]> git.lizzy.rs Git - minetest.git/blob - src/script/lua_api/l_item.cpp
Fix minetest.get_(all)_craft_recipe(s) regression
[minetest.git] / src / script / lua_api / l_item.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 "lua_api/l_item.h"
21 #include "lua_api/l_internal.h"
22 #include "common/c_converter.h"
23 #include "common/c_content.h"
24 #include "itemdef.h"
25 #include "nodedef.h"
26 #include "server.h"
27 #include "content_sao.h"
28 #include "inventory.h"
29 #include "log.h"
30
31
32 // garbage collector
33 int LuaItemStack::gc_object(lua_State *L)
34 {
35         LuaItemStack *o = *(LuaItemStack **)(lua_touserdata(L, 1));
36         delete o;
37         return 0;
38 }
39
40 // is_empty(self) -> true/false
41 int LuaItemStack::l_is_empty(lua_State *L)
42 {
43         NO_MAP_LOCK_REQUIRED;
44         LuaItemStack *o = checkobject(L, 1);
45         ItemStack &item = o->m_stack;
46         lua_pushboolean(L, item.empty());
47         return 1;
48 }
49
50 // get_name(self) -> string
51 int LuaItemStack::l_get_name(lua_State *L)
52 {
53         NO_MAP_LOCK_REQUIRED;
54         LuaItemStack *o = checkobject(L, 1);
55         ItemStack &item = o->m_stack;
56         lua_pushstring(L, item.name.c_str());
57         return 1;
58 }
59
60 // set_name(self, name)
61 int LuaItemStack::l_set_name(lua_State *L)
62 {
63         NO_MAP_LOCK_REQUIRED;
64         LuaItemStack *o = checkobject(L, 1);
65         ItemStack &item = o->m_stack;
66
67         bool status = true;
68         item.name = luaL_checkstring(L, 2);
69         if (item.name == "" || item.empty()) {
70                 item.clear();
71                 status = false;
72         }
73
74         lua_pushboolean(L, status);
75         return 1;
76 }
77
78 // get_count(self) -> number
79 int LuaItemStack::l_get_count(lua_State *L)
80 {
81         NO_MAP_LOCK_REQUIRED;
82         LuaItemStack *o = checkobject(L, 1);
83         ItemStack &item = o->m_stack;
84         lua_pushinteger(L, item.count);
85         return 1;
86 }
87
88 // set_count(self, number)
89 int LuaItemStack::l_set_count(lua_State *L)
90 {
91         NO_MAP_LOCK_REQUIRED;
92         LuaItemStack *o = checkobject(L, 1);
93         ItemStack &item = o->m_stack;
94
95         bool status;
96         lua_Integer count = luaL_checkinteger(L, 2);
97         if (count <= 65535) {
98                 item.count = count;
99                 status = true;
100         } else {
101                 item.clear();
102                 status = false;
103         }
104
105         lua_pushboolean(L, status);
106         return 1;
107 }
108
109 // get_wear(self) -> number
110 int LuaItemStack::l_get_wear(lua_State *L)
111 {
112         NO_MAP_LOCK_REQUIRED;
113         LuaItemStack *o = checkobject(L, 1);
114         ItemStack &item = o->m_stack;
115         lua_pushinteger(L, item.wear);
116         return 1;
117 }
118
119 // set_wear(self, number)
120 int LuaItemStack::l_set_wear(lua_State *L)
121 {
122         NO_MAP_LOCK_REQUIRED;
123         LuaItemStack *o = checkobject(L, 1);
124         ItemStack &item = o->m_stack;
125
126         bool status;
127         lua_Integer wear = luaL_checkinteger(L, 2);
128         if (wear <= 65535) {
129                 item.wear = wear;
130                 status = true;
131         } else {
132                 item.clear();
133                 status = false;
134         }
135
136         lua_pushboolean(L, status);
137         return 1;
138 }
139
140 // get_metadata(self) -> string
141 int LuaItemStack::l_get_metadata(lua_State *L)
142 {
143         NO_MAP_LOCK_REQUIRED;
144         LuaItemStack *o = checkobject(L, 1);
145         ItemStack &item = o->m_stack;
146         lua_pushlstring(L, item.metadata.c_str(), item.metadata.size());
147         return 1;
148 }
149
150 // set_metadata(self, string)
151 int LuaItemStack::l_set_metadata(lua_State *L)
152 {
153         NO_MAP_LOCK_REQUIRED;
154         LuaItemStack *o = checkobject(L, 1);
155         ItemStack &item = o->m_stack;
156
157         size_t len = 0;
158         const char *ptr = luaL_checklstring(L, 2, &len);
159         item.metadata.assign(ptr, len);
160
161         lua_pushboolean(L, true);
162         return 1;
163 }
164
165 // clear(self) -> true
166 int LuaItemStack::l_clear(lua_State *L)
167 {
168         NO_MAP_LOCK_REQUIRED;
169         LuaItemStack *o = checkobject(L, 1);
170         o->m_stack.clear();
171         lua_pushboolean(L, true);
172         return 1;
173 }
174
175 // replace(self, itemstack or itemstring or table or nil) -> true
176 int LuaItemStack::l_replace(lua_State *L)
177 {
178         NO_MAP_LOCK_REQUIRED;
179         LuaItemStack *o = checkobject(L, 1);
180         o->m_stack = read_item(L,2,getServer(L));
181         lua_pushboolean(L, true);
182         return 1;
183 }
184
185 // to_string(self) -> string
186 int LuaItemStack::l_to_string(lua_State *L)
187 {
188         NO_MAP_LOCK_REQUIRED;
189         LuaItemStack *o = checkobject(L, 1);
190         std::string itemstring = o->m_stack.getItemString();
191         lua_pushstring(L, itemstring.c_str());
192         return 1;
193 }
194
195 // to_table(self) -> table or nil
196 int LuaItemStack::l_to_table(lua_State *L)
197 {
198         NO_MAP_LOCK_REQUIRED;
199         LuaItemStack *o = checkobject(L, 1);
200         const ItemStack &item = o->m_stack;
201         if(item.empty())
202         {
203                 lua_pushnil(L);
204         }
205         else
206         {
207                 lua_newtable(L);
208                 lua_pushstring(L, item.name.c_str());
209                 lua_setfield(L, -2, "name");
210                 lua_pushinteger(L, item.count);
211                 lua_setfield(L, -2, "count");
212                 lua_pushinteger(L, item.wear);
213                 lua_setfield(L, -2, "wear");
214                 lua_pushlstring(L, item.metadata.c_str(), item.metadata.size());
215                 lua_setfield(L, -2, "metadata");
216         }
217         return 1;
218 }
219
220 // get_stack_max(self) -> number
221 int LuaItemStack::l_get_stack_max(lua_State *L)
222 {
223         NO_MAP_LOCK_REQUIRED;
224         LuaItemStack *o = checkobject(L, 1);
225         ItemStack &item = o->m_stack;
226         lua_pushinteger(L, item.getStackMax(getServer(L)->idef()));
227         return 1;
228 }
229
230 // get_free_space(self) -> number
231 int LuaItemStack::l_get_free_space(lua_State *L)
232 {
233         NO_MAP_LOCK_REQUIRED;
234         LuaItemStack *o = checkobject(L, 1);
235         ItemStack &item = o->m_stack;
236         lua_pushinteger(L, item.freeSpace(getServer(L)->idef()));
237         return 1;
238 }
239
240 // is_known(self) -> true/false
241 // Checks if the item is defined.
242 int LuaItemStack::l_is_known(lua_State *L)
243 {
244         NO_MAP_LOCK_REQUIRED;
245         LuaItemStack *o = checkobject(L, 1);
246         ItemStack &item = o->m_stack;
247         bool is_known = item.isKnown(getServer(L)->idef());
248         lua_pushboolean(L, is_known);
249         return 1;
250 }
251
252 // get_definition(self) -> table
253 // Returns the item definition table from registered_items,
254 // or a fallback one (name="unknown")
255 int LuaItemStack::l_get_definition(lua_State *L)
256 {
257         NO_MAP_LOCK_REQUIRED;
258         LuaItemStack *o = checkobject(L, 1);
259         ItemStack &item = o->m_stack;
260
261         // Get registered_items[name]
262         lua_getglobal(L, "core");
263         lua_getfield(L, -1, "registered_items");
264         luaL_checktype(L, -1, LUA_TTABLE);
265         lua_getfield(L, -1, item.name.c_str());
266         if(lua_isnil(L, -1))
267         {
268                 lua_pop(L, 1);
269                 lua_getfield(L, -1, "unknown");
270         }
271         return 1;
272 }
273
274 // get_tool_capabilities(self) -> table
275 // Returns the effective tool digging properties.
276 // Returns those of the hand ("") if this item has none associated.
277 int LuaItemStack::l_get_tool_capabilities(lua_State *L)
278 {
279         NO_MAP_LOCK_REQUIRED;
280         LuaItemStack *o = checkobject(L, 1);
281         ItemStack &item = o->m_stack;
282         const ToolCapabilities &prop =
283                 item.getToolCapabilities(getServer(L)->idef());
284         push_tool_capabilities(L, prop);
285         return 1;
286 }
287
288 // add_wear(self, amount) -> true/false
289 // The range for "amount" is [0,65535]. Wear is only added if the item
290 // is a tool. Adding wear might destroy the item.
291 // Returns true if the item is (or was) a tool.
292 int LuaItemStack::l_add_wear(lua_State *L)
293 {
294         NO_MAP_LOCK_REQUIRED;
295         LuaItemStack *o = checkobject(L, 1);
296         ItemStack &item = o->m_stack;
297         int amount = lua_tointeger(L, 2);
298         bool result = item.addWear(amount, getServer(L)->idef());
299         lua_pushboolean(L, result);
300         return 1;
301 }
302
303 // add_item(self, itemstack or itemstring or table or nil) -> itemstack
304 // Returns leftover item stack
305 int LuaItemStack::l_add_item(lua_State *L)
306 {
307         NO_MAP_LOCK_REQUIRED;
308         LuaItemStack *o = checkobject(L, 1);
309         ItemStack &item = o->m_stack;
310         ItemStack newitem = read_item(L,-1, getServer(L));
311         ItemStack leftover = item.addItem(newitem, getServer(L)->idef());
312         create(L, leftover);
313         return 1;
314 }
315
316 // item_fits(self, itemstack or itemstring or table or nil) -> true/false, itemstack
317 // First return value is true iff the new item fits fully into the stack
318 // Second return value is the would-be-left-over item stack
319 int LuaItemStack::l_item_fits(lua_State *L)
320 {
321         NO_MAP_LOCK_REQUIRED;
322         LuaItemStack *o = checkobject(L, 1);
323         ItemStack &item = o->m_stack;
324         ItemStack newitem = read_item(L, 2, getServer(L));
325         ItemStack restitem;
326         bool fits = item.itemFits(newitem, &restitem, getServer(L)->idef());
327         lua_pushboolean(L, fits);  // first return value
328         create(L, restitem);       // second return value
329         return 2;
330 }
331
332 // take_item(self, takecount=1) -> itemstack
333 int LuaItemStack::l_take_item(lua_State *L)
334 {
335         NO_MAP_LOCK_REQUIRED;
336         LuaItemStack *o = checkobject(L, 1);
337         ItemStack &item = o->m_stack;
338         u32 takecount = 1;
339         if(!lua_isnone(L, 2))
340                 takecount = luaL_checkinteger(L, 2);
341         ItemStack taken = item.takeItem(takecount);
342         create(L, taken);
343         return 1;
344 }
345
346 // peek_item(self, peekcount=1) -> itemstack
347 int LuaItemStack::l_peek_item(lua_State *L)
348 {
349         NO_MAP_LOCK_REQUIRED;
350         LuaItemStack *o = checkobject(L, 1);
351         ItemStack &item = o->m_stack;
352         u32 peekcount = 1;
353         if(!lua_isnone(L, 2))
354                 peekcount = lua_tointeger(L, 2);
355         ItemStack peekaboo = item.peekItem(peekcount);
356         create(L, peekaboo);
357         return 1;
358 }
359
360 LuaItemStack::LuaItemStack(const ItemStack &item):
361         m_stack(item)
362 {
363 }
364
365 LuaItemStack::~LuaItemStack()
366 {
367 }
368
369 const ItemStack& LuaItemStack::getItem() const
370 {
371         return m_stack;
372 }
373 ItemStack& LuaItemStack::getItem()
374 {
375         return m_stack;
376 }
377
378 // LuaItemStack(itemstack or itemstring or table or nil)
379 // Creates an LuaItemStack and leaves it on top of stack
380 int LuaItemStack::create_object(lua_State *L)
381 {
382         NO_MAP_LOCK_REQUIRED;
383         ItemStack item = read_item(L, 1, getServer(L));
384         LuaItemStack *o = new LuaItemStack(item);
385         *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
386         luaL_getmetatable(L, className);
387         lua_setmetatable(L, -2);
388         return 1;
389 }
390 // Not callable from Lua
391 int LuaItemStack::create(lua_State *L, const ItemStack &item)
392 {
393         NO_MAP_LOCK_REQUIRED;
394         LuaItemStack *o = new LuaItemStack(item);
395         *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
396         luaL_getmetatable(L, className);
397         lua_setmetatable(L, -2);
398         return 1;
399 }
400
401 LuaItemStack* LuaItemStack::checkobject(lua_State *L, int narg)
402 {
403         luaL_checktype(L, narg, LUA_TUSERDATA);
404         void *ud = luaL_checkudata(L, narg, className);
405         if(!ud) luaL_typerror(L, narg, className);
406         return *(LuaItemStack**)ud;  // unbox pointer
407 }
408
409 void LuaItemStack::Register(lua_State *L)
410 {
411         lua_newtable(L);
412         int methodtable = lua_gettop(L);
413         luaL_newmetatable(L, className);
414         int metatable = lua_gettop(L);
415
416         lua_pushliteral(L, "__metatable");
417         lua_pushvalue(L, methodtable);
418         lua_settable(L, metatable);  // hide metatable from Lua getmetatable()
419
420         lua_pushliteral(L, "__index");
421         lua_pushvalue(L, methodtable);
422         lua_settable(L, metatable);
423
424         lua_pushliteral(L, "__gc");
425         lua_pushcfunction(L, gc_object);
426         lua_settable(L, metatable);
427
428         lua_pop(L, 1);  // drop metatable
429
430         luaL_openlib(L, 0, methods, 0);  // fill methodtable
431         lua_pop(L, 1);  // drop methodtable
432
433         // Can be created from Lua (LuaItemStack(itemstack or itemstring or table or nil))
434         lua_register(L, className, create_object);
435 }
436
437 const char LuaItemStack::className[] = "ItemStack";
438 const luaL_reg LuaItemStack::methods[] = {
439         luamethod(LuaItemStack, is_empty),
440         luamethod(LuaItemStack, get_name),
441         luamethod(LuaItemStack, set_name),
442         luamethod(LuaItemStack, get_count),
443         luamethod(LuaItemStack, set_count),
444         luamethod(LuaItemStack, get_wear),
445         luamethod(LuaItemStack, set_wear),
446         luamethod(LuaItemStack, get_metadata),
447         luamethod(LuaItemStack, set_metadata),
448         luamethod(LuaItemStack, clear),
449         luamethod(LuaItemStack, replace),
450         luamethod(LuaItemStack, to_string),
451         luamethod(LuaItemStack, to_table),
452         luamethod(LuaItemStack, get_stack_max),
453         luamethod(LuaItemStack, get_free_space),
454         luamethod(LuaItemStack, is_known),
455         luamethod(LuaItemStack, get_definition),
456         luamethod(LuaItemStack, get_tool_capabilities),
457         luamethod(LuaItemStack, add_wear),
458         luamethod(LuaItemStack, add_item),
459         luamethod(LuaItemStack, item_fits),
460         luamethod(LuaItemStack, take_item),
461         luamethod(LuaItemStack, peek_item),
462         {0,0}
463 };
464
465 /*
466         ItemDefinition
467 */
468
469 // register_item_raw({lots of stuff})
470 int ModApiItemMod::l_register_item_raw(lua_State *L)
471 {
472         NO_MAP_LOCK_REQUIRED;
473         luaL_checktype(L, 1, LUA_TTABLE);
474         int table = 1;
475
476         // Get the writable item and node definition managers from the server
477         IWritableItemDefManager *idef =
478                         getServer(L)->getWritableItemDefManager();
479         IWritableNodeDefManager *ndef =
480                         getServer(L)->getWritableNodeDefManager();
481
482         // Check if name is defined
483         std::string name;
484         lua_getfield(L, table, "name");
485         if(lua_isstring(L, -1)){
486                 name = lua_tostring(L, -1);
487                 verbosestream<<"register_item_raw: "<<name<<std::endl;
488         } else {
489                 throw LuaError("register_item_raw: name is not defined or not a string");
490         }
491
492         // Check if on_use is defined
493
494         ItemDefinition def;
495         // Set a distinctive default value to check if this is set
496         def.node_placement_prediction = "__default";
497
498         // Read the item definition
499         def = read_item_definition(L, table, def);
500
501         // Default to having client-side placement prediction for nodes
502         // ("" in item definition sets it off)
503         if(def.node_placement_prediction == "__default"){
504                 if(def.type == ITEM_NODE)
505                         def.node_placement_prediction = name;
506                 else
507                         def.node_placement_prediction = "";
508         }
509
510         // Register item definition
511         idef->registerItem(def);
512
513         // Read the node definition (content features) and register it
514         if(def.type == ITEM_NODE){
515                 ContentFeatures f = read_content_features(L, table);
516                 content_t id = ndef->set(f.name, f);
517
518                 if(id > MAX_REGISTERED_CONTENT){
519                         throw LuaError("Number of registerable nodes ("
520                                         + itos(MAX_REGISTERED_CONTENT+1)
521                                         + ") exceeded (" + name + ")");
522                 }
523         }
524
525         return 0; /* number of results */
526 }
527
528 // register_alias_raw(name, convert_to_name)
529 int ModApiItemMod::l_register_alias_raw(lua_State *L)
530 {
531         NO_MAP_LOCK_REQUIRED;
532         std::string name = luaL_checkstring(L, 1);
533         std::string convert_to = luaL_checkstring(L, 2);
534
535         // Get the writable item definition manager from the server
536         IWritableItemDefManager *idef =
537                         getServer(L)->getWritableItemDefManager();
538
539         idef->registerAlias(name, convert_to);
540
541         return 0; /* number of results */
542 }
543
544 // get_content_id(name)
545 int ModApiItemMod::l_get_content_id(lua_State *L)
546 {
547         NO_MAP_LOCK_REQUIRED;
548         std::string name = luaL_checkstring(L, 1);
549
550         INodeDefManager *ndef = getServer(L)->getNodeDefManager();
551         content_t c = ndef->getId(name);
552
553         lua_pushinteger(L, c);
554         return 1; /* number of results */
555 }
556
557 // get_name_from_content_id(name)
558 int ModApiItemMod::l_get_name_from_content_id(lua_State *L)
559 {
560         NO_MAP_LOCK_REQUIRED;
561         content_t c = luaL_checkint(L, 1);
562
563         INodeDefManager *ndef = getServer(L)->getNodeDefManager();
564         const char *name = ndef->get(c).name.c_str();
565
566         lua_pushstring(L, name);
567         return 1; /* number of results */
568 }
569
570 void ModApiItemMod::Initialize(lua_State *L, int top)
571 {
572         API_FCT(register_item_raw);
573         API_FCT(register_alias_raw);
574         API_FCT(get_content_id);
575         API_FCT(get_name_from_content_id);
576 }