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