X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fscript%2Fcpp_api%2Fs_item.cpp;h=24955cefcb161ed7568480312fa9eb7d5469f9bf;hb=dd5a732fa90550066bb96305b64b6648903cc822;hp=6937ebbebf21529c8c57e98fe6bc167228e1d9c4;hpb=ab433775777c4f5055bcf4d2a1cffc506c4f9961;p=dragonfireclient.git diff --git a/src/script/cpp_api/s_item.cpp b/src/script/cpp_api/s_item.cpp index 6937ebbeb..24955cefc 100644 --- a/src/script/cpp_api/s_item.cpp +++ b/src/script/cpp_api/s_item.cpp @@ -18,28 +18,41 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "cpp_api/s_item.h" +#include "cpp_api/s_internal.h" #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; } @@ -48,18 +61,30 @@ 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); + + if (!placer) + lua_pushnil(L); + else + 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; } @@ -68,97 +93,171 @@ 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, const PointedThing &pointed) +{ + 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); 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; } -// Retrieves minetest.registered_items[name][callbackname] +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; +} + +bool ScriptApiItem::item_CraftPredict(ItemStack &item, ServerActiveObject *user, + const InventoryList *old_craft_grid, const InventoryLocation &craft_inv) +{ + SCRIPTAPI_PRECHECKHEADER + sanity_check(old_craft_grid); + 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) +bool ScriptApiItem::getItemCallback(const char *name, const char *callbackname, + const v3s16 *p) { 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) - { + if (lua_type(L, -1) != LUA_TTABLE) { // Report error and clean up - errorstream<<"Item \""<