3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
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.
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.
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.
20 #include "cpp_api/s_nodemeta.h"
21 #include "cpp_api/s_internal.h"
22 #include "common/c_converter.h"
26 #include "environment.h"
27 #include "lua_api/l_item.h"
29 // Return number of accepted items to be moved
30 int ScriptApiNodemeta::nodemeta_inventory_AllowMove(v3s16 p,
31 const std::string &from_list, int from_index,
32 const std::string &to_list, int to_index,
33 int count, ServerActiveObject *player)
35 SCRIPTAPI_PRECHECKHEADER
37 int error_handler = PUSH_ERROR_HANDLER(L);
39 const NodeDefManager *ndef = getServer()->ndef();
41 // If node doesn't exist, we don't know what callback to call
42 MapNode node = getEnv()->getMap().getNodeNoEx(p);
43 if (node.getContent() == CONTENT_IGNORE)
46 // Push callback function on stack
47 std::string nodename = ndef->get(node).name;
48 if (!getItemCallback(nodename.c_str(), "allow_metadata_inventory_move", &p))
51 // function(pos, from_list, from_index, to_list, to_index, count, player)
52 push_v3s16(L, p); // pos
53 lua_pushstring(L, from_list.c_str()); // from_list
54 lua_pushinteger(L, from_index + 1); // from_index
55 lua_pushstring(L, to_list.c_str()); // to_list
56 lua_pushinteger(L, to_index + 1); // to_index
57 lua_pushinteger(L, count); // count
58 objectrefGetOrCreate(L, player); // player
59 PCALL_RES(lua_pcall(L, 7, 1, error_handler));
60 if (!lua_isnumber(L, -1))
61 throw LuaError("allow_metadata_inventory_move should"
62 " return a number, guilty node: " + nodename);
63 int num = luaL_checkinteger(L, -1);
64 lua_pop(L, 2); // Pop integer and error handler
68 // Return number of accepted items to be put
69 int ScriptApiNodemeta::nodemeta_inventory_AllowPut(v3s16 p,
70 const std::string &listname, int index, ItemStack &stack,
71 ServerActiveObject *player)
73 SCRIPTAPI_PRECHECKHEADER
75 int error_handler = PUSH_ERROR_HANDLER(L);
77 const NodeDefManager *ndef = getServer()->ndef();
79 // If node doesn't exist, we don't know what callback to call
80 MapNode node = getEnv()->getMap().getNodeNoEx(p);
81 if (node.getContent() == CONTENT_IGNORE)
84 // Push callback function on stack
85 std::string nodename = ndef->get(node).name;
86 if (!getItemCallback(nodename.c_str(), "allow_metadata_inventory_put", &p))
89 // Call function(pos, listname, index, stack, player)
90 push_v3s16(L, p); // pos
91 lua_pushstring(L, listname.c_str()); // listname
92 lua_pushinteger(L, index + 1); // index
93 LuaItemStack::create(L, stack); // stack
94 objectrefGetOrCreate(L, player); // player
95 PCALL_RES(lua_pcall(L, 5, 1, error_handler));
96 if(!lua_isnumber(L, -1))
97 throw LuaError("allow_metadata_inventory_put should"
98 " return a number, guilty node: " + nodename);
99 int num = luaL_checkinteger(L, -1);
100 lua_pop(L, 2); // Pop integer and error handler
104 // Return number of accepted items to be taken
105 int ScriptApiNodemeta::nodemeta_inventory_AllowTake(v3s16 p,
106 const std::string &listname, int index, ItemStack &stack,
107 ServerActiveObject *player)
109 SCRIPTAPI_PRECHECKHEADER
111 int error_handler = PUSH_ERROR_HANDLER(L);
113 const NodeDefManager *ndef = getServer()->ndef();
115 // If node doesn't exist, we don't know what callback to call
116 MapNode node = getEnv()->getMap().getNodeNoEx(p);
117 if (node.getContent() == CONTENT_IGNORE)
120 // Push callback function on stack
121 std::string nodename = ndef->get(node).name;
122 if (!getItemCallback(nodename.c_str(), "allow_metadata_inventory_take", &p))
125 // Call function(pos, listname, index, count, player)
126 push_v3s16(L, p); // pos
127 lua_pushstring(L, listname.c_str()); // listname
128 lua_pushinteger(L, index + 1); // index
129 LuaItemStack::create(L, stack); // stack
130 objectrefGetOrCreate(L, player); // player
131 PCALL_RES(lua_pcall(L, 5, 1, error_handler));
132 if (!lua_isnumber(L, -1))
133 throw LuaError("allow_metadata_inventory_take should"
134 " return a number, guilty node: " + nodename);
135 int num = luaL_checkinteger(L, -1);
136 lua_pop(L, 2); // Pop integer and error handler
140 // Report moved items
141 void ScriptApiNodemeta::nodemeta_inventory_OnMove(v3s16 p,
142 const std::string &from_list, int from_index,
143 const std::string &to_list, int to_index,
144 int count, ServerActiveObject *player)
146 SCRIPTAPI_PRECHECKHEADER
148 int error_handler = PUSH_ERROR_HANDLER(L);
150 const NodeDefManager *ndef = getServer()->ndef();
152 // If node doesn't exist, we don't know what callback to call
153 MapNode node = getEnv()->getMap().getNodeNoEx(p);
154 if (node.getContent() == CONTENT_IGNORE)
157 // Push callback function on stack
158 std::string nodename = ndef->get(node).name;
159 if (!getItemCallback(nodename.c_str(), "on_metadata_inventory_move", &p))
162 // function(pos, from_list, from_index, to_list, to_index, count, player)
163 push_v3s16(L, p); // pos
164 lua_pushstring(L, from_list.c_str()); // from_list
165 lua_pushinteger(L, from_index + 1); // from_index
166 lua_pushstring(L, to_list.c_str()); // to_list
167 lua_pushinteger(L, to_index + 1); // to_index
168 lua_pushinteger(L, count); // count
169 objectrefGetOrCreate(L, player); // player
170 PCALL_RES(lua_pcall(L, 7, 0, error_handler));
171 lua_pop(L, 1); // Pop error handler
175 void ScriptApiNodemeta::nodemeta_inventory_OnPut(v3s16 p,
176 const std::string &listname, int index, ItemStack &stack,
177 ServerActiveObject *player)
179 SCRIPTAPI_PRECHECKHEADER
181 int error_handler = PUSH_ERROR_HANDLER(L);
183 const NodeDefManager *ndef = getServer()->ndef();
185 // If node doesn't exist, we don't know what callback to call
186 MapNode node = getEnv()->getMap().getNodeNoEx(p);
187 if (node.getContent() == CONTENT_IGNORE)
190 // Push callback function on stack
191 std::string nodename = ndef->get(node).name;
192 if (!getItemCallback(nodename.c_str(), "on_metadata_inventory_put", &p))
195 // Call function(pos, listname, index, stack, player)
196 push_v3s16(L, p); // pos
197 lua_pushstring(L, listname.c_str()); // listname
198 lua_pushinteger(L, index + 1); // index
199 LuaItemStack::create(L, stack); // stack
200 objectrefGetOrCreate(L, player); // player
201 PCALL_RES(lua_pcall(L, 5, 0, error_handler));
202 lua_pop(L, 1); // Pop error handler
205 // Report taken items
206 void ScriptApiNodemeta::nodemeta_inventory_OnTake(v3s16 p,
207 const std::string &listname, int index, ItemStack &stack,
208 ServerActiveObject *player)
210 SCRIPTAPI_PRECHECKHEADER
212 int error_handler = PUSH_ERROR_HANDLER(L);
214 const NodeDefManager *ndef = getServer()->ndef();
216 // If node doesn't exist, we don't know what callback to call
217 MapNode node = getEnv()->getMap().getNodeNoEx(p);
218 if (node.getContent() == CONTENT_IGNORE)
221 // Push callback function on stack
222 std::string nodename = ndef->get(node).name;
223 if (!getItemCallback(nodename.c_str(), "on_metadata_inventory_take", &p))
226 // Call function(pos, listname, index, stack, player)
227 push_v3s16(L, p); // pos
228 lua_pushstring(L, listname.c_str()); // listname
229 lua_pushinteger(L, index + 1); // index
230 LuaItemStack::create(L, stack); // stack
231 objectrefGetOrCreate(L, player); // player
232 PCALL_RES(lua_pcall(L, 5, 0, error_handler));
233 lua_pop(L, 1); // Pop error handler