3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
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.
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.
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.
20 #include "lua_api/l_item.h"
21 #include "common/c_converter.h"
22 #include "common/c_content.h"
23 #include "cpp_api/scriptapi.h"
25 #include "common/c_internal.h"
28 int LuaItemStack::gc_object(lua_State *L)
30 LuaItemStack *o = *(LuaItemStack **)(lua_touserdata(L, 1));
35 // is_empty(self) -> true/false
36 int LuaItemStack::l_is_empty(lua_State *L)
39 LuaItemStack *o = checkobject(L, 1);
40 ItemStack &item = o->m_stack;
41 lua_pushboolean(L, item.empty());
45 // get_name(self) -> string
46 int LuaItemStack::l_get_name(lua_State *L)
49 LuaItemStack *o = checkobject(L, 1);
50 ItemStack &item = o->m_stack;
51 lua_pushstring(L, item.name.c_str());
55 // get_count(self) -> number
56 int LuaItemStack::l_get_count(lua_State *L)
59 LuaItemStack *o = checkobject(L, 1);
60 ItemStack &item = o->m_stack;
61 lua_pushinteger(L, item.count);
65 // get_wear(self) -> number
66 int LuaItemStack::l_get_wear(lua_State *L)
69 LuaItemStack *o = checkobject(L, 1);
70 ItemStack &item = o->m_stack;
71 lua_pushinteger(L, item.wear);
75 // get_metadata(self) -> string
76 int LuaItemStack::l_get_metadata(lua_State *L)
79 LuaItemStack *o = checkobject(L, 1);
80 ItemStack &item = o->m_stack;
81 lua_pushlstring(L, item.metadata.c_str(), item.metadata.size());
85 // clear(self) -> true
86 int LuaItemStack::l_clear(lua_State *L)
89 LuaItemStack *o = checkobject(L, 1);
91 lua_pushboolean(L, true);
95 // replace(self, itemstack or itemstring or table or nil) -> true
96 int LuaItemStack::l_replace(lua_State *L)
99 LuaItemStack *o = checkobject(L, 1);
100 o->m_stack = read_item(L,2,STACK_TO_SERVER(L));
101 lua_pushboolean(L, true);
105 // to_string(self) -> string
106 int LuaItemStack::l_to_string(lua_State *L)
108 NO_MAP_LOCK_REQUIRED;
109 LuaItemStack *o = checkobject(L, 1);
110 std::string itemstring = o->m_stack.getItemString();
111 lua_pushstring(L, itemstring.c_str());
115 // to_table(self) -> table or nil
116 int LuaItemStack::l_to_table(lua_State *L)
118 NO_MAP_LOCK_REQUIRED;
119 LuaItemStack *o = checkobject(L, 1);
120 const ItemStack &item = o->m_stack;
128 lua_pushstring(L, item.name.c_str());
129 lua_setfield(L, -2, "name");
130 lua_pushinteger(L, item.count);
131 lua_setfield(L, -2, "count");
132 lua_pushinteger(L, item.wear);
133 lua_setfield(L, -2, "wear");
134 lua_pushlstring(L, item.metadata.c_str(), item.metadata.size());
135 lua_setfield(L, -2, "metadata");
140 // get_stack_max(self) -> number
141 int LuaItemStack::l_get_stack_max(lua_State *L)
143 NO_MAP_LOCK_REQUIRED;
144 LuaItemStack *o = checkobject(L, 1);
145 ItemStack &item = o->m_stack;
146 lua_pushinteger(L, item.getStackMax(STACK_TO_SERVER(L)->idef()));
150 // get_free_space(self) -> number
151 int LuaItemStack::l_get_free_space(lua_State *L)
153 NO_MAP_LOCK_REQUIRED;
154 LuaItemStack *o = checkobject(L, 1);
155 ItemStack &item = o->m_stack;
156 lua_pushinteger(L, item.freeSpace(STACK_TO_SERVER(L)->idef()));
160 // is_known(self) -> true/false
161 // Checks if the item is defined.
162 int LuaItemStack::l_is_known(lua_State *L)
164 NO_MAP_LOCK_REQUIRED;
165 LuaItemStack *o = checkobject(L, 1);
166 ItemStack &item = o->m_stack;
167 bool is_known = item.isKnown(STACK_TO_SERVER(L)->idef());
168 lua_pushboolean(L, is_known);
172 // get_definition(self) -> table
173 // Returns the item definition table from minetest.registered_items,
174 // or a fallback one (name="unknown")
175 int LuaItemStack::l_get_definition(lua_State *L)
177 NO_MAP_LOCK_REQUIRED;
178 LuaItemStack *o = checkobject(L, 1);
179 ItemStack &item = o->m_stack;
181 // Get minetest.registered_items[name]
182 lua_getglobal(L, "minetest");
183 lua_getfield(L, -1, "registered_items");
184 luaL_checktype(L, -1, LUA_TTABLE);
185 lua_getfield(L, -1, item.name.c_str());
189 lua_getfield(L, -1, "unknown");
194 // get_tool_capabilities(self) -> table
195 // Returns the effective tool digging properties.
196 // Returns those of the hand ("") if this item has none associated.
197 int LuaItemStack::l_get_tool_capabilities(lua_State *L)
199 NO_MAP_LOCK_REQUIRED;
200 LuaItemStack *o = checkobject(L, 1);
201 ItemStack &item = o->m_stack;
202 const ToolCapabilities &prop =
203 item.getToolCapabilities(STACK_TO_SERVER(L)->idef());
204 push_tool_capabilities(L, prop);
208 // add_wear(self, amount) -> true/false
209 // The range for "amount" is [0,65535]. Wear is only added if the item
210 // is a tool. Adding wear might destroy the item.
211 // Returns true if the item is (or was) a tool.
212 int LuaItemStack::l_add_wear(lua_State *L)
214 NO_MAP_LOCK_REQUIRED;
215 LuaItemStack *o = checkobject(L, 1);
216 ItemStack &item = o->m_stack;
217 int amount = lua_tointeger(L, 2);
218 bool result = item.addWear(amount, STACK_TO_SERVER(L)->idef());
219 lua_pushboolean(L, result);
223 // add_item(self, itemstack or itemstring or table or nil) -> itemstack
224 // Returns leftover item stack
225 int LuaItemStack::l_add_item(lua_State *L)
227 NO_MAP_LOCK_REQUIRED;
228 LuaItemStack *o = checkobject(L, 1);
229 ItemStack &item = o->m_stack;
230 ItemStack newitem = read_item(L,-1, STACK_TO_SERVER(L));
231 ItemStack leftover = item.addItem(newitem, STACK_TO_SERVER(L)->idef());
236 // item_fits(self, itemstack or itemstring or table or nil) -> true/false, itemstack
237 // First return value is true iff the new item fits fully into the stack
238 // Second return value is the would-be-left-over item stack
239 int LuaItemStack::l_item_fits(lua_State *L)
241 NO_MAP_LOCK_REQUIRED;
242 LuaItemStack *o = checkobject(L, 1);
243 ItemStack &item = o->m_stack;
244 ItemStack newitem = read_item(L, 2 ,STACK_TO_SERVER(L));
246 bool fits = item.itemFits(newitem, &restitem, STACK_TO_SERVER(L)->idef());
247 lua_pushboolean(L, fits); // first return value
248 create(L, restitem); // second return value
252 // take_item(self, takecount=1) -> itemstack
253 int LuaItemStack::l_take_item(lua_State *L)
255 NO_MAP_LOCK_REQUIRED;
256 LuaItemStack *o = checkobject(L, 1);
257 ItemStack &item = o->m_stack;
259 if(!lua_isnone(L, 2))
260 takecount = luaL_checkinteger(L, 2);
261 ItemStack taken = item.takeItem(takecount);
266 // peek_item(self, peekcount=1) -> itemstack
267 int LuaItemStack::l_peek_item(lua_State *L)
269 NO_MAP_LOCK_REQUIRED;
270 LuaItemStack *o = checkobject(L, 1);
271 ItemStack &item = o->m_stack;
273 if(!lua_isnone(L, 2))
274 peekcount = lua_tointeger(L, 2);
275 ItemStack peekaboo = item.peekItem(peekcount);
280 LuaItemStack::LuaItemStack(const ItemStack &item):
285 LuaItemStack::~LuaItemStack()
289 const ItemStack& LuaItemStack::getItem() const
293 ItemStack& LuaItemStack::getItem()
298 // LuaItemStack(itemstack or itemstring or table or nil)
299 // Creates an LuaItemStack and leaves it on top of stack
300 int LuaItemStack::create_object(lua_State *L)
302 NO_MAP_LOCK_REQUIRED;
303 ItemStack item = read_item(L,1,STACK_TO_SERVER(L));
304 LuaItemStack *o = new LuaItemStack(item);
305 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
306 luaL_getmetatable(L, className);
307 lua_setmetatable(L, -2);
310 // Not callable from Lua
311 int LuaItemStack::create(lua_State *L, const ItemStack &item)
313 NO_MAP_LOCK_REQUIRED;
314 LuaItemStack *o = new LuaItemStack(item);
315 *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
316 luaL_getmetatable(L, className);
317 lua_setmetatable(L, -2);
321 LuaItemStack* LuaItemStack::checkobject(lua_State *L, int narg)
323 luaL_checktype(L, narg, LUA_TUSERDATA);
324 void *ud = luaL_checkudata(L, narg, className);
325 if(!ud) luaL_typerror(L, narg, className);
326 return *(LuaItemStack**)ud; // unbox pointer
329 void LuaItemStack::Register(lua_State *L)
332 int methodtable = lua_gettop(L);
333 luaL_newmetatable(L, className);
334 int metatable = lua_gettop(L);
336 lua_pushliteral(L, "__metatable");
337 lua_pushvalue(L, methodtable);
338 lua_settable(L, metatable); // hide metatable from Lua getmetatable()
340 lua_pushliteral(L, "__index");
341 lua_pushvalue(L, methodtable);
342 lua_settable(L, metatable);
344 lua_pushliteral(L, "__gc");
345 lua_pushcfunction(L, gc_object);
346 lua_settable(L, metatable);
348 lua_pop(L, 1); // drop metatable
350 luaL_openlib(L, 0, methods, 0); // fill methodtable
351 lua_pop(L, 1); // drop methodtable
353 // Can be created from Lua (LuaItemStack(itemstack or itemstring or table or nil))
354 lua_register(L, className, create_object);
357 const char LuaItemStack::className[] = "ItemStack";
358 const luaL_reg LuaItemStack::methods[] = {
359 luamethod(LuaItemStack, is_empty),
360 luamethod(LuaItemStack, get_name),
361 luamethod(LuaItemStack, get_count),
362 luamethod(LuaItemStack, get_wear),
363 luamethod(LuaItemStack, get_metadata),
364 luamethod(LuaItemStack, clear),
365 luamethod(LuaItemStack, replace),
366 luamethod(LuaItemStack, to_string),
367 luamethod(LuaItemStack, to_table),
368 luamethod(LuaItemStack, get_stack_max),
369 luamethod(LuaItemStack, get_free_space),
370 luamethod(LuaItemStack, is_known),
371 luamethod(LuaItemStack, get_definition),
372 luamethod(LuaItemStack, get_tool_capabilities),
373 luamethod(LuaItemStack, add_wear),
374 luamethod(LuaItemStack, add_item),
375 luamethod(LuaItemStack, item_fits),
376 luamethod(LuaItemStack, take_item),
377 luamethod(LuaItemStack, peek_item),
381 ModApiItemMod::ModApiItemMod() {
388 // register_item_raw({lots of stuff})
389 int ModApiItemMod::l_register_item_raw(lua_State *L)
391 NO_MAP_LOCK_REQUIRED;
392 luaL_checktype(L, 1, LUA_TTABLE);
395 ScriptApi* scriptIface = get_scriptapi(L);
397 // Get the writable item and node definition managers from the server
398 IWritableItemDefManager *idef =
399 scriptIface->getServer()->getWritableItemDefManager();
400 IWritableNodeDefManager *ndef =
401 scriptIface->getServer()->getWritableNodeDefManager();
403 // Check if name is defined
405 lua_getfield(L, table, "name");
406 if(lua_isstring(L, -1)){
407 name = lua_tostring(L, -1);
408 verbosestream<<"register_item_raw: "<<name<<std::endl;
410 throw LuaError(L, "register_item_raw: name is not defined or not a string");
413 // Check if on_use is defined
416 // Set a distinctive default value to check if this is set
417 def.node_placement_prediction = "__default";
419 // Read the item definition
420 def = read_item_definition(L, table, def);
422 // Default to having client-side placement prediction for nodes
423 // ("" in item definition sets it off)
424 if(def.node_placement_prediction == "__default"){
425 if(def.type == ITEM_NODE)
426 def.node_placement_prediction = name;
428 def.node_placement_prediction = "";
431 // Register item definition
432 idef->registerItem(def);
434 // Read the node definition (content features) and register it
435 if(def.type == ITEM_NODE){
436 ContentFeatures f = read_content_features(L, table);
437 content_t id = ndef->set(f.name, f);
439 if(id > MAX_REGISTERED_CONTENT){
440 throw LuaError(L, "Number of registerable nodes ("
441 + itos(MAX_REGISTERED_CONTENT+1)
442 + ") exceeded (" + name + ")");
446 return 0; /* number of results */
449 // register_alias_raw(name, convert_to_name)
450 int ModApiItemMod::l_register_alias_raw(lua_State *L)
452 NO_MAP_LOCK_REQUIRED;
453 std::string name = luaL_checkstring(L, 1);
454 std::string convert_to = luaL_checkstring(L, 2);
456 // Get the writable item definition manager from the server
457 IWritableItemDefManager *idef =
458 STACK_TO_SERVER(L)->getWritableItemDefManager();
460 idef->registerAlias(name, convert_to);
462 return 0; /* number of results */
465 // get_content_id(name)
466 int ModApiItemMod::l_get_content_id(lua_State *L)
468 NO_MAP_LOCK_REQUIRED;
469 std::string name = luaL_checkstring(L, 1);
471 INodeDefManager *ndef = STACK_TO_SERVER(L)->getNodeDefManager();
472 content_t c = ndef->getId(name);
474 lua_pushinteger(L, c);
475 return 1; /* number of results */
478 // get_name_from_content_id(name)
479 int ModApiItemMod::l_get_name_from_content_id(lua_State *L)
481 NO_MAP_LOCK_REQUIRED;
482 content_t c = luaL_checkint(L, 1);
484 INodeDefManager *ndef = STACK_TO_SERVER(L)->getNodeDefManager();
485 const char *name = ndef->get(c).name.c_str();
487 lua_pushstring(L, name);
488 return 1; /* number of results */
491 bool ModApiItemMod::Initialize(lua_State *L,int top) {
495 retval &= API_FCT(register_item_raw);
496 retval &= API_FCT(register_alias_raw);
497 retval &= API_FCT(get_content_id);
498 retval &= API_FCT(get_name_from_content_id);
500 LuaItemStack::Register(L);
505 ModApiItemMod modapi_item_prototyp;