51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include "cpp_api/scriptapi.h"
-#include "common/c_converter.h"
-#include "common/c_content.h"
#include "lua_api/l_inventory.h"
+#include "lua_api/l_internal.h"
#include "lua_api/l_item.h"
-#include "common/c_internal.h"
+#include "common/c_converter.h"
+#include "common/c_content.h"
#include "server.h"
-#include "log.h"
-#include "inventorymanager.h"
+#include "remoteplayer.h"
/*
InvRef
Inventory* InvRef::getinv(lua_State *L, InvRef *ref)
{
- return STACK_TO_SERVER(L)->getInventory(ref->m_loc);
+ return getServer(L)->getInventory(ref->m_loc);
}
InventoryList* InvRef::getlist(lua_State *L, InvRef *ref,
void InvRef::reportInventoryChange(lua_State *L, InvRef *ref)
{
// Inform other things that the inventory has changed
- STACK_TO_SERVER(L)->setInventoryModified(ref->m_loc);
+ getServer(L)->setInventoryModified(ref->m_loc);
}
// Exported functions
NO_MAP_LOCK_REQUIRED;
InvRef *ref = checkobject(L, 1);
const char *listname = luaL_checkstring(L, 2);
+
int newsize = luaL_checknumber(L, 3);
+ if (newsize < 0) {
+ lua_pushboolean(L, false);
+ return 1;
+ }
+
Inventory *inv = getinv(L, ref);
+ if(inv == NULL){
+ lua_pushboolean(L, false);
+ return 1;
+ }
if(newsize == 0){
inv->deleteList(listname);
reportInventoryChange(L, ref);
- return 0;
+ lua_pushboolean(L, true);
+ return 1;
}
InventoryList *list = inv->getList(listname);
if(list){
list->setSize(newsize);
} else {
list = inv->addList(listname, newsize);
+ if (!list)
+ {
+ lua_pushboolean(L, false);
+ return 1;
+ }
}
reportInventoryChange(L, ref);
- return 0;
+ lua_pushboolean(L, true);
+ return 1;
}
// set_width(self, listname, size)
const char *listname = luaL_checkstring(L, 2);
int newwidth = luaL_checknumber(L, 3);
Inventory *inv = getinv(L, ref);
+ if(inv == NULL){
+ return 0;
+ }
InventoryList *list = inv->getList(listname);
if(list){
list->setWidth(newwidth);
InvRef *ref = checkobject(L, 1);
const char *listname = luaL_checkstring(L, 2);
int i = luaL_checknumber(L, 3) - 1;
- ItemStack newitem = read_item(L, 4,STACK_TO_SERVER(L));
+ ItemStack newitem = read_item(L, 4, getServer(L)->idef());
InventoryList *list = getlist(L, ref, listname);
if(list != NULL && i >= 0 && i < (int) list->getSize()){
list->changeItem(i, newitem);
InvRef *ref = checkobject(L, 1);
const char *listname = luaL_checkstring(L, 2);
Inventory *inv = getinv(L, ref);
- push_inventory_list(inv, listname, L);
+ if(inv){
+ push_inventory_list(L, inv, listname);
+ } else {
+ lua_pushnil(L);
+ }
return 1;
}
InvRef *ref = checkobject(L, 1);
const char *listname = luaL_checkstring(L, 2);
Inventory *inv = getinv(L, ref);
+ if(inv == NULL){
+ return 0;
+ }
InventoryList *list = inv->getList(listname);
if(list)
- read_inventory_list(inv, listname, L, 3,
- STACK_TO_SERVER(L),list->getSize());
+ read_inventory_list(L, 3, inv, listname,
+ getServer(L), list->getSize());
else
- read_inventory_list(inv, listname, L, 3,STACK_TO_SERVER(L));
+ read_inventory_list(L, 3, inv, listname, getServer(L));
reportInventoryChange(L, ref);
return 0;
}
+// get_lists(self) -> list of InventoryLists
+int InvRef::l_get_lists(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
+ InvRef *ref = checkobject(L, 1);
+ Inventory *inv = getinv(L, ref);
+ if (!inv) {
+ return 0;
+ }
+ std::vector<const InventoryList*> lists = inv->getLists();
+ std::vector<const InventoryList*>::iterator iter = lists.begin();
+ lua_createtable(L, 0, lists.size());
+ for (; iter != lists.end(); iter++) {
+ const char* name = (*iter)->getName().c_str();
+ lua_pushstring(L, name);
+ push_inventory_list(L, inv, name);
+ lua_rawset(L, -3);
+ }
+ return 1;
+}
+
+// set_lists(self, lists)
+int InvRef::l_set_lists(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
+ InvRef *ref = checkobject(L, 1);
+ Inventory *inv = getinv(L, ref);
+ if (!inv) {
+ return 0;
+ }
+
+ // Make a temporary inventory in case reading fails
+ Inventory *tempInv(inv);
+ tempInv->clear();
+
+ Server *server = getServer(L);
+
+ lua_pushnil(L);
+ while (lua_next(L, 2)) {
+ const char *listname = lua_tostring(L, -2);
+ read_inventory_list(L, -1, tempInv, listname, server);
+ lua_pop(L, 1);
+ }
+ inv = tempInv;
+ return 0;
+}
+
// add_item(self, listname, itemstack or itemstring or table or nil) -> itemstack
// Returns the leftover stack
int InvRef::l_add_item(lua_State *L)
NO_MAP_LOCK_REQUIRED;
InvRef *ref = checkobject(L, 1);
const char *listname = luaL_checkstring(L, 2);
- ItemStack item = read_item(L, 3,STACK_TO_SERVER(L));
+ ItemStack item = read_item(L, 3, getServer(L)->idef());
InventoryList *list = getlist(L, ref, listname);
if(list){
ItemStack leftover = list->addItem(item);
NO_MAP_LOCK_REQUIRED;
InvRef *ref = checkobject(L, 1);
const char *listname = luaL_checkstring(L, 2);
- ItemStack item = read_item(L, 3,STACK_TO_SERVER(L));
+ ItemStack item = read_item(L, 3, getServer(L)->idef());
InventoryList *list = getlist(L, ref, listname);
if(list){
lua_pushboolean(L, list->roomForItem(item));
return 1;
}
-// contains_item(self, listname, itemstack or itemstring or table or nil) -> true/false
-// Returns true if the list contains the given count of the given item name
+// contains_item(self, listname, itemstack or itemstring or table or nil, [match_meta]) -> true/false
+// Returns true if the list contains the given count of the given item
int InvRef::l_contains_item(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
InvRef *ref = checkobject(L, 1);
const char *listname = luaL_checkstring(L, 2);
- ItemStack item = read_item(L, 3, STACK_TO_SERVER(L));
+ ItemStack item = read_item(L, 3, getServer(L)->idef());
InventoryList *list = getlist(L, ref, listname);
- if(list){
- lua_pushboolean(L, list->containsItem(item));
+ bool match_meta = false;
+ if (lua_isboolean(L, 4))
+ match_meta = readParam<bool>(L, 4);
+ if (list) {
+ lua_pushboolean(L, list->containsItem(item, match_meta));
} else {
lua_pushboolean(L, false);
}
NO_MAP_LOCK_REQUIRED;
InvRef *ref = checkobject(L, 1);
const char *listname = luaL_checkstring(L, 2);
- ItemStack item = read_item(L, 3,STACK_TO_SERVER(L));
+ ItemStack item = read_item(L, 3, getServer(L)->idef());
InventoryList *list = getlist(L, ref, listname);
if(list){
ItemStack removed = list->removeItem(item);
return 1;
}
-// get_location() -> location (like minetest.get_inventory(location))
+// get_location() -> location (like get_inventory(location))
int InvRef::l_get_location(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
{
}
-InvRef::~InvRef()
-{
-}
-
// Creates an InvRef and leaves it on top of stack
// Not callable from Lua; all references are created on the C side.
void InvRef::create(lua_State *L, const InventoryLocation &loc)
luaL_getmetatable(L, className);
lua_setmetatable(L, -2);
}
-void InvRef::createPlayer(lua_State *L, Player *player)
+void InvRef::createPlayer(lua_State *L, RemotePlayer *player)
{
NO_MAP_LOCK_REQUIRED;
InventoryLocation loc;
}
const char InvRef::className[] = "InvRef";
-const luaL_reg InvRef::methods[] = {
+const luaL_Reg InvRef::methods[] = {
luamethod(InvRef, is_empty),
luamethod(InvRef, get_size),
luamethod(InvRef, set_size),
luamethod(InvRef, set_stack),
luamethod(InvRef, get_list),
luamethod(InvRef, set_list),
+ luamethod(InvRef, get_lists),
+ luamethod(InvRef, set_lists),
luamethod(InvRef, add_item),
luamethod(InvRef, room_for_item),
luamethod(InvRef, contains_item),
std::string type = checkstringfield(L, 1, "type");
if(type == "node"){
+ MAP_LOCK_REQUIRED;
lua_getfield(L, 1, "pos");
v3s16 pos = check_v3s16(L, -1);
loc.setNodeMeta(pos);
- if(getServer(L)->getInventory(loc) != NULL)
+ if (getServer(L)->getInventory(loc) != NULL)
InvRef::create(L, loc);
else
lua_pushnil(L);
return 1;
- } else {
- NO_MAP_LOCK_REQUIRED;
- if(type == "player"){
- std::string name = checkstringfield(L, 1, "name");
- loc.setPlayer(name);
- } else if(type == "detached"){
- std::string name = checkstringfield(L, 1, "name");
- loc.setDetached(name);
- }
+ }
- if(getServer(L)->getInventory(loc) != NULL)
- InvRef::create(L, loc);
- else
- lua_pushnil(L);
- return 1;
- // END NO_MAP_LOCK_REQUIRED;
+ NO_MAP_LOCK_REQUIRED;
+ if (type == "player") {
+ std::string name = checkstringfield(L, 1, "name");
+ loc.setPlayer(name);
+ } else if (type == "detached") {
+ std::string name = checkstringfield(L, 1, "name");
+ loc.setDetached(name);
}
+
+ if (getServer(L)->getInventory(loc) != NULL)
+ InvRef::create(L, loc);
+ else
+ lua_pushnil(L);
+ return 1;
+ // END NO_MAP_LOCK_REQUIRED;
+
}
-// create_detached_inventory_raw(name)
+// create_detached_inventory_raw(name, [player_name])
int ModApiInventory::l_create_detached_inventory_raw(lua_State *L)
{
NO_MAP_LOCK_REQUIRED;
const char *name = luaL_checkstring(L, 1);
- if(getServer(L)->createDetachedInventory(name) != NULL){
+ std::string player = readParam<std::string>(L, 2, "");
+ if (getServer(L)->createDetachedInventory(name, player) != NULL) {
InventoryLocation loc;
loc.setDetached(name);
InvRef::create(L, loc);
- }else{
+ } else {
lua_pushnil(L);
}
return 1;
}
-bool ModApiInventory::Initialize(lua_State *L, int top) {
- bool retval = true;
-
- retval &= API_FCT(create_detached_inventory_raw);
- retval &= API_FCT(get_inventory);
-
- InvRef::Register(L);
-
- return retval;
+// remove_detached_inventory_raw(name)
+int ModApiInventory::l_remove_detached_inventory_raw(lua_State *L)
+{
+ NO_MAP_LOCK_REQUIRED;
+ const std::string &name = luaL_checkstring(L, 1);
+ lua_pushboolean(L, getServer(L)->removeDetachedInventory(name));
+ return 1;
}
-ModApiInventory::ModApiInventory()
- : ModApiBase() {
-
+void ModApiInventory::Initialize(lua_State *L, int top)
+{
+ API_FCT(create_detached_inventory_raw);
+ API_FCT(remove_detached_inventory_raw);
+ API_FCT(get_inventory);
}
-
-ModApiInventory modapiinventory_prototype;