]> git.lizzy.rs Git - dragonfireclient.git/blob - src/script/lua_api/l_item.cpp
Add helper functions to make tool usable n times (#12047)
[dragonfireclient.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_itemstackmeta.h"
22 #include "lua_api/l_internal.h"
23 #include "common/c_converter.h"
24 #include "common/c_content.h"
25 #include "common/c_packer.h"
26 #include "itemdef.h"
27 #include "nodedef.h"
28 #include "server.h"
29 #include "inventory.h"
30 #include "log.h"
31
32
33 // garbage collector
34 int LuaItemStack::gc_object(lua_State *L)
35 {
36         LuaItemStack *o = *(LuaItemStack **)(lua_touserdata(L, 1));
37         delete o;
38         return 0;
39 }
40
41 // __tostring metamethod
42 int LuaItemStack::mt_tostring(lua_State *L)
43 {
44         LuaItemStack *o = checkobject(L, 1);
45         std::string itemstring = o->m_stack.getItemString(false);
46         lua_pushfstring(L, "ItemStack(\"%s\")", itemstring.c_str());
47         return 1;
48 }
49
50 // is_empty(self) -> true/false
51 int LuaItemStack::l_is_empty(lua_State *L)
52 {
53         NO_MAP_LOCK_REQUIRED;
54         LuaItemStack *o = checkobject(L, 1);
55         ItemStack &item = o->m_stack;
56         lua_pushboolean(L, item.empty());
57         return 1;
58 }
59
60 // get_name(self) -> string
61 int LuaItemStack::l_get_name(lua_State *L)
62 {
63         NO_MAP_LOCK_REQUIRED;
64         LuaItemStack *o = checkobject(L, 1);
65         ItemStack &item = o->m_stack;
66         lua_pushstring(L, item.name.c_str());
67         return 1;
68 }
69
70 // set_name(self, name)
71 int LuaItemStack::l_set_name(lua_State *L)
72 {
73         NO_MAP_LOCK_REQUIRED;
74         LuaItemStack *o = checkobject(L, 1);
75         ItemStack &item = o->m_stack;
76
77         bool status = true;
78         item.name = luaL_checkstring(L, 2);
79         if (item.name.empty() || item.empty()) {
80                 item.clear();
81                 status = false;
82         }
83
84         lua_pushboolean(L, status);
85         return 1;
86 }
87
88 // get_count(self) -> number
89 int LuaItemStack::l_get_count(lua_State *L)
90 {
91         NO_MAP_LOCK_REQUIRED;
92         LuaItemStack *o = checkobject(L, 1);
93         ItemStack &item = o->m_stack;
94         lua_pushinteger(L, item.count);
95         return 1;
96 }
97
98 // set_count(self, number)
99 int LuaItemStack::l_set_count(lua_State *L)
100 {
101         NO_MAP_LOCK_REQUIRED;
102         LuaItemStack *o = checkobject(L, 1);
103         ItemStack &item = o->m_stack;
104
105         bool status;
106         lua_Integer count = luaL_checkinteger(L, 2);
107         if (count > 0 && count <= 65535) {
108                 item.count = count;
109                 status = true;
110         } else {
111                 item.clear();
112                 status = false;
113         }
114
115         lua_pushboolean(L, status);
116         return 1;
117 }
118
119 // get_wear(self) -> number
120 int LuaItemStack::l_get_wear(lua_State *L)
121 {
122         NO_MAP_LOCK_REQUIRED;
123         LuaItemStack *o = checkobject(L, 1);
124         ItemStack &item = o->m_stack;
125         lua_pushinteger(L, item.wear);
126         return 1;
127 }
128
129 // set_wear(self, number)
130 int LuaItemStack::l_set_wear(lua_State *L)
131 {
132         NO_MAP_LOCK_REQUIRED;
133         LuaItemStack *o = checkobject(L, 1);
134         ItemStack &item = o->m_stack;
135
136         bool status;
137         lua_Integer wear = luaL_checkinteger(L, 2);
138         if (wear <= 65535) {
139                 item.wear = wear;
140                 status = true;
141         } else {
142                 item.clear();
143                 status = false;
144         }
145
146         lua_pushboolean(L, status);
147         return 1;
148 }
149
150 // get_meta(self) -> string
151 int LuaItemStack::l_get_meta(lua_State *L)
152 {
153         NO_MAP_LOCK_REQUIRED;
154         LuaItemStack *o = checkobject(L, 1);
155         ItemStackMetaRef::create(L, &o->m_stack);
156         return 1;
157 }
158
159 // DEPRECATED
160 // get_metadata(self) -> string
161 int LuaItemStack::l_get_metadata(lua_State *L)
162 {
163         NO_MAP_LOCK_REQUIRED;
164         LuaItemStack *o = checkobject(L, 1);
165         ItemStack &item = o->m_stack;
166         const std::string &value = item.metadata.getString("");
167         lua_pushlstring(L, value.c_str(), value.size());
168         return 1;
169 }
170
171 // DEPRECATED
172 // set_metadata(self, string)
173 int LuaItemStack::l_set_metadata(lua_State *L)
174 {
175         NO_MAP_LOCK_REQUIRED;
176         LuaItemStack *o = checkobject(L, 1);
177         ItemStack &item = o->m_stack;
178
179         size_t len = 0;
180         const char *ptr = luaL_checklstring(L, 2, &len);
181         item.metadata.setString("", std::string(ptr, len));
182
183         lua_pushboolean(L, true);
184         return 1;
185 }
186
187 // get_description(self)
188 int LuaItemStack::l_get_description(lua_State *L)
189 {
190         NO_MAP_LOCK_REQUIRED;
191         LuaItemStack *o = checkobject(L, 1);
192         std::string desc = o->m_stack.getDescription(getGameDef(L)->idef());
193         lua_pushstring(L, desc.c_str());
194         return 1;
195 }
196
197 // get_short_description(self)
198 int LuaItemStack::l_get_short_description(lua_State *L)
199 {
200         NO_MAP_LOCK_REQUIRED;
201         LuaItemStack *o = checkobject(L, 1);
202         std::string desc = o->m_stack.getShortDescription(getGameDef(L)->idef());
203         lua_pushstring(L, desc.c_str());
204         return 1;
205 }
206
207 // clear(self) -> true
208 int LuaItemStack::l_clear(lua_State *L)
209 {
210         NO_MAP_LOCK_REQUIRED;
211         LuaItemStack *o = checkobject(L, 1);
212         o->m_stack.clear();
213         lua_pushboolean(L, true);
214         return 1;
215 }
216
217 // replace(self, itemstack or itemstring or table or nil) -> true
218 int LuaItemStack::l_replace(lua_State *L)
219 {
220         NO_MAP_LOCK_REQUIRED;
221         LuaItemStack *o = checkobject(L, 1);
222         o->m_stack = read_item(L, 2, getGameDef(L)->idef());
223         lua_pushboolean(L, true);
224         return 1;
225 }
226
227 // to_string(self) -> string
228 int LuaItemStack::l_to_string(lua_State *L)
229 {
230         NO_MAP_LOCK_REQUIRED;
231         LuaItemStack *o = checkobject(L, 1);
232         std::string itemstring = o->m_stack.getItemString();
233         lua_pushstring(L, itemstring.c_str());
234         return 1;
235 }
236
237 // to_table(self) -> table or nil
238 int LuaItemStack::l_to_table(lua_State *L)
239 {
240         NO_MAP_LOCK_REQUIRED;
241         LuaItemStack *o = checkobject(L, 1);
242         const ItemStack &item = o->m_stack;
243         if(item.empty())
244         {
245                 lua_pushnil(L);
246         }
247         else
248         {
249                 lua_newtable(L);
250                 lua_pushstring(L, item.name.c_str());
251                 lua_setfield(L, -2, "name");
252                 lua_pushinteger(L, item.count);
253                 lua_setfield(L, -2, "count");
254                 lua_pushinteger(L, item.wear);
255                 lua_setfield(L, -2, "wear");
256
257                 const std::string &metadata_str = item.metadata.getString("");
258                 lua_pushlstring(L, metadata_str.c_str(), metadata_str.size());
259                 lua_setfield(L, -2, "metadata");
260
261                 lua_newtable(L);
262                 const StringMap &fields = item.metadata.getStrings();
263                 for (const auto &field : fields) {
264                         const std::string &name = field.first;
265                         if (name.empty())
266                                 continue;
267                         const std::string &value = field.second;
268                         lua_pushlstring(L, name.c_str(), name.size());
269                         lua_pushlstring(L, value.c_str(), value.size());
270                         lua_settable(L, -3);
271                 }
272                 lua_setfield(L, -2, "meta");
273         }
274         return 1;
275 }
276
277 // get_stack_max(self) -> number
278 int LuaItemStack::l_get_stack_max(lua_State *L)
279 {
280         NO_MAP_LOCK_REQUIRED;
281         LuaItemStack *o = checkobject(L, 1);
282         ItemStack &item = o->m_stack;
283         lua_pushinteger(L, item.getStackMax(getGameDef(L)->idef()));
284         return 1;
285 }
286
287 // get_free_space(self) -> number
288 int LuaItemStack::l_get_free_space(lua_State *L)
289 {
290         NO_MAP_LOCK_REQUIRED;
291         LuaItemStack *o = checkobject(L, 1);
292         ItemStack &item = o->m_stack;
293         lua_pushinteger(L, item.freeSpace(getGameDef(L)->idef()));
294         return 1;
295 }
296
297 // is_known(self) -> true/false
298 // Checks if the item is defined.
299 int LuaItemStack::l_is_known(lua_State *L)
300 {
301         NO_MAP_LOCK_REQUIRED;
302         LuaItemStack *o = checkobject(L, 1);
303         ItemStack &item = o->m_stack;
304         bool is_known = item.isKnown(getGameDef(L)->idef());
305         lua_pushboolean(L, is_known);
306         return 1;
307 }
308
309 // get_definition(self) -> table
310 // Returns the item definition table from registered_items,
311 // or a fallback one (name="unknown")
312 int LuaItemStack::l_get_definition(lua_State *L)
313 {
314         NO_MAP_LOCK_REQUIRED;
315         LuaItemStack *o = checkobject(L, 1);
316         ItemStack &item = o->m_stack;
317
318         // Get registered_items[name]
319         lua_getglobal(L, "core");
320         lua_getfield(L, -1, "registered_items");
321         luaL_checktype(L, -1, LUA_TTABLE);
322         lua_getfield(L, -1, item.name.c_str());
323         if(lua_isnil(L, -1))
324         {
325                 lua_pop(L, 1);
326                 lua_getfield(L, -1, "unknown");
327         }
328         return 1;
329 }
330
331 // get_tool_capabilities(self) -> table
332 // Returns the effective tool digging properties.
333 // Returns those of the hand ("") if this item has none associated.
334 int LuaItemStack::l_get_tool_capabilities(lua_State *L)
335 {
336         NO_MAP_LOCK_REQUIRED;
337         LuaItemStack *o = checkobject(L, 1);
338         ItemStack &item = o->m_stack;
339         const ToolCapabilities &prop =
340                 item.getToolCapabilities(getGameDef(L)->idef());
341         push_tool_capabilities(L, prop);
342         return 1;
343 }
344
345 // add_wear(self, amount) -> true/false
346 // The range for "amount" is [0,65536]. Wear is only added if the item
347 // is a tool. Adding wear might destroy the item.
348 // Returns true if the item is (or was) a tool.
349 int LuaItemStack::l_add_wear(lua_State *L)
350 {
351         NO_MAP_LOCK_REQUIRED;
352         LuaItemStack *o = checkobject(L, 1);
353         ItemStack &item = o->m_stack;
354         int amount = lua_tointeger(L, 2);
355         bool result = item.addWear(amount, getGameDef(L)->idef());
356         lua_pushboolean(L, result);
357         return 1;
358 }
359
360 // add_wear_by_uses(self, max_uses) -> true/false
361 // The range for "max_uses" is [0,65536].
362 // Adds wear to the item in such a way that, if
363 // only this function is called to add wear, the item
364 // will be destroyed exactly after `max_uses` times of calling it.
365 // No-op if `max_uses` is 0 or item is not a tool.
366 // Returns true if the item is (or was) a tool.
367 int LuaItemStack::l_add_wear_by_uses(lua_State *L)
368 {
369         NO_MAP_LOCK_REQUIRED;
370         LuaItemStack *o = checkobject(L, 1);
371         ItemStack &item = o->m_stack;
372         u32 max_uses = readParam<int>(L, 2);
373         u32 add_wear = calculateResultWear(max_uses, item.wear);
374         bool result = item.addWear(add_wear, getGameDef(L)->idef());
375         lua_pushboolean(L, result);
376         return 1;
377 }
378
379 // add_item(self, itemstack or itemstring or table or nil) -> itemstack
380 // Returns leftover item stack
381 int LuaItemStack::l_add_item(lua_State *L)
382 {
383         NO_MAP_LOCK_REQUIRED;
384         LuaItemStack *o = checkobject(L, 1);
385         ItemStack &item = o->m_stack;
386         ItemStack newitem = read_item(L, -1, getGameDef(L)->idef());
387         ItemStack leftover = item.addItem(newitem, getGameDef(L)->idef());
388         create(L, leftover);
389         return 1;
390 }
391
392 // item_fits(self, itemstack or itemstring or table or nil) -> true/false, itemstack
393 // First return value is true iff the new item fits fully into the stack
394 // Second return value is the would-be-left-over item stack
395 int LuaItemStack::l_item_fits(lua_State *L)
396 {
397         NO_MAP_LOCK_REQUIRED;
398         LuaItemStack *o = checkobject(L, 1);
399         ItemStack &item = o->m_stack;
400         ItemStack newitem = read_item(L, 2, getGameDef(L)->idef());
401         ItemStack restitem;
402         bool fits = item.itemFits(newitem, &restitem, getGameDef(L)->idef());
403         lua_pushboolean(L, fits);  // first return value
404         create(L, restitem);       // second return value
405         return 2;
406 }
407
408 // take_item(self, takecount=1) -> itemstack
409 int LuaItemStack::l_take_item(lua_State *L)
410 {
411         NO_MAP_LOCK_REQUIRED;
412         LuaItemStack *o = checkobject(L, 1);
413         ItemStack &item = o->m_stack;
414         u32 takecount = 1;
415         if(!lua_isnone(L, 2))
416                 takecount = luaL_checkinteger(L, 2);
417         ItemStack taken = item.takeItem(takecount);
418         create(L, taken);
419         return 1;
420 }
421
422 // peek_item(self, peekcount=1) -> itemstack
423 int LuaItemStack::l_peek_item(lua_State *L)
424 {
425         NO_MAP_LOCK_REQUIRED;
426         LuaItemStack *o = checkobject(L, 1);
427         ItemStack &item = o->m_stack;
428         u32 peekcount = 1;
429         if(!lua_isnone(L, 2))
430                 peekcount = lua_tointeger(L, 2);
431         ItemStack peekaboo = item.peekItem(peekcount);
432         create(L, peekaboo);
433         return 1;
434 }
435
436 LuaItemStack::LuaItemStack(const ItemStack &item):
437         m_stack(item)
438 {
439 }
440
441 const ItemStack& LuaItemStack::getItem() const
442 {
443         return m_stack;
444 }
445 ItemStack& LuaItemStack::getItem()
446 {
447         return m_stack;
448 }
449
450 // LuaItemStack(itemstack or itemstring or table or nil)
451 // Creates an LuaItemStack and leaves it on top of stack
452 int LuaItemStack::create_object(lua_State *L)
453 {
454         NO_MAP_LOCK_REQUIRED;
455         ItemStack item;
456         if (!lua_isnone(L, 1))
457                 item = read_item(L, 1, getGameDef(L)->idef());
458         LuaItemStack *o = new LuaItemStack(item);
459         *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
460         luaL_getmetatable(L, className);
461         lua_setmetatable(L, -2);
462         return 1;
463 }
464
465 // Not callable from Lua
466 int LuaItemStack::create(lua_State *L, const ItemStack &item)
467 {
468         NO_MAP_LOCK_REQUIRED;
469         LuaItemStack *o = new LuaItemStack(item);
470         *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
471         luaL_getmetatable(L, className);
472         lua_setmetatable(L, -2);
473         return 1;
474 }
475
476 LuaItemStack *LuaItemStack::checkobject(lua_State *L, int narg)
477 {
478         return *(LuaItemStack **)luaL_checkudata(L, narg, className);
479 }
480
481 void *LuaItemStack::packIn(lua_State *L, int idx)
482 {
483         LuaItemStack *o = checkobject(L, idx);
484         return new ItemStack(o->getItem());
485 }
486
487 void LuaItemStack::packOut(lua_State *L, void *ptr)
488 {
489         ItemStack *stack = reinterpret_cast<ItemStack*>(ptr);
490         if (L)
491                 create(L, *stack);
492         delete stack;
493 }
494
495 void LuaItemStack::Register(lua_State *L)
496 {
497         lua_newtable(L);
498         int methodtable = lua_gettop(L);
499         luaL_newmetatable(L, className);
500         int metatable = lua_gettop(L);
501
502         // hide metatable from Lua getmetatable()
503         lua_pushliteral(L, "__metatable");
504         lua_pushvalue(L, methodtable);
505         lua_settable(L, metatable);
506
507         lua_pushliteral(L, "__index");
508         lua_pushvalue(L, methodtable);
509         lua_settable(L, metatable);
510
511         lua_pushliteral(L, "__gc");
512         lua_pushcfunction(L, gc_object);
513         lua_settable(L, metatable);
514
515         lua_pushliteral(L, "__tostring");
516         lua_pushcfunction(L, mt_tostring);
517         lua_settable(L, metatable);
518
519         lua_pop(L, 1);  // drop metatable
520
521         luaL_register(L, nullptr, methods);  // fill methodtable
522         lua_pop(L, 1);  // drop methodtable
523
524         // Can be created from Lua (ItemStack(itemstack or itemstring or table or nil))
525         lua_register(L, className, create_object);
526
527         script_register_packer(L, className, packIn, packOut);
528 }
529
530 const char LuaItemStack::className[] = "ItemStack";
531 const luaL_Reg LuaItemStack::methods[] = {
532         luamethod(LuaItemStack, is_empty),
533         luamethod(LuaItemStack, get_name),
534         luamethod(LuaItemStack, set_name),
535         luamethod(LuaItemStack, get_count),
536         luamethod(LuaItemStack, set_count),
537         luamethod(LuaItemStack, get_wear),
538         luamethod(LuaItemStack, set_wear),
539         luamethod(LuaItemStack, get_meta),
540         luamethod(LuaItemStack, get_metadata),
541         luamethod(LuaItemStack, set_metadata),
542         luamethod(LuaItemStack, get_description),
543         luamethod(LuaItemStack, get_short_description),
544         luamethod(LuaItemStack, clear),
545         luamethod(LuaItemStack, replace),
546         luamethod(LuaItemStack, to_string),
547         luamethod(LuaItemStack, to_table),
548         luamethod(LuaItemStack, get_stack_max),
549         luamethod(LuaItemStack, get_free_space),
550         luamethod(LuaItemStack, is_known),
551         luamethod(LuaItemStack, get_definition),
552         luamethod(LuaItemStack, get_tool_capabilities),
553         luamethod(LuaItemStack, add_wear),
554         luamethod(LuaItemStack, add_wear_by_uses),
555         luamethod(LuaItemStack, add_item),
556         luamethod(LuaItemStack, item_fits),
557         luamethod(LuaItemStack, take_item),
558         luamethod(LuaItemStack, peek_item),
559         {0,0}
560 };
561
562 /*
563         ItemDefinition
564 */
565
566 // register_item_raw({lots of stuff})
567 int ModApiItemMod::l_register_item_raw(lua_State *L)
568 {
569         NO_MAP_LOCK_REQUIRED;
570         luaL_checktype(L, 1, LUA_TTABLE);
571         int table = 1;
572
573         // Get the writable item and node definition managers from the server
574         IWritableItemDefManager *idef =
575                         getServer(L)->getWritableItemDefManager();
576         NodeDefManager *ndef =
577                         getServer(L)->getWritableNodeDefManager();
578
579         // Check if name is defined
580         std::string name;
581         lua_getfield(L, table, "name");
582         if(lua_isstring(L, -1)){
583                 name = readParam<std::string>(L, -1);
584         } else {
585                 throw LuaError("register_item_raw: name is not defined or not a string");
586         }
587
588         // Check if on_use is defined
589
590         ItemDefinition def;
591         // Set a distinctive default value to check if this is set
592         def.node_placement_prediction = "__default";
593
594         // Read the item definition
595         read_item_definition(L, table, def, def);
596
597         // Default to having client-side placement prediction for nodes
598         // ("" in item definition sets it off)
599         if(def.node_placement_prediction == "__default"){
600                 if(def.type == ITEM_NODE)
601                         def.node_placement_prediction = name;
602                 else
603                         def.node_placement_prediction = "";
604         }
605
606         // Register item definition
607         idef->registerItem(def);
608
609         // Read the node definition (content features) and register it
610         if (def.type == ITEM_NODE) {
611                 ContentFeatures f;
612                 read_content_features(L, f, table);
613                 // when a mod reregisters ignore, only texture changes and such should
614                 // be done
615                 if (f.name == "ignore")
616                         return 0;
617                 // This would break everything
618                 if (f.name.empty())
619                         throw LuaError("Cannot register node with empty name");
620
621                 content_t id = ndef->set(f.name, f);
622
623                 if (id > MAX_REGISTERED_CONTENT) {
624                         throw LuaError("Number of registerable nodes ("
625                                         + itos(MAX_REGISTERED_CONTENT+1)
626                                         + ") exceeded (" + name + ")");
627                 }
628         }
629
630         return 0; /* number of results */
631 }
632
633 // unregister_item(name)
634 int ModApiItemMod::l_unregister_item_raw(lua_State *L)
635 {
636         NO_MAP_LOCK_REQUIRED;
637         std::string name = luaL_checkstring(L, 1);
638
639         IWritableItemDefManager *idef =
640                         getServer(L)->getWritableItemDefManager();
641
642         // Unregister the node
643         if (idef->get(name).type == ITEM_NODE) {
644                 NodeDefManager *ndef =
645                         getServer(L)->getWritableNodeDefManager();
646                 ndef->removeNode(name);
647         }
648
649         idef->unregisterItem(name);
650
651         return 0; /* number of results */
652 }
653
654 // register_alias_raw(name, convert_to_name)
655 int ModApiItemMod::l_register_alias_raw(lua_State *L)
656 {
657         NO_MAP_LOCK_REQUIRED;
658         std::string name = luaL_checkstring(L, 1);
659         std::string convert_to = luaL_checkstring(L, 2);
660
661         // Get the writable item definition manager from the server
662         IWritableItemDefManager *idef =
663                         getServer(L)->getWritableItemDefManager();
664
665         idef->registerAlias(name, convert_to);
666
667         return 0; /* number of results */
668 }
669
670 // get_content_id(name)
671 int ModApiItemMod::l_get_content_id(lua_State *L)
672 {
673         NO_MAP_LOCK_REQUIRED;
674         std::string name = luaL_checkstring(L, 1);
675
676         const IItemDefManager *idef = getGameDef(L)->idef();
677         const NodeDefManager *ndef = getGameDef(L)->ndef();
678
679         // If this is called at mod load time, NodeDefManager isn't aware of
680         // aliases yet, so we need to handle them manually
681         std::string alias_name = idef->getAlias(name);
682
683         content_t content_id;
684         if (alias_name != name) {
685                 if (!ndef->getId(alias_name, content_id))
686                         throw LuaError("Unknown node: " + alias_name +
687                                         " (from alias " + name + ")");
688         } else if (!ndef->getId(name, content_id)) {
689                 throw LuaError("Unknown node: " + name);
690         }
691
692         lua_pushinteger(L, content_id);
693         return 1; /* number of results */
694 }
695
696 // get_name_from_content_id(name)
697 int ModApiItemMod::l_get_name_from_content_id(lua_State *L)
698 {
699         NO_MAP_LOCK_REQUIRED;
700         content_t c = luaL_checkint(L, 1);
701
702         const NodeDefManager *ndef = getGameDef(L)->ndef();
703         const char *name = ndef->get(c).name.c_str();
704
705         lua_pushstring(L, name);
706         return 1; /* number of results */
707 }
708
709 void ModApiItemMod::Initialize(lua_State *L, int top)
710 {
711         API_FCT(register_item_raw);
712         API_FCT(unregister_item_raw);
713         API_FCT(register_alias_raw);
714         API_FCT(get_content_id);
715         API_FCT(get_name_from_content_id);
716 }
717
718 void ModApiItemMod::InitializeAsync(lua_State *L, int top)
719 {
720         // all read-only functions
721         API_FCT(get_content_id);
722         API_FCT(get_name_from_content_id);
723 }