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