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