]> git.lizzy.rs Git - minetest.git/blob - src/script/cpp_api/s_nodemeta.cpp
Merge remote-tracking branch 'origin/master'
[minetest.git] / src / script / cpp_api / s_nodemeta.cpp
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_nodemeta.h"
21 #include "common/c_converter.h"
22 #include "nodedef.h"
23 #include "mapnode.h"
24 #include "server.h"
25 #include "lua_api/l_item.h"
26
27 extern "C" {
28 #include "lauxlib.h"
29 }
30
31 // Return number of accepted items to be moved
32 int ScriptApiNodemeta::nodemeta_inventory_AllowMove(v3s16 p,
33                 const std::string &from_list, int from_index,
34                 const std::string &to_list, int to_index,
35                 int count, ServerActiveObject *player)
36 {
37         SCRIPTAPI_PRECHECKHEADER
38
39         INodeDefManager *ndef = getServer()->ndef();
40
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)
44                 return 0;
45
46         // Push callback function on stack
47         if(!getItemCallback(ndef->get(node).name.c_str(),
48                         "allow_metadata_inventory_move"))
49                 return count;
50
51         // function(pos, from_list, from_index, to_list, to_index, count, player)
52         // pos
53         push_v3s16(L, p);
54         // from_list
55         lua_pushstring(L, from_list.c_str());
56         // from_index
57         lua_pushinteger(L, from_index + 1);
58         // to_list
59         lua_pushstring(L, to_list.c_str());
60         // to_index
61         lua_pushinteger(L, to_index + 1);
62         // count
63         lua_pushinteger(L, count);
64         // player
65         objectrefGetOrCreate(player);
66         if(lua_pcall(L, 7, 1, 0))
67                 scriptError("error: %s", lua_tostring(L, -1));
68         if(!lua_isnumber(L, -1))
69                 throw LuaError(L, "allow_metadata_inventory_move should return a number");
70         return luaL_checkinteger(L, -1);
71 }
72
73 // Return number of accepted items to be put
74 int ScriptApiNodemeta::nodemeta_inventory_AllowPut(v3s16 p,
75                 const std::string &listname, int index, ItemStack &stack,
76                 ServerActiveObject *player)
77 {
78         SCRIPTAPI_PRECHECKHEADER
79
80         INodeDefManager *ndef = getServer()->ndef();
81
82         // If node doesn't exist, we don't know what callback to call
83         MapNode node = getEnv()->getMap().getNodeNoEx(p);
84         if(node.getContent() == CONTENT_IGNORE)
85                 return 0;
86
87         // Push callback function on stack
88         if(!getItemCallback(ndef->get(node).name.c_str(),
89                         "allow_metadata_inventory_put"))
90                 return stack.count;
91
92         // Call function(pos, listname, index, stack, player)
93         // pos
94         push_v3s16(L, p);
95         // listname
96         lua_pushstring(L, listname.c_str());
97         // index
98         lua_pushinteger(L, index + 1);
99         // stack
100         LuaItemStack::create(L, stack);
101         // player
102         objectrefGetOrCreate(player);
103         if(lua_pcall(L, 5, 1, 0))
104                 scriptError("error: %s", lua_tostring(L, -1));
105         if(!lua_isnumber(L, -1))
106                 throw LuaError(L, "allow_metadata_inventory_put should return a number");
107         return luaL_checkinteger(L, -1);
108 }
109
110 // Return number of accepted items to be taken
111 int ScriptApiNodemeta::nodemeta_inventory_AllowTake(v3s16 p,
112                 const std::string &listname, int index, ItemStack &stack,
113                 ServerActiveObject *player)
114 {
115         SCRIPTAPI_PRECHECKHEADER
116
117         INodeDefManager *ndef = getServer()->ndef();
118
119         // If node doesn't exist, we don't know what callback to call
120         MapNode node = getEnv()->getMap().getNodeNoEx(p);
121         if(node.getContent() == CONTENT_IGNORE)
122                 return 0;
123
124         // Push callback function on stack
125         if(!getItemCallback(ndef->get(node).name.c_str(),
126                         "allow_metadata_inventory_take"))
127                 return stack.count;
128
129         // Call function(pos, listname, index, count, player)
130         // pos
131         push_v3s16(L, p);
132         // listname
133         lua_pushstring(L, listname.c_str());
134         // index
135         lua_pushinteger(L, index + 1);
136         // stack
137         LuaItemStack::create(L, stack);
138         // player
139         objectrefGetOrCreate(player);
140         if(lua_pcall(L, 5, 1, 0))
141                 scriptError("error: %s", lua_tostring(L, -1));
142         if(!lua_isnumber(L, -1))
143                 throw LuaError(L, "allow_metadata_inventory_take should return a number");
144         return luaL_checkinteger(L, -1);
145 }
146
147 // Report moved items
148 void ScriptApiNodemeta::nodemeta_inventory_OnMove(v3s16 p,
149                 const std::string &from_list, int from_index,
150                 const std::string &to_list, int to_index,
151                 int count, ServerActiveObject *player)
152 {
153         SCRIPTAPI_PRECHECKHEADER
154
155         INodeDefManager *ndef = getServer()->ndef();
156
157         // If node doesn't exist, we don't know what callback to call
158         MapNode node = getEnv()->getMap().getNodeNoEx(p);
159         if(node.getContent() == CONTENT_IGNORE)
160                 return;
161
162         // Push callback function on stack
163         if(!getItemCallback(ndef->get(node).name.c_str(),
164                         "on_metadata_inventory_move"))
165                 return;
166
167         // function(pos, from_list, from_index, to_list, to_index, count, player)
168         // pos
169         push_v3s16(L, p);
170         // from_list
171         lua_pushstring(L, from_list.c_str());
172         // from_index
173         lua_pushinteger(L, from_index + 1);
174         // to_list
175         lua_pushstring(L, to_list.c_str());
176         // to_index
177         lua_pushinteger(L, to_index + 1);
178         // count
179         lua_pushinteger(L, count);
180         // player
181         objectrefGetOrCreate(player);
182         if(lua_pcall(L, 7, 0, 0))
183                 scriptError("error: %s", lua_tostring(L, -1));
184 }
185
186 // Report put items
187 void ScriptApiNodemeta::nodemeta_inventory_OnPut(v3s16 p,
188                 const std::string &listname, int index, ItemStack &stack,
189                 ServerActiveObject *player)
190 {
191         SCRIPTAPI_PRECHECKHEADER
192
193         INodeDefManager *ndef = getServer()->ndef();
194
195         // If node doesn't exist, we don't know what callback to call
196         MapNode node = getEnv()->getMap().getNodeNoEx(p);
197         if(node.getContent() == CONTENT_IGNORE)
198                 return;
199
200         // Push callback function on stack
201         if(!getItemCallback(ndef->get(node).name.c_str(),
202                         "on_metadata_inventory_put"))
203                 return;
204
205         // Call function(pos, listname, index, stack, player)
206         // pos
207         push_v3s16(L, p);
208         // listname
209         lua_pushstring(L, listname.c_str());
210         // index
211         lua_pushinteger(L, index + 1);
212         // stack
213         LuaItemStack::create(L, stack);
214         // player
215         objectrefGetOrCreate(player);
216         if(lua_pcall(L, 5, 0, 0))
217                 scriptError("error: %s", lua_tostring(L, -1));
218 }
219
220 // Report taken items
221 void ScriptApiNodemeta::nodemeta_inventory_OnTake(v3s16 p,
222                 const std::string &listname, int index, ItemStack &stack,
223                 ServerActiveObject *player)
224 {
225         SCRIPTAPI_PRECHECKHEADER
226
227         INodeDefManager *ndef = getServer()->ndef();
228
229         // If node doesn't exist, we don't know what callback to call
230         MapNode node = getEnv()->getMap().getNodeNoEx(p);
231         if(node.getContent() == CONTENT_IGNORE)
232                 return;
233
234         // Push callback function on stack
235         if(!getItemCallback(ndef->get(node).name.c_str(),
236                         "on_metadata_inventory_take"))
237                 return;
238
239         // Call function(pos, listname, index, stack, player)
240         // pos
241         push_v3s16(L, p);
242         // listname
243         lua_pushstring(L, listname.c_str());
244         // index
245         lua_pushinteger(L, index + 1);
246         // stack
247         LuaItemStack::create(L, stack);
248         // player
249         objectrefGetOrCreate(player);
250         if(lua_pcall(L, 5, 0, 0))
251                 scriptError("error: %s", lua_tostring(L, -1));
252 }
253
254 ScriptApiNodemeta::ScriptApiNodemeta() {
255 }
256
257 ScriptApiNodemeta::~ScriptApiNodemeta() {
258 }
259
260
261