]> git.lizzy.rs Git - dragonfireclient.git/blob - src/script/cpp_api/s_node.cpp
Add 'on_prejoinplayer' callback
[dragonfireclient.git] / src / script / cpp_api / s_node.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_node.h"
21 #include "cpp_api/s_internal.h"
22 #include "common/c_converter.h"
23 #include "common/c_content.h"
24 #include "nodedef.h"
25 #include "server.h"
26 #include "environment.h"
27
28
29 struct EnumString ScriptApiNode::es_DrawType[] =
30         {
31                 {NDT_NORMAL, "normal"},
32                 {NDT_AIRLIKE, "airlike"},
33                 {NDT_LIQUID, "liquid"},
34                 {NDT_FLOWINGLIQUID, "flowingliquid"},
35                 {NDT_GLASSLIKE, "glasslike"},
36                 {NDT_GLASSLIKE_FRAMED, "glasslike_framed"},
37                 {NDT_ALLFACES, "allfaces"},
38                 {NDT_ALLFACES_OPTIONAL, "allfaces_optional"},
39                 {NDT_TORCHLIKE, "torchlike"},
40                 {NDT_SIGNLIKE, "signlike"},
41                 {NDT_PLANTLIKE, "plantlike"},
42                 {NDT_FENCELIKE, "fencelike"},
43                 {NDT_RAILLIKE, "raillike"},
44                 {NDT_NODEBOX, "nodebox"},
45                 {0, NULL},
46         };
47
48 struct EnumString ScriptApiNode::es_ContentParamType2[] =
49         {
50                 {CPT2_NONE, "none"},
51                 {CPT2_FULL, "full"},
52                 {CPT2_FLOWINGLIQUID, "flowingliquid"},
53                 {CPT2_FACEDIR, "facedir"},
54                 {CPT2_WALLMOUNTED, "wallmounted"},
55                 {CPT2_LEVELED, "leveled"},
56                 {0, NULL},
57         };
58
59 struct EnumString ScriptApiNode::es_LiquidType[] =
60         {
61                 {LIQUID_NONE, "none"},
62                 {LIQUID_FLOWING, "flowing"},
63                 {LIQUID_SOURCE, "source"},
64                 {0, NULL},
65         };
66
67 struct EnumString ScriptApiNode::es_ContentParamType[] =
68         {
69                 {CPT_NONE, "none"},
70                 {CPT_LIGHT, "light"},
71                 {0, NULL},
72         };
73
74 struct EnumString ScriptApiNode::es_NodeBoxType[] =
75         {
76                 {NODEBOX_REGULAR, "regular"},
77                 {NODEBOX_FIXED, "fixed"},
78                 {NODEBOX_WALLMOUNTED, "wallmounted"},
79                 {NODEBOX_LEVELED, "leveled"},
80                 {0, NULL},
81         };
82
83 ScriptApiNode::ScriptApiNode() {
84 }
85
86 ScriptApiNode::~ScriptApiNode() {
87 }
88
89 bool ScriptApiNode::node_on_punch(v3s16 p, MapNode node,
90                 ServerActiveObject *puncher)
91 {
92         SCRIPTAPI_PRECHECKHEADER
93
94         lua_pushcfunction(L, script_error_handler);
95         int errorhandler = lua_gettop(L);
96
97         INodeDefManager *ndef = getServer()->ndef();
98
99         // Push callback function on stack
100         if(!getItemCallback(ndef->get(node).name.c_str(), "on_punch"))
101                 return false;
102
103         // Call function
104         push_v3s16(L, p);
105         pushnode(L, node, ndef);
106         objectrefGetOrCreate(puncher);
107         if(lua_pcall(L, 3, 0, errorhandler))
108                 scriptError();
109         lua_pop(L, 1); // Pop error handler
110         return true;
111 }
112
113 bool ScriptApiNode::node_on_dig(v3s16 p, MapNode node,
114                 ServerActiveObject *digger)
115 {
116         SCRIPTAPI_PRECHECKHEADER
117
118         lua_pushcfunction(L, script_error_handler);
119         int errorhandler = lua_gettop(L);
120
121         INodeDefManager *ndef = getServer()->ndef();
122
123         // Push callback function on stack
124         if(!getItemCallback(ndef->get(node).name.c_str(), "on_dig"))
125                 return false;
126
127         // Call function
128         push_v3s16(L, p);
129         pushnode(L, node, ndef);
130         objectrefGetOrCreate(digger);
131         if(lua_pcall(L, 3, 0, errorhandler))
132                 scriptError();
133         lua_pop(L, 1); // Pop error handler
134         return true;
135 }
136
137 void ScriptApiNode::node_on_construct(v3s16 p, MapNode node)
138 {
139         SCRIPTAPI_PRECHECKHEADER
140
141         lua_pushcfunction(L, script_error_handler);
142         int errorhandler = lua_gettop(L);
143
144         INodeDefManager *ndef = getServer()->ndef();
145
146         // Push callback function on stack
147         if(!getItemCallback(ndef->get(node).name.c_str(), "on_construct"))
148                 return;
149
150         // Call function
151         push_v3s16(L, p);
152         if(lua_pcall(L, 1, 0, errorhandler))
153                 scriptError();
154         lua_pop(L, 1); // Pop error handler
155 }
156
157 void ScriptApiNode::node_on_destruct(v3s16 p, MapNode node)
158 {
159         SCRIPTAPI_PRECHECKHEADER
160
161         lua_pushcfunction(L, script_error_handler);
162         int errorhandler = lua_gettop(L);
163
164         INodeDefManager *ndef = getServer()->ndef();
165
166         // Push callback function on stack
167         if(!getItemCallback(ndef->get(node).name.c_str(), "on_destruct"))
168                 return;
169
170         // Call function
171         push_v3s16(L, p);
172         if(lua_pcall(L, 1, 0, errorhandler))
173                 scriptError();
174         lua_pop(L, 1); // Pop error handler
175 }
176
177 void ScriptApiNode::node_after_destruct(v3s16 p, MapNode node)
178 {
179         SCRIPTAPI_PRECHECKHEADER
180
181         lua_pushcfunction(L, script_error_handler);
182         int errorhandler = lua_gettop(L);
183
184         INodeDefManager *ndef = getServer()->ndef();
185
186         // Push callback function on stack
187         if(!getItemCallback(ndef->get(node).name.c_str(), "after_destruct"))
188                 return;
189
190         // Call function
191         push_v3s16(L, p);
192         pushnode(L, node, ndef);
193         if(lua_pcall(L, 2, 0, errorhandler))
194                 scriptError();
195         lua_pop(L, 1); // Pop error handler
196 }
197
198 bool ScriptApiNode::node_on_timer(v3s16 p, MapNode node, f32 dtime)
199 {
200         SCRIPTAPI_PRECHECKHEADER
201
202         lua_pushcfunction(L, script_error_handler);
203         int errorhandler = lua_gettop(L);
204
205         INodeDefManager *ndef = getServer()->ndef();
206
207         // Push callback function on stack
208         if(!getItemCallback(ndef->get(node).name.c_str(), "on_timer"))
209                 return false;
210
211         // Call function
212         push_v3s16(L, p);
213         lua_pushnumber(L,dtime);
214         if(lua_pcall(L, 2, 1, errorhandler))
215                 scriptError();
216         lua_remove(L, errorhandler); // Remove error handler
217         return (bool) lua_isboolean(L, -1) && (bool) lua_toboolean(L, -1) == true;
218 }
219
220 void ScriptApiNode::node_on_receive_fields(v3s16 p,
221                 const std::string &formname,
222                 const std::map<std::string, std::string> &fields,
223                 ServerActiveObject *sender)
224 {
225         SCRIPTAPI_PRECHECKHEADER
226
227         lua_pushcfunction(L, script_error_handler);
228         int errorhandler = lua_gettop(L);
229
230         INodeDefManager *ndef = getServer()->ndef();
231
232         // If node doesn't exist, we don't know what callback to call
233         MapNode node = getEnv()->getMap().getNodeNoEx(p);
234         if(node.getContent() == CONTENT_IGNORE)
235                 return;
236
237         // Push callback function on stack
238         if(!getItemCallback(ndef->get(node).name.c_str(), "on_receive_fields"))
239                 return;
240
241         // Call function
242         push_v3s16(L, p);                    // pos
243         lua_pushstring(L, formname.c_str()); // formname
244         lua_newtable(L);                     // fields
245         for(std::map<std::string, std::string>::const_iterator
246                         i = fields.begin(); i != fields.end(); i++){
247                 const std::string &name = i->first;
248                 const std::string &value = i->second;
249                 lua_pushstring(L, name.c_str());
250                 lua_pushlstring(L, value.c_str(), value.size());
251                 lua_settable(L, -3);
252         }
253         objectrefGetOrCreate(sender);        // player
254         if(lua_pcall(L, 4, 0, errorhandler))
255                 scriptError();
256         lua_pop(L, 1); // Pop error handler
257 }
258
259 void ScriptApiNode::node_falling_update(v3s16 p)
260 {
261         SCRIPTAPI_PRECHECKHEADER
262
263         lua_pushcfunction(L, script_error_handler);
264         int errorhandler = lua_gettop(L);
265
266         lua_getglobal(L, "nodeupdate");
267         push_v3s16(L, p);
268         if(lua_pcall(L, 1, 0, errorhandler))
269                 scriptError();
270         lua_pop(L, 1); // Pop error handler
271 }
272
273 void ScriptApiNode::node_falling_update_single(v3s16 p)
274 {
275         SCRIPTAPI_PRECHECKHEADER
276
277         lua_pushcfunction(L, script_error_handler);
278         int errorhandler = lua_gettop(L);
279
280         lua_getglobal(L, "nodeupdate_single");
281         push_v3s16(L, p);
282         if(lua_pcall(L, 1, 0, errorhandler))
283                 scriptError();
284         lua_pop(L, 1); // Pop error handler
285 }
286