summaryrefslogtreecommitdiff
path: root/src/scriptapi_item.cpp
diff options
context:
space:
mode:
authorsapier <Sapier at GMX dot net>2013-05-25 00:51:02 +0200
committerKahrl <kahrl@gmx.net>2013-05-25 00:51:02 +0200
commitab433775777c4f5055bcf4d2a1cffc506c4f9961 (patch)
tree9f80c74c95cbb1efa15c0c36df8d5e35235e5554 /src/scriptapi_item.cpp
parent865f380c91ced850d1a499c91aa2ab5489624802 (diff)
downloadminetest-ab433775777c4f5055bcf4d2a1cffc506c4f9961.tar.gz
minetest-ab433775777c4f5055bcf4d2a1cffc506c4f9961.tar.bz2
minetest-ab433775777c4f5055bcf4d2a1cffc506c4f9961.zip
Move scriptapi to separate folder (by sapier)
On the lua side, notably minetest.env:<function>(<args>) should now be replaced by minetest.<function>(<args>). The old way is and will stay supported for a long time. Also: Update and clean up lua_api.txt (by celeron55) Move EnvRef to lua and remove add_rat and add_firefly (by kahrl) Add separate src/util/CMakeLists.txt, other minor fixes (by kahrl)
Diffstat (limited to 'src/scriptapi_item.cpp')
-rw-r--r--src/scriptapi_item.cpp718
1 files changed, 0 insertions, 718 deletions
diff --git a/src/scriptapi_item.cpp b/src/scriptapi_item.cpp
deleted file mode 100644
index b266d856d..000000000
--- a/src/scriptapi_item.cpp
+++ /dev/null
@@ -1,718 +0,0 @@
-/*
-Minetest
-Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation; either version 2.1 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#include "scriptapi.h"
-#include "server.h"
-#include "script.h"
-#include "tool.h"
-#include "nodedef.h"
-#include "util/pointedthing.h"
-#include "scriptapi_item.h"
-#include "scriptapi_types.h"
-#include "scriptapi_common.h"
-#include "scriptapi_object.h"
-#include "scriptapi_content.h"
-
-
-struct EnumString es_ItemType[] =
-{
- {ITEM_NONE, "none"},
- {ITEM_NODE, "node"},
- {ITEM_CRAFT, "craft"},
- {ITEM_TOOL, "tool"},
- {0, NULL},
-};
-
-
-/*
- ItemDefinition
-*/
-
-ItemDefinition read_item_definition(lua_State *L, int index,
- ItemDefinition default_def)
-{
- if(index < 0)
- index = lua_gettop(L) + 1 + index;
-
- // Read the item definition
- ItemDefinition def = default_def;
-
- def.type = (ItemType)getenumfield(L, index, "type",
- es_ItemType, ITEM_NONE);
- getstringfield(L, index, "name", def.name);
- getstringfield(L, index, "description", def.description);
- getstringfield(L, index, "inventory_image", def.inventory_image);
- getstringfield(L, index, "wield_image", def.wield_image);
-
- lua_getfield(L, index, "wield_scale");
- if(lua_istable(L, -1)){
- def.wield_scale = check_v3f(L, -1);
- }
- lua_pop(L, 1);
-
- def.stack_max = getintfield_default(L, index, "stack_max", def.stack_max);
- if(def.stack_max == 0)
- def.stack_max = 1;
-
- lua_getfield(L, index, "on_use");
- def.usable = lua_isfunction(L, -1);
- lua_pop(L, 1);
-
- getboolfield(L, index, "liquids_pointable", def.liquids_pointable);
-
- warn_if_field_exists(L, index, "tool_digging_properties",
- "deprecated: use tool_capabilities");
-
- lua_getfield(L, index, "tool_capabilities");
- if(lua_istable(L, -1)){
- def.tool_capabilities = new ToolCapabilities(
- read_tool_capabilities(L, -1));
- }
-
- // If name is "" (hand), ensure there are ToolCapabilities
- // because it will be looked up there whenever any other item has
- // no ToolCapabilities
- if(def.name == "" && def.tool_capabilities == NULL){
- def.tool_capabilities = new ToolCapabilities();
- }
-
- lua_getfield(L, index, "groups");
- read_groups(L, -1, def.groups);
- lua_pop(L, 1);
-
- lua_getfield(L, index, "sounds");
- if(lua_istable(L, -1)){
- lua_getfield(L, -1, "place");
- read_soundspec(L, -1, def.sound_place);
- lua_pop(L, 1);
- }
- lua_pop(L, 1);
-
- // Client shall immediately place this node when player places the item.
- // Server will update the precise end result a moment later.
- // "" = no prediction
- getstringfield(L, index, "node_placement_prediction",
- def.node_placement_prediction);
-
- return def;
-}
-
-// register_item_raw({lots of stuff})
-int l_register_item_raw(lua_State *L)
-{
- luaL_checktype(L, 1, LUA_TTABLE);
- int table = 1;
-
- // Get the writable item and node definition managers from the server
- IWritableItemDefManager *idef =
- get_server(L)->getWritableItemDefManager();
- IWritableNodeDefManager *ndef =
- get_server(L)->getWritableNodeDefManager();
-
- // Check if name is defined
- std::string name;
- lua_getfield(L, table, "name");
- if(lua_isstring(L, -1)){
- name = lua_tostring(L, -1);
- verbosestream<<"register_item_raw: "<<name<<std::endl;
- } else {
- throw LuaError(L, "register_item_raw: name is not defined or not a string");
- }
-
- // Check if on_use is defined
-
- ItemDefinition def;
- // Set a distinctive default value to check if this is set
- def.node_placement_prediction = "__default";
-
- // Read the item definition
- def = read_item_definition(L, table, def);
-
- // Default to having client-side placement prediction for nodes
- // ("" in item definition sets it off)
- if(def.node_placement_prediction == "__default"){
- if(def.type == ITEM_NODE)
- def.node_placement_prediction = name;
- else
- def.node_placement_prediction = "";
- }
-
- // Register item definition
- idef->registerItem(def);
-
- // Read the node definition (content features) and register it
- if(def.type == ITEM_NODE)
- {
- ContentFeatures f = read_content_features(L, table);
- ndef->set(f.name, f);
- }
-
- return 0; /* number of results */
-}
-
-// register_alias_raw(name, convert_to_name)
-int l_register_alias_raw(lua_State *L)
-{
- std::string name = luaL_checkstring(L, 1);
- std::string convert_to = luaL_checkstring(L, 2);
-
- // Get the writable item definition manager from the server
- IWritableItemDefManager *idef =
- get_server(L)->getWritableItemDefManager();
-
- idef->registerAlias(name, convert_to);
-
- return 0; /* number of results */
-}
-
-// Retrieves minetest.registered_items[name][callbackname]
-// If that is nil or on error, return false and stack is unchanged
-// If that is a function, returns true and pushes the
-// function onto the stack
-// If minetest.registered_items[name] doesn't exist, minetest.nodedef_default
-// is tried instead so unknown items can still be manipulated to some degree
-bool get_item_callback(lua_State *L,
- const char *name, const char *callbackname)
-{
- lua_getglobal(L, "minetest");
- lua_getfield(L, -1, "registered_items");
- lua_remove(L, -2);
- luaL_checktype(L, -1, LUA_TTABLE);
- lua_getfield(L, -1, name);
- lua_remove(L, -2);
- // Should be a table
- if(lua_type(L, -1) != LUA_TTABLE)
- {
- // Report error and clean up
- errorstream<<"Item \""<<name<<"\" not defined"<<std::endl;
- lua_pop(L, 1);
-
- // Try minetest.nodedef_default instead
- lua_getglobal(L, "minetest");
- lua_getfield(L, -1, "nodedef_default");
- lua_remove(L, -2);
- luaL_checktype(L, -1, LUA_TTABLE);
- }
- lua_getfield(L, -1, callbackname);
- lua_remove(L, -2);
- // Should be a function or nil
- if(lua_type(L, -1) == LUA_TFUNCTION)
- {
- return true;
- }
- else if(lua_isnil(L, -1))
- {
- lua_pop(L, 1);
- return false;
- }
- else
- {
- errorstream<<"Item \""<<name<<"\" callback \""
- <<callbackname<<" is not a function"<<std::endl;
- lua_pop(L, 1);
- return false;
- }
-}
-
-bool scriptapi_item_on_drop(lua_State *L, ItemStack &item,
- ServerActiveObject *dropper, v3f pos)
-{
- realitycheck(L);
- assert(lua_checkstack(L, 20));
- StackUnroller stack_unroller(L);
-
- // Push callback function on stack
- if(!get_item_callback(L, item.name.c_str(), "on_drop"))
- return false;
-
- // Call function
- LuaItemStack::create(L, item);
- objectref_get_or_create(L, dropper);
- pushFloatPos(L, pos);
- if(lua_pcall(L, 3, 1, 0))
- script_error(L, "error: %s", lua_tostring(L, -1));
- if(!lua_isnil(L, -1))
- item = read_item(L, -1);
- return true;
-}
-
-bool scriptapi_item_on_place(lua_State *L, ItemStack &item,
- ServerActiveObject *placer, const PointedThing &pointed)
-{
- realitycheck(L);
- assert(lua_checkstack(L, 20));
- StackUnroller stack_unroller(L);
-
- // Push callback function on stack
- if(!get_item_callback(L, item.name.c_str(), "on_place"))
- return false;
-
- // Call function
- LuaItemStack::create(L, item);
- objectref_get_or_create(L, placer);
- push_pointed_thing(L, pointed);
- if(lua_pcall(L, 3, 1, 0))
- script_error(L, "error: %s", lua_tostring(L, -1));
- if(!lua_isnil(L, -1))
- item = read_item(L, -1);
- return true;
-}
-
-bool scriptapi_item_on_use(lua_State *L, ItemStack &item,
- ServerActiveObject *user, const PointedThing &pointed)
-{
- realitycheck(L);
- assert(lua_checkstack(L, 20));
- StackUnroller stack_unroller(L);
-
- // Push callback function on stack
- if(!get_item_callback(L, item.name.c_str(), "on_use"))
- return false;
-
- // Call function
- LuaItemStack::create(L, item);
- objectref_get_or_create(L, user);
- push_pointed_thing(L, pointed);
- if(lua_pcall(L, 3, 1, 0))
- script_error(L, "error: %s", lua_tostring(L, -1));
- if(!lua_isnil(L, -1))
- item = read_item(L, -1);
- return true;
-}
-
-// garbage collector
-int LuaItemStack::gc_object(lua_State *L)
-{
- LuaItemStack *o = *(LuaItemStack **)(lua_touserdata(L, 1));
- delete o;
- return 0;
-}
-
-// is_empty(self) -> true/false
-int LuaItemStack::l_is_empty(lua_State *L)
-{
- LuaItemStack *o = checkobject(L, 1);
- ItemStack &item = o->m_stack;
- lua_pushboolean(L, item.empty());
- return 1;
-}
-
-// get_name(self) -> string
-int LuaItemStack::l_get_name(lua_State *L)
-{
- LuaItemStack *o = checkobject(L, 1);
- ItemStack &item = o->m_stack;
- lua_pushstring(L, item.name.c_str());
- return 1;
-}
-
-// get_count(self) -> number
-int LuaItemStack::l_get_count(lua_State *L)
-{
- LuaItemStack *o = checkobject(L, 1);
- ItemStack &item = o->m_stack;
- lua_pushinteger(L, item.count);
- return 1;
-}
-
-// get_wear(self) -> number
-int LuaItemStack::l_get_wear(lua_State *L)
-{
- LuaItemStack *o = checkobject(L, 1);
- ItemStack &item = o->m_stack;
- lua_pushinteger(L, item.wear);
- return 1;
-}
-
-// get_metadata(self) -> string
-int LuaItemStack::l_get_metadata(lua_State *L)
-{
- LuaItemStack *o = checkobject(L, 1);
- ItemStack &item = o->m_stack;
- lua_pushlstring(L, item.metadata.c_str(), item.metadata.size());
- return 1;
-}
-
-// clear(self) -> true
-int LuaItemStack::l_clear(lua_State *L)
-{
- LuaItemStack *o = checkobject(L, 1);
- o->m_stack.clear();
- lua_pushboolean(L, true);
- return 1;
-}
-
-// replace(self, itemstack or itemstring or table or nil) -> true
-int LuaItemStack::l_replace(lua_State *L)
-{
- LuaItemStack *o = checkobject(L, 1);
- o->m_stack = read_item(L, 2);
- lua_pushboolean(L, true);
- return 1;
-}
-
-// to_string(self) -> string
-int LuaItemStack::l_to_string(lua_State *L)
-{
- LuaItemStack *o = checkobject(L, 1);
- std::string itemstring = o->m_stack.getItemString();
- lua_pushstring(L, itemstring.c_str());
- return 1;
-}
-
-// to_table(self) -> table or nil
-int LuaItemStack::l_to_table(lua_State *L)
-{
- LuaItemStack *o = checkobject(L, 1);
- const ItemStack &item = o->m_stack;
- if(item.empty())
- {
- lua_pushnil(L);
- }
- else
- {
- lua_newtable(L);
- lua_pushstring(L, item.name.c_str());
- lua_setfield(L, -2, "name");
- lua_pushinteger(L, item.count);
- lua_setfield(L, -2, "count");
- lua_pushinteger(L, item.wear);
- lua_setfield(L, -2, "wear");
- lua_pushlstring(L, item.metadata.c_str(), item.metadata.size());
- lua_setfield(L, -2, "metadata");
- }
- return 1;
-}
-
-// get_stack_max(self) -> number
-int LuaItemStack::l_get_stack_max(lua_State *L)
-{
- LuaItemStack *o = checkobject(L, 1);
- ItemStack &item = o->m_stack;
- lua_pushinteger(L, item.getStackMax(get_server(L)->idef()));
- return 1;
-}
-
-// get_free_space(self) -> number
-int LuaItemStack::l_get_free_space(lua_State *L)
-{
- LuaItemStack *o = checkobject(L, 1);
- ItemStack &item = o->m_stack;
- lua_pushinteger(L, item.freeSpace(get_server(L)->idef()));
- return 1;
-}
-
-// is_known(self) -> true/false
-// Checks if the item is defined.
-int LuaItemStack::l_is_known(lua_State *L)
-{
- LuaItemStack *o = checkobject(L, 1);
- ItemStack &item = o->m_stack;
- bool is_known = item.isKnown(get_server(L)->idef());
- lua_pushboolean(L, is_known);
- return 1;
-}
-
-// get_definition(self) -> table
-// Returns the item definition table from minetest.registered_items,
-// or a fallback one (name="unknown")
-int LuaItemStack::l_get_definition(lua_State *L)
-{
- LuaItemStack *o = checkobject(L, 1);
- ItemStack &item = o->m_stack;
-
- // Get minetest.registered_items[name]
- lua_getglobal(L, "minetest");
- lua_getfield(L, -1, "registered_items");
- luaL_checktype(L, -1, LUA_TTABLE);
- lua_getfield(L, -1, item.name.c_str());
- if(lua_isnil(L, -1))
- {
- lua_pop(L, 1);
- lua_getfield(L, -1, "unknown");
- }
- return 1;
-}
-
-// get_tool_capabilities(self) -> table
-// Returns the effective tool digging properties.
-// Returns those of the hand ("") if this item has none associated.
-int LuaItemStack::l_get_tool_capabilities(lua_State *L)
-{
- LuaItemStack *o = checkobject(L, 1);
- ItemStack &item = o->m_stack;
- const ToolCapabilities &prop =
- item.getToolCapabilities(get_server(L)->idef());
- push_tool_capabilities(L, prop);
- return 1;
-}
-
-// add_wear(self, amount) -> true/false
-// The range for "amount" is [0,65535]. Wear is only added if the item
-// is a tool. Adding wear might destroy the item.
-// Returns true if the item is (or was) a tool.
-int LuaItemStack::l_add_wear(lua_State *L)
-{
- LuaItemStack *o = checkobject(L, 1);
- ItemStack &item = o->m_stack;
- int amount = lua_tointeger(L, 2);
- bool result = item.addWear(amount, get_server(L)->idef());
- lua_pushboolean(L, result);
- return 1;
-}
-
-// add_item(self, itemstack or itemstring or table or nil) -> itemstack
-// Returns leftover item stack
-int LuaItemStack::l_add_item(lua_State *L)
-{
- LuaItemStack *o = checkobject(L, 1);
- ItemStack &item = o->m_stack;
- ItemStack newitem = read_item(L, 2);
- ItemStack leftover = item.addItem(newitem, get_server(L)->idef());
- create(L, leftover);
- return 1;
-}
-
-// item_fits(self, itemstack or itemstring or table or nil) -> true/false, itemstack
-// First return value is true iff the new item fits fully into the stack
-// Second return value is the would-be-left-over item stack
-int LuaItemStack::l_item_fits(lua_State *L)
-{
- LuaItemStack *o = checkobject(L, 1);
- ItemStack &item = o->m_stack;
- ItemStack newitem = read_item(L, 2);
- ItemStack restitem;
- bool fits = item.itemFits(newitem, &restitem, get_server(L)->idef());
- lua_pushboolean(L, fits); // first return value
- create(L, restitem); // second return value
- return 2;
-}
-
-// take_item(self, takecount=1) -> itemstack
-int LuaItemStack::l_take_item(lua_State *L)
-{
- LuaItemStack *o = checkobject(L, 1);
- ItemStack &item = o->m_stack;
- u32 takecount = 1;
- if(!lua_isnone(L, 2))
- takecount = luaL_checkinteger(L, 2);
- ItemStack taken = item.takeItem(takecount);
- create(L, taken);
- return 1;
-}
-
-// peek_item(self, peekcount=1) -> itemstack
-int LuaItemStack::l_peek_item(lua_State *L)
-{
- LuaItemStack *o = checkobject(L, 1);
- ItemStack &item = o->m_stack;
- u32 peekcount = 1;
- if(!lua_isnone(L, 2))
- peekcount = lua_tointeger(L, 2);
- ItemStack peekaboo = item.peekItem(peekcount);
- create(L, peekaboo);
- return 1;
-}
-
-LuaItemStack::LuaItemStack(const ItemStack &item):
- m_stack(item)
-{
-}
-
-LuaItemStack::~LuaItemStack()
-{
-}
-
-const ItemStack& LuaItemStack::getItem() const
-{
- return m_stack;
-}
-ItemStack& LuaItemStack::getItem()
-{
- return m_stack;
-}
-
-// LuaItemStack(itemstack or itemstring or table or nil)
-// Creates an LuaItemStack and leaves it on top of stack
-int LuaItemStack::create_object(lua_State *L)
-{
- ItemStack item = read_item(L, 1);
- LuaItemStack *o = new LuaItemStack(item);
- *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
- luaL_getmetatable(L, className);
- lua_setmetatable(L, -2);
- return 1;
-}
-// Not callable from Lua
-int LuaItemStack::create(lua_State *L, const ItemStack &item)
-{
- LuaItemStack *o = new LuaItemStack(item);
- *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
- luaL_getmetatable(L, className);
- lua_setmetatable(L, -2);
- return 1;
-}
-
-LuaItemStack* LuaItemStack::checkobject(lua_State *L, int narg)
-{
- luaL_checktype(L, narg, LUA_TUSERDATA);
- void *ud = luaL_checkudata(L, narg, className);
- if(!ud) luaL_typerror(L, narg, className);
- return *(LuaItemStack**)ud; // unbox pointer
-}
-
-void LuaItemStack::Register(lua_State *L)
-{
- lua_newtable(L);
- int methodtable = lua_gettop(L);
- luaL_newmetatable(L, className);
- int metatable = lua_gettop(L);
-
- lua_pushliteral(L, "__metatable");
- lua_pushvalue(L, methodtable);
- lua_settable(L, metatable); // hide metatable from Lua getmetatable()
-
- lua_pushliteral(L, "__index");
- lua_pushvalue(L, methodtable);
- lua_settable(L, metatable);
-
- lua_pushliteral(L, "__gc");
- lua_pushcfunction(L, gc_object);
- lua_settable(L, metatable);
-
- lua_pop(L, 1); // drop metatable
-
- luaL_openlib(L, 0, methods, 0); // fill methodtable
- lua_pop(L, 1); // drop methodtable
-
- // Can be created from Lua (LuaItemStack(itemstack or itemstring or table or nil))
- lua_register(L, className, create_object);
-}
-
-const char LuaItemStack::className[] = "ItemStack";
-const luaL_reg LuaItemStack::methods[] = {
- luamethod(LuaItemStack, is_empty),
- luamethod(LuaItemStack, get_name),
- luamethod(LuaItemStack, get_count),
- luamethod(LuaItemStack, get_wear),
- luamethod(LuaItemStack, get_metadata),
- luamethod(LuaItemStack, clear),
- luamethod(LuaItemStack, replace),
- luamethod(LuaItemStack, to_string),
- luamethod(LuaItemStack, to_table),
- luamethod(LuaItemStack, get_stack_max),
- luamethod(LuaItemStack, get_free_space),
- luamethod(LuaItemStack, is_known),
- luamethod(LuaItemStack, get_definition),
- luamethod(LuaItemStack, get_tool_capabilities),
- luamethod(LuaItemStack, add_wear),
- luamethod(LuaItemStack, add_item),
- luamethod(LuaItemStack, item_fits),
- luamethod(LuaItemStack, take_item),
- luamethod(LuaItemStack, peek_item),
- {0,0}
-};
-
-ItemStack read_item(lua_State *L, int index)
-{
- if(index < 0)
- index = lua_gettop(L) + 1 + index;
-
- if(lua_isnil(L, index))
- {
- return ItemStack();
- }
- else if(lua_isuserdata(L, index))
- {
- // Convert from LuaItemStack
- LuaItemStack *o = LuaItemStack::checkobject(L, index);
- return o->getItem();
- }
- else if(lua_isstring(L, index))
- {
- // Convert from itemstring
- std::string itemstring = lua_tostring(L, index);
- IItemDefManager *idef = get_server(L)->idef();
- try
- {
- ItemStack item;
- item.deSerialize(itemstring, idef);
- return item;
- }
- catch(SerializationError &e)
- {
- infostream<<"WARNING: unable to create item from itemstring"
- <<": "<<itemstring<<std::endl;
- return ItemStack();
- }
- }
- else if(lua_istable(L, index))
- {
- // Convert from table
- IItemDefManager *idef = get_server(L)->idef();
- std::string name = getstringfield_default(L, index, "name", "");
- int count = getintfield_default(L, index, "count", 1);
- int wear = getintfield_default(L, index, "wear", 0);
- std::string metadata = getstringfield_default(L, index, "metadata", "");
- return ItemStack(name, count, wear, metadata, idef);
- }
- else
- {
- throw LuaError(L, "Expecting itemstack, itemstring, table or nil");
- }
-}
-
-std::vector<ItemStack> read_items(lua_State *L, int index)
-{
- if(index < 0)
- index = lua_gettop(L) + 1 + index;
-
- std::vector<ItemStack> items;
- luaL_checktype(L, index, LUA_TTABLE);
- lua_pushnil(L);
- while(lua_next(L, index) != 0){
- // key at index -2 and value at index -1
- items.push_back(read_item(L, -1));
- // removes value, keeps key for next iteration
- lua_pop(L, 1);
- }
- return items;
-}
-
-// creates a table of ItemStacks
-void push_items(lua_State *L, const std::vector<ItemStack> &items)
-{
- // Get the table insert function
- lua_getglobal(L, "table");
- lua_getfield(L, -1, "insert");
- int table_insert = lua_gettop(L);
- // Create and fill table
- lua_newtable(L);
- int table = lua_gettop(L);
- for(u32 i=0; i<items.size(); i++){
- ItemStack item = items[i];
- lua_pushvalue(L, table_insert);
- lua_pushvalue(L, table);
- LuaItemStack::create(L, item);
- if(lua_pcall(L, 2, 0, 0))
- script_error(L, "error: %s", lua_tostring(L, -1));
- }
- lua_remove(L, -2); // Remove table
- lua_remove(L, -2); // Remove insert
-}