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