mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Detached inventory callbacks and reworked node metadata callbacks
This commit is contained in:
parent
2ac20982e0
commit
9eaf93d41d
11 changed files with 827 additions and 247 deletions
|
@ -4579,8 +4579,8 @@ static int l_get_inventory(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
// create_detached_inventory(name)
|
||||
static int l_create_detached_inventory(lua_State *L)
|
||||
// create_detached_inventory_raw(name)
|
||||
static int l_create_detached_inventory_raw(lua_State *L)
|
||||
{
|
||||
const char *name = luaL_checkstring(L, 1);
|
||||
if(get_server(L)->createDetachedInventory(name) != NULL){
|
||||
|
@ -4866,7 +4866,7 @@ static const struct luaL_Reg minetest_f [] = {
|
|||
{"chat_send_player", l_chat_send_player},
|
||||
{"get_player_privs", l_get_player_privs},
|
||||
{"get_inventory", l_get_inventory},
|
||||
{"create_detached_inventory", l_create_detached_inventory},
|
||||
{"create_detached_inventory_raw", l_create_detached_inventory_raw},
|
||||
{"get_dig_params", l_get_dig_params},
|
||||
{"get_hit_params", l_get_hit_params},
|
||||
{"get_current_modname", l_get_current_modname},
|
||||
|
@ -5734,7 +5734,128 @@ void scriptapi_node_on_receive_fields(lua_State *L, v3s16 p,
|
|||
script_error(L, "error: %s", lua_tostring(L, -1));
|
||||
}
|
||||
|
||||
void scriptapi_node_on_metadata_inventory_move(lua_State *L, v3s16 p,
|
||||
/*
|
||||
Node metadata inventory callbacks
|
||||
*/
|
||||
|
||||
// Return number of accepted items to be moved
|
||||
int scriptapi_nodemeta_inventory_allow_move(lua_State *L, v3s16 p,
|
||||
const std::string &from_list, int from_index,
|
||||
const std::string &to_list, int to_index,
|
||||
int count, ServerActiveObject *player)
|
||||
{
|
||||
realitycheck(L);
|
||||
assert(lua_checkstack(L, 20));
|
||||
StackUnroller stack_unroller(L);
|
||||
|
||||
INodeDefManager *ndef = get_server(L)->ndef();
|
||||
|
||||
// If node doesn't exist, we don't know what callback to call
|
||||
MapNode node = get_env(L)->getMap().getNodeNoEx(p);
|
||||
if(node.getContent() == CONTENT_IGNORE)
|
||||
return 0;
|
||||
|
||||
// Push callback function on stack
|
||||
if(!get_item_callback(L, ndef->get(node).name.c_str(),
|
||||
"allow_metadata_inventory_move"))
|
||||
return count;
|
||||
|
||||
// function(pos, from_list, from_index, to_list, to_index, count, player)
|
||||
// pos
|
||||
push_v3s16(L, p);
|
||||
// from_list
|
||||
lua_pushstring(L, from_list.c_str());
|
||||
// from_index
|
||||
lua_pushinteger(L, from_index + 1);
|
||||
// to_list
|
||||
lua_pushstring(L, to_list.c_str());
|
||||
// to_index
|
||||
lua_pushinteger(L, to_index + 1);
|
||||
// count
|
||||
lua_pushinteger(L, count);
|
||||
// player
|
||||
objectref_get_or_create(L, player);
|
||||
if(lua_pcall(L, 7, 1, 0))
|
||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
||||
return luaL_checkinteger(L, -1);
|
||||
}
|
||||
|
||||
// Return number of accepted items to be put
|
||||
int scriptapi_nodemeta_inventory_allow_put(lua_State *L, v3s16 p,
|
||||
const std::string &listname, int index, ItemStack &stack,
|
||||
ServerActiveObject *player)
|
||||
{
|
||||
realitycheck(L);
|
||||
assert(lua_checkstack(L, 20));
|
||||
StackUnroller stack_unroller(L);
|
||||
|
||||
INodeDefManager *ndef = get_server(L)->ndef();
|
||||
|
||||
// If node doesn't exist, we don't know what callback to call
|
||||
MapNode node = get_env(L)->getMap().getNodeNoEx(p);
|
||||
if(node.getContent() == CONTENT_IGNORE)
|
||||
return 0;
|
||||
|
||||
// Push callback function on stack
|
||||
if(!get_item_callback(L, ndef->get(node).name.c_str(),
|
||||
"allow_metadata_inventory_put"))
|
||||
return stack.count;
|
||||
|
||||
// Call function(pos, listname, index, stack, player)
|
||||
// pos
|
||||
push_v3s16(L, p);
|
||||
// listname
|
||||
lua_pushstring(L, listname.c_str());
|
||||
// index
|
||||
lua_pushinteger(L, index + 1);
|
||||
// stack
|
||||
LuaItemStack::create(L, stack);
|
||||
// player
|
||||
objectref_get_or_create(L, player);
|
||||
if(lua_pcall(L, 5, 1, 0))
|
||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
||||
return luaL_checkinteger(L, -1);
|
||||
}
|
||||
|
||||
// Return number of accepted items to be taken
|
||||
int scriptapi_nodemeta_inventory_allow_take(lua_State *L, v3s16 p,
|
||||
const std::string &listname, int index, int count,
|
||||
ServerActiveObject *player)
|
||||
{
|
||||
realitycheck(L);
|
||||
assert(lua_checkstack(L, 20));
|
||||
StackUnroller stack_unroller(L);
|
||||
|
||||
INodeDefManager *ndef = get_server(L)->ndef();
|
||||
|
||||
// If node doesn't exist, we don't know what callback to call
|
||||
MapNode node = get_env(L)->getMap().getNodeNoEx(p);
|
||||
if(node.getContent() == CONTENT_IGNORE)
|
||||
return 0;
|
||||
|
||||
// Push callback function on stack
|
||||
if(!get_item_callback(L, ndef->get(node).name.c_str(),
|
||||
"allow_metadata_inventory_take"))
|
||||
return count;
|
||||
|
||||
// Call function(pos, listname, index, count, player)
|
||||
// pos
|
||||
push_v3s16(L, p);
|
||||
// listname
|
||||
lua_pushstring(L, listname.c_str());
|
||||
// index
|
||||
lua_pushinteger(L, index + 1);
|
||||
// count
|
||||
lua_pushinteger(L, count);
|
||||
// player
|
||||
objectref_get_or_create(L, player);
|
||||
if(lua_pcall(L, 5, 1, 0))
|
||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
||||
return luaL_checkinteger(L, -1);
|
||||
}
|
||||
|
||||
// Report moved items
|
||||
void scriptapi_nodemeta_inventory_on_move(lua_State *L, v3s16 p,
|
||||
const std::string &from_list, int from_index,
|
||||
const std::string &to_list, int to_index,
|
||||
int count, ServerActiveObject *player)
|
||||
|
@ -5756,18 +5877,26 @@ void scriptapi_node_on_metadata_inventory_move(lua_State *L, v3s16 p,
|
|||
return;
|
||||
|
||||
// function(pos, from_list, from_index, to_list, to_index, count, player)
|
||||
// pos
|
||||
push_v3s16(L, p);
|
||||
// from_list
|
||||
lua_pushstring(L, from_list.c_str());
|
||||
// from_index
|
||||
lua_pushinteger(L, from_index + 1);
|
||||
// to_list
|
||||
lua_pushstring(L, to_list.c_str());
|
||||
// to_index
|
||||
lua_pushinteger(L, to_index + 1);
|
||||
// count
|
||||
lua_pushinteger(L, count);
|
||||
// player
|
||||
objectref_get_or_create(L, player);
|
||||
if(lua_pcall(L, 7, 0, 0))
|
||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
||||
}
|
||||
|
||||
ItemStack scriptapi_node_on_metadata_inventory_offer(lua_State *L, v3s16 p,
|
||||
// Report put items
|
||||
void scriptapi_nodemeta_inventory_on_put(lua_State *L, v3s16 p,
|
||||
const std::string &listname, int index, ItemStack &stack,
|
||||
ServerActiveObject *player)
|
||||
{
|
||||
|
@ -5780,25 +5909,30 @@ ItemStack scriptapi_node_on_metadata_inventory_offer(lua_State *L, v3s16 p,
|
|||
// If node doesn't exist, we don't know what callback to call
|
||||
MapNode node = get_env(L)->getMap().getNodeNoEx(p);
|
||||
if(node.getContent() == CONTENT_IGNORE)
|
||||
return stack;
|
||||
return;
|
||||
|
||||
// Push callback function on stack
|
||||
if(!get_item_callback(L, ndef->get(node).name.c_str(),
|
||||
"on_metadata_inventory_offer"))
|
||||
return stack;
|
||||
"on_metadata_inventory_put"))
|
||||
return;
|
||||
|
||||
// Call function(pos, listname, index, stack, player)
|
||||
// pos
|
||||
push_v3s16(L, p);
|
||||
// listname
|
||||
lua_pushstring(L, listname.c_str());
|
||||
// index
|
||||
lua_pushinteger(L, index + 1);
|
||||
// stack
|
||||
LuaItemStack::create(L, stack);
|
||||
// player
|
||||
objectref_get_or_create(L, player);
|
||||
if(lua_pcall(L, 5, 1, 0))
|
||||
if(lua_pcall(L, 5, 0, 0))
|
||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
||||
return read_item(L, -1);
|
||||
}
|
||||
|
||||
ItemStack scriptapi_node_on_metadata_inventory_take(lua_State *L, v3s16 p,
|
||||
// Report taken items
|
||||
void scriptapi_nodemeta_inventory_on_take(lua_State *L, v3s16 p,
|
||||
const std::string &listname, int index, int count,
|
||||
ServerActiveObject *player)
|
||||
{
|
||||
|
@ -5811,22 +5945,270 @@ ItemStack scriptapi_node_on_metadata_inventory_take(lua_State *L, v3s16 p,
|
|||
// If node doesn't exist, we don't know what callback to call
|
||||
MapNode node = get_env(L)->getMap().getNodeNoEx(p);
|
||||
if(node.getContent() == CONTENT_IGNORE)
|
||||
return ItemStack();
|
||||
return;
|
||||
|
||||
// Push callback function on stack
|
||||
if(!get_item_callback(L, ndef->get(node).name.c_str(),
|
||||
"on_metadata_inventory_take"))
|
||||
return ItemStack();
|
||||
return;
|
||||
|
||||
// Call function(pos, listname, index, count, player)
|
||||
// pos
|
||||
push_v3s16(L, p);
|
||||
// listname
|
||||
lua_pushstring(L, listname.c_str());
|
||||
// index
|
||||
lua_pushinteger(L, index + 1);
|
||||
// count
|
||||
lua_pushinteger(L, count);
|
||||
// player
|
||||
objectref_get_or_create(L, player);
|
||||
if(lua_pcall(L, 5, 0, 0))
|
||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
||||
}
|
||||
|
||||
/*
|
||||
Detached inventory callbacks
|
||||
*/
|
||||
|
||||
// Retrieves minetest.detached_inventories[name][callbackname]
|
||||
// If that is nil or on error, return false and stack is unchanged
|
||||
// If that is a function, returns true and pushes the
|
||||
// function onto the stack
|
||||
static bool get_detached_inventory_callback(lua_State *L,
|
||||
const std::string &name, const char *callbackname)
|
||||
{
|
||||
lua_getglobal(L, "minetest");
|
||||
lua_getfield(L, -1, "detached_inventories");
|
||||
lua_remove(L, -2);
|
||||
luaL_checktype(L, -1, LUA_TTABLE);
|
||||
lua_getfield(L, -1, name.c_str());
|
||||
lua_remove(L, -2);
|
||||
// Should be a table
|
||||
if(lua_type(L, -1) != LUA_TTABLE)
|
||||
{
|
||||
errorstream<<"Item \""<<name<<"\" not defined"<<std::endl;
|
||||
lua_pop(L, 1);
|
||||
return false;
|
||||
}
|
||||
lua_getfield(L, -1, callbackname);
|
||||
lua_remove(L, -2);
|
||||
// Should be a function or nil
|
||||
if(lua_type(L, -1) == LUA_TFUNCTION)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if(lua_isnil(L, -1))
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
errorstream<<"Detached inventory \""<<name<<"\" callback \""
|
||||
<<callbackname<<"\" is not a function"<<std::endl;
|
||||
lua_pop(L, 1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Return number of accepted items to be moved
|
||||
int scriptapi_detached_inventory_allow_move(lua_State *L,
|
||||
const std::string &name,
|
||||
const std::string &from_list, int from_index,
|
||||
const std::string &to_list, int to_index,
|
||||
int count, ServerActiveObject *player)
|
||||
{
|
||||
realitycheck(L);
|
||||
assert(lua_checkstack(L, 20));
|
||||
StackUnroller stack_unroller(L);
|
||||
|
||||
// Push callback function on stack
|
||||
if(!get_detached_inventory_callback(L, name, "allow_move"))
|
||||
return count;
|
||||
|
||||
// function(inv, from_list, from_index, to_list, to_index, count, player)
|
||||
// inv
|
||||
InventoryLocation loc;
|
||||
loc.setDetached(name);
|
||||
InvRef::create(L, loc);
|
||||
// from_list
|
||||
lua_pushstring(L, from_list.c_str());
|
||||
// from_index
|
||||
lua_pushinteger(L, from_index + 1);
|
||||
// to_list
|
||||
lua_pushstring(L, to_list.c_str());
|
||||
// to_index
|
||||
lua_pushinteger(L, to_index + 1);
|
||||
// count
|
||||
lua_pushinteger(L, count);
|
||||
// player
|
||||
objectref_get_or_create(L, player);
|
||||
if(lua_pcall(L, 7, 1, 0))
|
||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
||||
return luaL_checkinteger(L, -1);
|
||||
}
|
||||
|
||||
// Return number of accepted items to be put
|
||||
int scriptapi_detached_inventory_allow_put(lua_State *L,
|
||||
const std::string &name,
|
||||
const std::string &listname, int index, ItemStack &stack,
|
||||
ServerActiveObject *player)
|
||||
{
|
||||
realitycheck(L);
|
||||
assert(lua_checkstack(L, 20));
|
||||
StackUnroller stack_unroller(L);
|
||||
|
||||
// Push callback function on stack
|
||||
if(!get_detached_inventory_callback(L, name, "allow_put"))
|
||||
return stack.count; // All will be accepted
|
||||
|
||||
// Call function(inv, listname, index, stack, player)
|
||||
// inv
|
||||
InventoryLocation loc;
|
||||
loc.setDetached(name);
|
||||
InvRef::create(L, loc);
|
||||
// listname
|
||||
lua_pushstring(L, listname.c_str());
|
||||
// index
|
||||
lua_pushinteger(L, index + 1);
|
||||
// stack
|
||||
LuaItemStack::create(L, stack);
|
||||
// player
|
||||
objectref_get_or_create(L, player);
|
||||
if(lua_pcall(L, 5, 1, 0))
|
||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
||||
return read_item(L, -1);
|
||||
return luaL_checkinteger(L, -1);
|
||||
}
|
||||
|
||||
// Return number of accepted items to be taken
|
||||
int scriptapi_detached_inventory_allow_take(lua_State *L,
|
||||
const std::string &name,
|
||||
const std::string &listname, int index, int count,
|
||||
ServerActiveObject *player)
|
||||
{
|
||||
realitycheck(L);
|
||||
assert(lua_checkstack(L, 20));
|
||||
StackUnroller stack_unroller(L);
|
||||
|
||||
// Push callback function on stack
|
||||
if(!get_detached_inventory_callback(L, name, "allow_take"))
|
||||
return count; // All will be accepted
|
||||
|
||||
// Call function(inv, listname, index, count, player)
|
||||
// inv
|
||||
InventoryLocation loc;
|
||||
loc.setDetached(name);
|
||||
InvRef::create(L, loc);
|
||||
// listname
|
||||
lua_pushstring(L, listname.c_str());
|
||||
// index
|
||||
lua_pushinteger(L, index + 1);
|
||||
// count
|
||||
lua_pushinteger(L, count);
|
||||
// player
|
||||
objectref_get_or_create(L, player);
|
||||
if(lua_pcall(L, 5, 1, 0))
|
||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
||||
return luaL_checkinteger(L, -1);
|
||||
}
|
||||
|
||||
// Report moved items
|
||||
void scriptapi_detached_inventory_on_move(lua_State *L,
|
||||
const std::string &name,
|
||||
const std::string &from_list, int from_index,
|
||||
const std::string &to_list, int to_index,
|
||||
int count, ServerActiveObject *player)
|
||||
{
|
||||
realitycheck(L);
|
||||
assert(lua_checkstack(L, 20));
|
||||
StackUnroller stack_unroller(L);
|
||||
|
||||
// Push callback function on stack
|
||||
if(!get_detached_inventory_callback(L, name, "on_move"))
|
||||
return;
|
||||
|
||||
// function(inv, from_list, from_index, to_list, to_index, count, player)
|
||||
// inv
|
||||
InventoryLocation loc;
|
||||
loc.setDetached(name);
|
||||
InvRef::create(L, loc);
|
||||
// from_list
|
||||
lua_pushstring(L, from_list.c_str());
|
||||
// from_index
|
||||
lua_pushinteger(L, from_index + 1);
|
||||
// to_list
|
||||
lua_pushstring(L, to_list.c_str());
|
||||
// to_index
|
||||
lua_pushinteger(L, to_index + 1);
|
||||
// count
|
||||
lua_pushinteger(L, count);
|
||||
// player
|
||||
objectref_get_or_create(L, player);
|
||||
if(lua_pcall(L, 7, 0, 0))
|
||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
||||
}
|
||||
|
||||
// Report put items
|
||||
void scriptapi_detached_inventory_on_put(lua_State *L,
|
||||
const std::string &name,
|
||||
const std::string &listname, int index, ItemStack &stack,
|
||||
ServerActiveObject *player)
|
||||
{
|
||||
realitycheck(L);
|
||||
assert(lua_checkstack(L, 20));
|
||||
StackUnroller stack_unroller(L);
|
||||
|
||||
// Push callback function on stack
|
||||
if(!get_detached_inventory_callback(L, name, "on_put"))
|
||||
return;
|
||||
|
||||
// Call function(inv, listname, index, stack, player)
|
||||
// inv
|
||||
InventoryLocation loc;
|
||||
loc.setDetached(name);
|
||||
InvRef::create(L, loc);
|
||||
// listname
|
||||
lua_pushstring(L, listname.c_str());
|
||||
// index
|
||||
lua_pushinteger(L, index + 1);
|
||||
// stack
|
||||
LuaItemStack::create(L, stack);
|
||||
// player
|
||||
objectref_get_or_create(L, player);
|
||||
if(lua_pcall(L, 5, 0, 0))
|
||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
||||
}
|
||||
|
||||
// Report taken items
|
||||
void scriptapi_detached_inventory_on_take(lua_State *L,
|
||||
const std::string &name,
|
||||
const std::string &listname, int index, int count,
|
||||
ServerActiveObject *player)
|
||||
{
|
||||
realitycheck(L);
|
||||
assert(lua_checkstack(L, 20));
|
||||
StackUnroller stack_unroller(L);
|
||||
|
||||
// Push callback function on stack
|
||||
if(!get_detached_inventory_callback(L, name, "on_take"))
|
||||
return;
|
||||
|
||||
// Call function(inv, listname, index, count, player)
|
||||
// inv
|
||||
InventoryLocation loc;
|
||||
loc.setDetached(name);
|
||||
InvRef::create(L, loc);
|
||||
// listname
|
||||
lua_pushstring(L, listname.c_str());
|
||||
// index
|
||||
lua_pushinteger(L, index + 1);
|
||||
// count
|
||||
lua_pushinteger(L, count);
|
||||
// player
|
||||
objectref_get_or_create(L, player);
|
||||
if(lua_pcall(L, 5, 0, 0))
|
||||
script_error(L, "error: %s", lua_tostring(L, -1));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue