LCOV - code coverage report
Current view: top level - src/script/cpp_api - s_item.cpp (source / functions) Hit Total Coverage
Test: report Lines: 1 125 0.8 %
Date: 2015-07-11 18:23:49 Functions: 2 9 22.2 %

          Line data    Source code
       1             : /*
       2             : Minetest
       3             : Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
       4             : 
       5             : This program is free software; you can redistribute it and/or modify
       6             : it under the terms of the GNU Lesser General Public License as published by
       7             : the Free Software Foundation; either version 2.1 of the License, or
       8             : (at your option) any later version.
       9             : 
      10             : This program is distributed in the hope that it will be useful,
      11             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      12             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13             : GNU Lesser General Public License for more details.
      14             : 
      15             : You should have received a copy of the GNU Lesser General Public License along
      16             : with this program; if not, write to the Free Software Foundation, Inc.,
      17             : 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      18             : */
      19             : 
      20             : #include "cpp_api/s_item.h"
      21             : #include "cpp_api/s_internal.h"
      22             : #include "common/c_converter.h"
      23             : #include "common/c_content.h"
      24             : #include "lua_api/l_item.h"
      25             : #include "lua_api/l_inventory.h"
      26             : #include "server.h"
      27             : #include "log.h"
      28             : #include "util/pointedthing.h"
      29             : #include "inventory.h"
      30             : #include "inventorymanager.h"
      31             : 
      32           0 : bool ScriptApiItem::item_OnDrop(ItemStack &item,
      33             :                 ServerActiveObject *dropper, v3f pos)
      34             : {
      35           0 :         SCRIPTAPI_PRECHECKHEADER
      36             : 
      37             :         // Push callback function on stack
      38           0 :         if (!getItemCallback(item.name.c_str(), "on_drop"))
      39           0 :                 return false;
      40             : 
      41             :         // Call function
      42           0 :         LuaItemStack::create(L, item);
      43           0 :         objectrefGetOrCreate(L, dropper);
      44           0 :         pushFloatPos(L, pos);
      45           0 :         if (lua_pcall(L, 3, 1, m_errorhandler))
      46           0 :                 scriptError();
      47           0 :         if (!lua_isnil(L, -1)) {
      48             :                 try {
      49           0 :                         item = read_item(L,-1, getServer());
      50           0 :                 } catch (LuaError &e) {
      51           0 :                         throw LuaError(std::string(e.what()) + ". item=" + item.name);
      52             :                 }
      53             :         }
      54           0 :         lua_pop(L, 1);  // Pop item
      55           0 :         return true;
      56             : }
      57             : 
      58           0 : bool ScriptApiItem::item_OnPlace(ItemStack &item,
      59             :                 ServerActiveObject *placer, const PointedThing &pointed)
      60             : {
      61           0 :         SCRIPTAPI_PRECHECKHEADER
      62             : 
      63             :         // Push callback function on stack
      64           0 :         if (!getItemCallback(item.name.c_str(), "on_place"))
      65           0 :                 return false;
      66             : 
      67             :         // Call function
      68           0 :         LuaItemStack::create(L, item);
      69           0 :         objectrefGetOrCreate(L, placer);
      70           0 :         pushPointedThing(pointed);
      71           0 :         if (lua_pcall(L, 3, 1, m_errorhandler))
      72           0 :                 scriptError();
      73           0 :         if (!lua_isnil(L, -1)) {
      74             :                 try {
      75           0 :                         item = read_item(L,-1, getServer());
      76           0 :                 } catch (LuaError &e) {
      77           0 :                         throw LuaError(std::string(e.what()) + ". item=" + item.name);
      78             :                 }
      79             :         }
      80           0 :         lua_pop(L, 1);  // Pop item
      81           0 :         return true;
      82             : }
      83             : 
      84           0 : bool ScriptApiItem::item_OnUse(ItemStack &item,
      85             :                 ServerActiveObject *user, const PointedThing &pointed)
      86             : {
      87           0 :         SCRIPTAPI_PRECHECKHEADER
      88             : 
      89             :         // Push callback function on stack
      90           0 :         if (!getItemCallback(item.name.c_str(), "on_use"))
      91           0 :                 return false;
      92             : 
      93             :         // Call function
      94           0 :         LuaItemStack::create(L, item);
      95           0 :         objectrefGetOrCreate(L, user);
      96           0 :         pushPointedThing(pointed);
      97           0 :         if (lua_pcall(L, 3, 1, m_errorhandler))
      98           0 :                 scriptError();
      99           0 :         if(!lua_isnil(L, -1)) {
     100             :                 try {
     101           0 :                         item = read_item(L,-1, getServer());
     102           0 :                 } catch (LuaError &e) {
     103           0 :                         throw LuaError(std::string(e.what()) + ". item=" + item.name);
     104             :                 }
     105             :         }
     106           0 :         lua_pop(L, 1);  // Pop item
     107           0 :         return true;
     108             : }
     109             : 
     110           0 : bool ScriptApiItem::item_OnCraft(ItemStack &item, ServerActiveObject *user,
     111             :                 const InventoryList *old_craft_grid, const InventoryLocation &craft_inv)
     112             : {
     113           0 :         SCRIPTAPI_PRECHECKHEADER
     114             : 
     115           0 :         lua_getglobal(L, "core");
     116           0 :         lua_getfield(L, -1, "on_craft");
     117           0 :         LuaItemStack::create(L, item);
     118           0 :         objectrefGetOrCreate(L, user);
     119             :         
     120             :         // Push inventory list
     121           0 :         std::vector<ItemStack> items;
     122           0 :         for (u32 i = 0; i < old_craft_grid->getSize(); i++) {
     123           0 :                 items.push_back(old_craft_grid->getItem(i));
     124             :         }
     125           0 :         push_items(L, items);
     126             : 
     127           0 :         InvRef::create(L, craft_inv);
     128           0 :         if (lua_pcall(L, 4, 1, m_errorhandler))
     129           0 :                 scriptError();
     130           0 :         if (!lua_isnil(L, -1)) {
     131             :                 try {
     132           0 :                         item = read_item(L,-1, getServer());
     133           0 :                 } catch (LuaError &e) {
     134           0 :                         throw LuaError(std::string(e.what()) + ". item=" + item.name);
     135             :                 }
     136             :         }
     137           0 :         lua_pop(L, 1);  // Pop item
     138           0 :         return true;
     139             : }
     140             : 
     141           0 : bool ScriptApiItem::item_CraftPredict(ItemStack &item, ServerActiveObject *user,
     142             :                 const InventoryList *old_craft_grid, const InventoryLocation &craft_inv)
     143             : {
     144           0 :         SCRIPTAPI_PRECHECKHEADER
     145             : 
     146           0 :         lua_getglobal(L, "core");
     147           0 :         lua_getfield(L, -1, "craft_predict");
     148           0 :         LuaItemStack::create(L, item);
     149           0 :         objectrefGetOrCreate(L, user);
     150             : 
     151             :         //Push inventory list
     152           0 :         std::vector<ItemStack> items;
     153           0 :         for (u32 i = 0; i < old_craft_grid->getSize(); i++) {
     154           0 :                 items.push_back(old_craft_grid->getItem(i));
     155             :         }
     156           0 :         push_items(L, items);
     157             : 
     158           0 :         InvRef::create(L, craft_inv);
     159           0 :         if (lua_pcall(L, 4, 1, m_errorhandler))
     160           0 :                 scriptError();
     161           0 :         if (!lua_isnil(L, -1)) {
     162             :                 try {
     163           0 :                         item = read_item(L,-1, getServer());
     164           0 :                 } catch (LuaError &e) {
     165           0 :                         throw LuaError(std::string(e.what()) + ". item=" + item.name);
     166             :                 }
     167             :         }
     168           0 :         lua_pop(L, 1);  // Pop item
     169           0 :         return true;
     170             : }
     171             : 
     172             : // Retrieves core.registered_items[name][callbackname]
     173             : // If that is nil or on error, return false and stack is unchanged
     174             : // If that is a function, returns true and pushes the
     175             : // function onto the stack
     176             : // If core.registered_items[name] doesn't exist, core.nodedef_default
     177             : // is tried instead so unknown items can still be manipulated to some degree
     178           0 : bool ScriptApiItem::getItemCallback(const char *name, const char *callbackname)
     179             : {
     180           0 :         lua_State* L = getStack();
     181             : 
     182           0 :         lua_getglobal(L, "core");
     183           0 :         lua_getfield(L, -1, "registered_items");
     184           0 :         lua_remove(L, -2); // Remove core
     185           0 :         luaL_checktype(L, -1, LUA_TTABLE);
     186           0 :         lua_getfield(L, -1, name);
     187           0 :         lua_remove(L, -2); // Remove registered_items
     188             :         // Should be a table
     189           0 :         if(lua_type(L, -1) != LUA_TTABLE)
     190             :         {
     191             :                 // Report error and clean up
     192           0 :                 errorstream << "Item \"" << name << "\" not defined" << std::endl;
     193           0 :                 lua_pop(L, 1);
     194             : 
     195             :                 // Try core.nodedef_default instead
     196           0 :                 lua_getglobal(L, "core");
     197           0 :                 lua_getfield(L, -1, "nodedef_default");
     198           0 :                 lua_remove(L, -2);
     199           0 :                 luaL_checktype(L, -1, LUA_TTABLE);
     200             :         }
     201           0 :         lua_getfield(L, -1, callbackname);
     202           0 :         lua_remove(L, -2); // Remove item def
     203             :         // Should be a function or nil
     204           0 :         if (lua_type(L, -1) == LUA_TFUNCTION) {
     205           0 :                 return true;
     206           0 :         } else if (!lua_isnil(L, -1)) {
     207           0 :                 errorstream << "Item \"" << name << "\" callback \""
     208           0 :                         << callbackname << "\" is not a function" << std::endl;
     209             :         }
     210           0 :         lua_pop(L, 1);
     211           0 :         return false;
     212             : }
     213             : 
     214           0 : void ScriptApiItem::pushPointedThing(const PointedThing& pointed)
     215             : {
     216           0 :         lua_State* L = getStack();
     217             : 
     218           0 :         lua_newtable(L);
     219           0 :         if(pointed.type == POINTEDTHING_NODE)
     220             :         {
     221           0 :                 lua_pushstring(L, "node");
     222           0 :                 lua_setfield(L, -2, "type");
     223           0 :                 push_v3s16(L, pointed.node_undersurface);
     224           0 :                 lua_setfield(L, -2, "under");
     225           0 :                 push_v3s16(L, pointed.node_abovesurface);
     226           0 :                 lua_setfield(L, -2, "above");
     227             :         }
     228           0 :         else if(pointed.type == POINTEDTHING_OBJECT)
     229             :         {
     230           0 :                 lua_pushstring(L, "object");
     231           0 :                 lua_setfield(L, -2, "type");
     232           0 :                 objectrefGet(L, pointed.object_id);
     233           0 :                 lua_setfield(L, -2, "ref");
     234             :         }
     235             :         else
     236             :         {
     237           0 :                 lua_pushstring(L, "nothing");
     238           0 :                 lua_setfield(L, -2, "type");
     239             :         }
     240           3 : }
     241             : 

Generated by: LCOV version 1.11