]> git.lizzy.rs Git - dragonfireclient.git/blob - src/script/cpp_api/s_item.cpp
Omnicleanup: header cleanup, add ModApiUtil shared between game and mainmenu
[dragonfireclient.git] / src / script / cpp_api / s_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 "cpp_api/s_item.h"
21 #include "cpp_api/s_internal.h"
22 #include "common/c_converter.h"
23 #include "common/c_content.h"
24 #include "lua_api/l_item.h"
25 #include "server.h"
26 #include "log.h"
27 #include "util/pointedthing.h"
28
29 bool ScriptApiItem::item_OnDrop(ItemStack &item,
30                 ServerActiveObject *dropper, v3f pos)
31 {
32         SCRIPTAPI_PRECHECKHEADER
33
34         // Push callback function on stack
35         if(!getItemCallback(item.name.c_str(), "on_drop"))
36                 return false;
37
38         // Call function
39         LuaItemStack::create(L, item);
40         objectrefGetOrCreate(dropper);
41         pushFloatPos(L, pos);
42         if(lua_pcall(L, 3, 1, 0))
43                 scriptError("error: %s", lua_tostring(L, -1));
44         if(!lua_isnil(L, -1))
45                 item = read_item(L,-1, getServer());
46         return true;
47 }
48
49 bool ScriptApiItem::item_OnPlace(ItemStack &item,
50                 ServerActiveObject *placer, const PointedThing &pointed)
51 {
52         SCRIPTAPI_PRECHECKHEADER
53
54         // Push callback function on stack
55         if(!getItemCallback(item.name.c_str(), "on_place"))
56                 return false;
57
58         // Call function
59         LuaItemStack::create(L, item);
60         objectrefGetOrCreate(placer);
61         pushPointedThing(pointed);
62         if(lua_pcall(L, 3, 1, 0))
63                 scriptError("error: %s", lua_tostring(L, -1));
64         if(!lua_isnil(L, -1))
65                 item = read_item(L,-1, getServer());
66         return true;
67 }
68
69 bool ScriptApiItem::item_OnUse(ItemStack &item,
70                 ServerActiveObject *user, const PointedThing &pointed)
71 {
72         SCRIPTAPI_PRECHECKHEADER
73
74         // Push callback function on stack
75         if(!getItemCallback(item.name.c_str(), "on_use"))
76                 return false;
77
78         // Call function
79         LuaItemStack::create(L, item);
80         objectrefGetOrCreate(user);
81         pushPointedThing(pointed);
82         if(lua_pcall(L, 3, 1, 0))
83                 scriptError("error: %s", lua_tostring(L, -1));
84         if(!lua_isnil(L, -1))
85                 item = read_item(L,-1, getServer());
86         return true;
87 }
88
89 // Retrieves minetest.registered_items[name][callbackname]
90 // If that is nil or on error, return false and stack is unchanged
91 // If that is a function, returns true and pushes the
92 // function onto the stack
93 // If minetest.registered_items[name] doesn't exist, minetest.nodedef_default
94 // is tried instead so unknown items can still be manipulated to some degree
95 bool ScriptApiItem::getItemCallback(const char *name, const char *callbackname)
96 {
97         lua_State* L = getStack();
98
99         lua_getglobal(L, "minetest");
100         lua_getfield(L, -1, "registered_items");
101         lua_remove(L, -2);
102         luaL_checktype(L, -1, LUA_TTABLE);
103         lua_getfield(L, -1, name);
104         lua_remove(L, -2);
105         // Should be a table
106         if(lua_type(L, -1) != LUA_TTABLE)
107         {
108                 // Report error and clean up
109                 errorstream<<"Item \""<<name<<"\" not defined"<<std::endl;
110                 lua_pop(L, 1);
111
112                 // Try minetest.nodedef_default instead
113                 lua_getglobal(L, "minetest");
114                 lua_getfield(L, -1, "nodedef_default");
115                 lua_remove(L, -2);
116                 luaL_checktype(L, -1, LUA_TTABLE);
117         }
118         lua_getfield(L, -1, callbackname);
119         lua_remove(L, -2);
120         // Should be a function or nil
121         if(lua_type(L, -1) == LUA_TFUNCTION)
122         {
123                 return true;
124         }
125         else if(lua_isnil(L, -1))
126         {
127                 lua_pop(L, 1);
128                 return false;
129         }
130         else
131         {
132                 errorstream<<"Item \""<<name<<"\" callback \""
133                         <<callbackname<<" is not a function"<<std::endl;
134                 lua_pop(L, 1);
135                 return false;
136         }
137 }
138
139 void ScriptApiItem::pushPointedThing(const PointedThing& pointed)
140 {
141         lua_State* L = getStack();
142
143         lua_newtable(L);
144         if(pointed.type == POINTEDTHING_NODE)
145         {
146                 lua_pushstring(L, "node");
147                 lua_setfield(L, -2, "type");
148                 push_v3s16(L, pointed.node_undersurface);
149                 lua_setfield(L, -2, "under");
150                 push_v3s16(L, pointed.node_abovesurface);
151                 lua_setfield(L, -2, "above");
152         }
153         else if(pointed.type == POINTEDTHING_OBJECT)
154         {
155                 lua_pushstring(L, "object");
156                 lua_setfield(L, -2, "type");
157                 objectrefGet(pointed.object_id);
158                 lua_setfield(L, -2, "ref");
159         }
160         else
161         {
162                 lua_pushstring(L, "nothing");
163                 lua_setfield(L, -2, "type");
164         }
165 }
166
167