X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fscript%2Fcpp_api%2Fs_item.cpp;h=032018f2f7438c59bef671b7a5b3b85d3c290fc1;hb=772944daf69ab463568fbbf35a9011e4c8e6c44a;hp=b4536ac63b95b49184a5096abb31e000b6637a7d;hpb=4e1f50035e860a00636ca5d804c267119df99601;p=dragonfireclient.git diff --git a/src/script/cpp_api/s_item.cpp b/src/script/cpp_api/s_item.cpp index b4536ac63..032018f2f 100644 --- a/src/script/cpp_api/s_item.cpp +++ b/src/script/cpp_api/s_item.cpp @@ -22,27 +22,37 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "common/c_converter.h" #include "common/c_content.h" #include "lua_api/l_item.h" +#include "lua_api/l_inventory.h" #include "server.h" #include "log.h" #include "util/pointedthing.h" +#include "inventory.h" +#include "inventorymanager.h" bool ScriptApiItem::item_OnDrop(ItemStack &item, ServerActiveObject *dropper, v3f pos) { SCRIPTAPI_PRECHECKHEADER + int error_handler = PUSH_ERROR_HANDLER(L); + // Push callback function on stack - if(!getItemCallback(item.name.c_str(), "on_drop")) + if (!getItemCallback(item.name.c_str(), "on_drop")) return false; // Call function LuaItemStack::create(L, item); - objectrefGetOrCreate(dropper); + objectrefGetOrCreate(L, dropper); pushFloatPos(L, pos); - if(lua_pcall(L, 3, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); - if(!lua_isnil(L, -1)) - item = read_item(L,-1, getServer()); + PCALL_RES(lua_pcall(L, 3, 1, error_handler)); + if (!lua_isnil(L, -1)) { + try { + item = read_item(L, -1, getServer()->idef()); + } catch (LuaError &e) { + throw LuaError(std::string(e.what()) + ". item=" + item.name); + } + } + lua_pop(L, 2); // Pop item and error handler return true; } @@ -51,18 +61,25 @@ bool ScriptApiItem::item_OnPlace(ItemStack &item, { SCRIPTAPI_PRECHECKHEADER + int error_handler = PUSH_ERROR_HANDLER(L); + // Push callback function on stack - if(!getItemCallback(item.name.c_str(), "on_place")) + if (!getItemCallback(item.name.c_str(), "on_place")) return false; // Call function LuaItemStack::create(L, item); - objectrefGetOrCreate(placer); + objectrefGetOrCreate(L, placer); pushPointedThing(pointed); - if(lua_pcall(L, 3, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); - if(!lua_isnil(L, -1)) - item = read_item(L,-1, getServer()); + PCALL_RES(lua_pcall(L, 3, 1, error_handler)); + if (!lua_isnil(L, -1)) { + try { + item = read_item(L, -1, getServer()->idef()); + } catch (LuaError &e) { + throw LuaError(std::string(e.what()) + ". item=" + item.name); + } + } + lua_pop(L, 2); // Pop item and error handler return true; } @@ -71,97 +88,167 @@ bool ScriptApiItem::item_OnUse(ItemStack &item, { SCRIPTAPI_PRECHECKHEADER + int error_handler = PUSH_ERROR_HANDLER(L); + // Push callback function on stack - if(!getItemCallback(item.name.c_str(), "on_use")) + if (!getItemCallback(item.name.c_str(), "on_use")) return false; // Call function LuaItemStack::create(L, item); - objectrefGetOrCreate(user); + objectrefGetOrCreate(L, user); + pushPointedThing(pointed); + PCALL_RES(lua_pcall(L, 3, 1, error_handler)); + if(!lua_isnil(L, -1)) { + try { + item = read_item(L, -1, getServer()->idef()); + } catch (LuaError &e) { + throw LuaError(std::string(e.what()) + ". item=" + item.name); + } + } + lua_pop(L, 2); // Pop item and error handler + return true; +} + +bool ScriptApiItem::item_OnSecondaryUse(ItemStack &item, ServerActiveObject *user) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + if (!getItemCallback(item.name.c_str(), "on_secondary_use")) + return false; + + LuaItemStack::create(L, item); + objectrefGetOrCreate(L, user); + PointedThing pointed; + pointed.type = POINTEDTHING_NOTHING; pushPointedThing(pointed); - if(lua_pcall(L, 3, 1, 0)) - scriptError("error: %s", lua_tostring(L, -1)); - if(!lua_isnil(L, -1)) - item = read_item(L,-1, getServer()); + PCALL_RES(lua_pcall(L, 3, 1, error_handler)); + if (!lua_isnil(L, -1)) { + try { + item = read_item(L, -1, getServer()->idef()); + } catch (LuaError &e) { + throw LuaError(std::string(e.what()) + ". item=" + item.name); + } + } + lua_pop(L, 2); // Pop item and error handler + return true; +} + +bool ScriptApiItem::item_OnCraft(ItemStack &item, ServerActiveObject *user, + const InventoryList *old_craft_grid, const InventoryLocation &craft_inv) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + lua_getglobal(L, "core"); + lua_getfield(L, -1, "on_craft"); + LuaItemStack::create(L, item); + objectrefGetOrCreate(L, user); + + // Push inventory list + std::vector items; + for (u32 i = 0; i < old_craft_grid->getSize(); i++) { + items.push_back(old_craft_grid->getItem(i)); + } + push_items(L, items); + + InvRef::create(L, craft_inv); + PCALL_RES(lua_pcall(L, 4, 1, error_handler)); + if (!lua_isnil(L, -1)) { + try { + item = read_item(L, -1, getServer()->idef()); + } catch (LuaError &e) { + throw LuaError(std::string(e.what()) + ". item=" + item.name); + } + } + lua_pop(L, 2); // Pop item and error handler return true; } -// Retrieves minetest.registered_items[name][callbackname] +bool ScriptApiItem::item_CraftPredict(ItemStack &item, ServerActiveObject *user, + const InventoryList *old_craft_grid, const InventoryLocation &craft_inv) +{ + SCRIPTAPI_PRECHECKHEADER + + int error_handler = PUSH_ERROR_HANDLER(L); + + lua_getglobal(L, "core"); + lua_getfield(L, -1, "craft_predict"); + LuaItemStack::create(L, item); + objectrefGetOrCreate(L, user); + + //Push inventory list + std::vector items; + for (u32 i = 0; i < old_craft_grid->getSize(); i++) { + items.push_back(old_craft_grid->getItem(i)); + } + push_items(L, items); + + InvRef::create(L, craft_inv); + PCALL_RES(lua_pcall(L, 4, 1, error_handler)); + if (!lua_isnil(L, -1)) { + try { + item = read_item(L, -1, getServer()->idef()); + } catch (LuaError &e) { + throw LuaError(std::string(e.what()) + ". item=" + item.name); + } + } + lua_pop(L, 2); // Pop item and error handler + return true; +} + +// Retrieves core.registered_items[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 -// If minetest.registered_items[name] doesn't exist, minetest.nodedef_default +// If core.registered_items[name] doesn't exist, core.nodedef_default // is tried instead so unknown items can still be manipulated to some degree bool ScriptApiItem::getItemCallback(const char *name, const char *callbackname) { lua_State* L = getStack(); - lua_getglobal(L, "minetest"); + lua_getglobal(L, "core"); lua_getfield(L, -1, "registered_items"); - lua_remove(L, -2); + lua_remove(L, -2); // Remove core luaL_checktype(L, -1, LUA_TTABLE); lua_getfield(L, -1, name); - lua_remove(L, -2); + lua_remove(L, -2); // Remove registered_items // Should be a table if(lua_type(L, -1) != LUA_TTABLE) { // Report error and clean up - errorstream<<"Item \""<