s_nodemeta.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /*
  2. Minetest
  3. Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 2.1 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License along
  13. with this program; if not, write to the Free Software Foundation, Inc.,
  14. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  15. */
  16. #include "cpp_api/s_nodemeta.h"
  17. #include "cpp_api/s_internal.h"
  18. #include "common/c_converter.h"
  19. #include "nodedef.h"
  20. #include "mapnode.h"
  21. #include "server.h"
  22. #include "environment.h"
  23. #include "lua_api/l_item.h"
  24. // Return number of accepted items to be moved
  25. int ScriptApiNodemeta::nodemeta_inventory_AllowMove(
  26. const MoveAction &ma, int count,
  27. ServerActiveObject *player)
  28. {
  29. SCRIPTAPI_PRECHECKHEADER
  30. int error_handler = PUSH_ERROR_HANDLER(L);
  31. const NodeDefManager *ndef = getServer()->ndef();
  32. // If node doesn't exist, we don't know what callback to call
  33. MapNode node = getEnv()->getMap().getNode(ma.to_inv.p);
  34. if (node.getContent() == CONTENT_IGNORE)
  35. return 0;
  36. // Push callback function on stack
  37. const auto &nodename = ndef->get(node).name;
  38. if (!getItemCallback(nodename.c_str(), "allow_metadata_inventory_move", &ma.to_inv.p))
  39. return count;
  40. // function(pos, from_list, from_index, to_list, to_index, count, player)
  41. push_v3s16(L, ma.to_inv.p); // pos
  42. lua_pushstring(L, ma.from_list.c_str()); // from_list
  43. lua_pushinteger(L, ma.from_i + 1); // from_index
  44. lua_pushstring(L, ma.to_list.c_str()); // to_list
  45. lua_pushinteger(L, ma.to_i + 1); // to_index
  46. lua_pushinteger(L, count); // count
  47. objectrefGetOrCreate(L, player); // player
  48. PCALL_RES(lua_pcall(L, 7, 1, error_handler));
  49. if (!lua_isnumber(L, -1))
  50. throw LuaError("allow_metadata_inventory_move should"
  51. " return a number. node=" + nodename);
  52. int num = luaL_checkinteger(L, -1);
  53. lua_pop(L, 2); // Pop integer and error handler
  54. return num;
  55. }
  56. // Return number of accepted items to be put
  57. int ScriptApiNodemeta::nodemeta_inventory_AllowPut(
  58. const MoveAction &ma, const ItemStack &stack,
  59. ServerActiveObject *player)
  60. {
  61. SCRIPTAPI_PRECHECKHEADER
  62. int error_handler = PUSH_ERROR_HANDLER(L);
  63. const NodeDefManager *ndef = getServer()->ndef();
  64. // If node doesn't exist, we don't know what callback to call
  65. MapNode node = getEnv()->getMap().getNode(ma.to_inv.p);
  66. if (node.getContent() == CONTENT_IGNORE)
  67. return 0;
  68. // Push callback function on stack
  69. const auto &nodename = ndef->get(node).name;
  70. if (!getItemCallback(nodename.c_str(), "allow_metadata_inventory_put", &ma.to_inv.p))
  71. return stack.count;
  72. // Call function(pos, listname, index, stack, player)
  73. push_v3s16(L, ma.to_inv.p); // pos
  74. lua_pushstring(L, ma.to_list.c_str()); // listname
  75. lua_pushinteger(L, ma.to_i + 1); // index
  76. LuaItemStack::create(L, stack); // stack
  77. objectrefGetOrCreate(L, player); // player
  78. PCALL_RES(lua_pcall(L, 5, 1, error_handler));
  79. if(!lua_isnumber(L, -1))
  80. throw LuaError("allow_metadata_inventory_put should"
  81. " return a number. node=" + nodename);
  82. int num = luaL_checkinteger(L, -1);
  83. lua_pop(L, 2); // Pop integer and error handler
  84. return num;
  85. }
  86. // Return number of accepted items to be taken
  87. int ScriptApiNodemeta::nodemeta_inventory_AllowTake(
  88. const MoveAction &ma, const ItemStack &stack,
  89. ServerActiveObject *player)
  90. {
  91. SCRIPTAPI_PRECHECKHEADER
  92. int error_handler = PUSH_ERROR_HANDLER(L);
  93. const NodeDefManager *ndef = getServer()->ndef();
  94. // If node doesn't exist, we don't know what callback to call
  95. MapNode node = getEnv()->getMap().getNode(ma.from_inv.p);
  96. if (node.getContent() == CONTENT_IGNORE)
  97. return 0;
  98. // Push callback function on stack
  99. const auto &nodename = ndef->get(node).name;
  100. if (!getItemCallback(nodename.c_str(), "allow_metadata_inventory_take", &ma.from_inv.p))
  101. return stack.count;
  102. // Call function(pos, listname, index, count, player)
  103. push_v3s16(L, ma.from_inv.p); // pos
  104. lua_pushstring(L, ma.from_list.c_str()); // listname
  105. lua_pushinteger(L, ma.from_i + 1); // index
  106. LuaItemStack::create(L, stack); // stack
  107. objectrefGetOrCreate(L, player); // player
  108. PCALL_RES(lua_pcall(L, 5, 1, error_handler));
  109. if (!lua_isnumber(L, -1))
  110. throw LuaError("allow_metadata_inventory_take should"
  111. " return a number. node=" + nodename);
  112. int num = luaL_checkinteger(L, -1);
  113. lua_pop(L, 2); // Pop integer and error handler
  114. return num;
  115. }
  116. // Report moved items
  117. void ScriptApiNodemeta::nodemeta_inventory_OnMove(
  118. const MoveAction &ma, int count,
  119. ServerActiveObject *player)
  120. {
  121. SCRIPTAPI_PRECHECKHEADER
  122. int error_handler = PUSH_ERROR_HANDLER(L);
  123. const NodeDefManager *ndef = getServer()->ndef();
  124. // If node doesn't exist, we don't know what callback to call
  125. MapNode node = getEnv()->getMap().getNode(ma.from_inv.p);
  126. if (node.getContent() == CONTENT_IGNORE)
  127. return;
  128. // Push callback function on stack
  129. const auto &nodename = ndef->get(node).name;
  130. if (!getItemCallback(nodename.c_str(), "on_metadata_inventory_move", &ma.from_inv.p))
  131. return;
  132. // function(pos, from_list, from_index, to_list, to_index, count, player)
  133. push_v3s16(L, ma.from_inv.p); // pos
  134. lua_pushstring(L, ma.from_list.c_str()); // from_list
  135. lua_pushinteger(L, ma.from_i + 1); // from_index
  136. lua_pushstring(L, ma.to_list.c_str()); // to_list
  137. lua_pushinteger(L, ma.to_i + 1); // to_index
  138. lua_pushinteger(L, count); // count
  139. objectrefGetOrCreate(L, player); // player
  140. PCALL_RES(lua_pcall(L, 7, 0, error_handler));
  141. lua_pop(L, 1); // Pop error handler
  142. }
  143. // Report put items
  144. void ScriptApiNodemeta::nodemeta_inventory_OnPut(
  145. const MoveAction &ma, const ItemStack &stack,
  146. ServerActiveObject *player)
  147. {
  148. SCRIPTAPI_PRECHECKHEADER
  149. int error_handler = PUSH_ERROR_HANDLER(L);
  150. const NodeDefManager *ndef = getServer()->ndef();
  151. // If node doesn't exist, we don't know what callback to call
  152. MapNode node = getEnv()->getMap().getNode(ma.to_inv.p);
  153. if (node.getContent() == CONTENT_IGNORE)
  154. return;
  155. // Push callback function on stack
  156. const auto &nodename = ndef->get(node).name;
  157. if (!getItemCallback(nodename.c_str(), "on_metadata_inventory_put", &ma.to_inv.p))
  158. return;
  159. // Call function(pos, listname, index, stack, player)
  160. push_v3s16(L, ma.to_inv.p); // pos
  161. lua_pushstring(L, ma.to_list.c_str()); // listname
  162. lua_pushinteger(L, ma.to_i + 1); // index
  163. LuaItemStack::create(L, stack); // stack
  164. objectrefGetOrCreate(L, player); // player
  165. PCALL_RES(lua_pcall(L, 5, 0, error_handler));
  166. lua_pop(L, 1); // Pop error handler
  167. }
  168. // Report taken items
  169. void ScriptApiNodemeta::nodemeta_inventory_OnTake(
  170. const MoveAction &ma, const ItemStack &stack,
  171. ServerActiveObject *player)
  172. {
  173. SCRIPTAPI_PRECHECKHEADER
  174. int error_handler = PUSH_ERROR_HANDLER(L);
  175. const NodeDefManager *ndef = getServer()->ndef();
  176. // If node doesn't exist, we don't know what callback to call
  177. MapNode node = getEnv()->getMap().getNode(ma.from_inv.p);
  178. if (node.getContent() == CONTENT_IGNORE)
  179. return;
  180. // Push callback function on stack
  181. const auto &nodename = ndef->get(node).name;
  182. if (!getItemCallback(nodename.c_str(), "on_metadata_inventory_take", &ma.from_inv.p))
  183. return;
  184. // Call function(pos, listname, index, stack, player)
  185. push_v3s16(L, ma.from_inv.p); // pos
  186. lua_pushstring(L, ma.from_list.c_str()); // listname
  187. lua_pushinteger(L, ma.from_i + 1); // index
  188. LuaItemStack::create(L, stack); // stack
  189. objectrefGetOrCreate(L, player); // player
  190. PCALL_RES(lua_pcall(L, 5, 0, error_handler));
  191. lua_pop(L, 1); // Pop error handler
  192. }