]> git.lizzy.rs Git - dragonfireclient.git/blob - src/script/cpp_api/s_client.cpp
Merge branch 'master' of https://github.com/minetest/minetest
[dragonfireclient.git] / src / script / cpp_api / s_client.cpp
1 /*
2 Minetest
3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4 Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include "nodedef.h"
22 #include "itemdef.h"
23 #include "s_client.h"
24 #include "s_internal.h"
25 #include "client/client.h"
26 #include "common/c_converter.h"
27 #include "common/c_content.h"
28 #include "lua_api/l_clientobject.h"
29 #include "s_item.h"
30
31 void ScriptApiClient::on_mods_loaded()
32 {
33         SCRIPTAPI_PRECHECKHEADER
34
35         // Get registered shutdown hooks
36         lua_getglobal(L, "core");
37         lua_getfield(L, -1, "registered_on_mods_loaded");
38         // Call callbacks
39         try {
40                 runCallbacks(0, RUN_CALLBACKS_MODE_FIRST);
41         } catch (LuaError &e) {
42                 getClient()->setFatalError(e);
43         }
44 }
45
46 void ScriptApiClient::on_shutdown()
47 {
48         SCRIPTAPI_PRECHECKHEADER
49
50         // Get registered shutdown hooks
51         lua_getglobal(L, "core");
52         lua_getfield(L, -1, "registered_on_shutdown");
53         // Call callbacks
54         try {
55                 runCallbacks(0, RUN_CALLBACKS_MODE_FIRST);
56         } catch (LuaError &e) {
57                 getClient()->setFatalError(e);
58         }
59 }
60
61 bool ScriptApiClient::on_sending_message(const std::string &message)
62 {
63         SCRIPTAPI_PRECHECKHEADER
64
65         // Get core.registered_on_chat_messages
66         lua_getglobal(L, "core");
67         lua_getfield(L, -1, "registered_on_sending_chat_message");
68         // Call callbacks
69         lua_pushstring(L, message.c_str());
70         try {
71                 runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC);
72         } catch (LuaError &e) {
73                 getClient()->setFatalError(e);
74                 return true;
75         }
76         return readParam<bool>(L, -1);
77 }
78
79 bool ScriptApiClient::on_receiving_message(const std::string &message)
80 {
81         SCRIPTAPI_PRECHECKHEADER
82
83         // Get core.registered_on_chat_messages
84         lua_getglobal(L, "core");
85         lua_getfield(L, -1, "registered_on_receiving_chat_message");
86         // Call callbacks
87         lua_pushstring(L, message.c_str());
88         try {
89                 runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC);
90         } catch (LuaError &e) {
91                 getClient()->setFatalError(e);
92                 return true;
93         }
94         return readParam<bool>(L, -1);
95 }
96
97 void ScriptApiClient::on_damage_taken(int32_t damage_amount)
98 {
99         SCRIPTAPI_PRECHECKHEADER
100
101         // Get core.registered_on_chat_messages
102         lua_getglobal(L, "core");
103         lua_getfield(L, -1, "registered_on_damage_taken");
104         // Call callbacks
105         lua_pushinteger(L, damage_amount);
106         try {
107                 runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC);
108         } catch (LuaError &e) {
109                 getClient()->setFatalError(e);
110         }
111 }
112
113 void ScriptApiClient::on_hp_modification(int32_t newhp)
114 {
115         SCRIPTAPI_PRECHECKHEADER
116
117         // Get core.registered_on_chat_messages
118         lua_getglobal(L, "core");
119         lua_getfield(L, -1, "registered_on_hp_modification");
120         // Call callbacks
121         lua_pushinteger(L, newhp);
122         try {
123                 runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC);
124         } catch (LuaError &e) {
125                 getClient()->setFatalError(e);
126         }
127 }
128
129 void ScriptApiClient::on_death()
130 {
131         SCRIPTAPI_PRECHECKHEADER
132
133         // Get registered shutdown hooks
134         lua_getglobal(L, "core");
135         lua_getfield(L, -1, "registered_on_death");
136         // Call callbacks
137         try {
138                 runCallbacks(0, RUN_CALLBACKS_MODE_FIRST);
139         } catch (LuaError &e) {
140                 getClient()->setFatalError(e);
141         }
142 }
143
144 void ScriptApiClient::environment_step(float dtime)
145 {
146         SCRIPTAPI_PRECHECKHEADER
147
148         // Get core.registered_globalsteps
149         lua_getglobal(L, "core");
150         lua_getfield(L, -1, "registered_globalsteps");
151         // Call callbacks
152         lua_pushnumber(L, dtime);
153         try {
154                 runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
155         } catch (LuaError &e) {
156                 getClient()->setFatalError(e);
157         }
158 }
159
160 void ScriptApiClient::on_formspec_input(const std::string &formname,
161         const StringMap &fields)
162 {
163         SCRIPTAPI_PRECHECKHEADER
164
165         // Get core.registered_on_chat_messages
166         lua_getglobal(L, "core");
167         lua_getfield(L, -1, "registered_on_formspec_input");
168         // Call callbacks
169         // param 1
170         lua_pushstring(L, formname.c_str());
171         // param 2
172         lua_newtable(L);
173         StringMap::const_iterator it;
174         for (it = fields.begin(); it != fields.end(); ++it) {
175                 const std::string &name = it->first;
176                 const std::string &value = it->second;
177                 lua_pushstring(L, name.c_str());
178                 lua_pushlstring(L, value.c_str(), value.size());
179                 lua_settable(L, -3);
180         }
181         try {
182                 runCallbacks(2, RUN_CALLBACKS_MODE_OR_SC);
183         } catch (LuaError &e) {
184                 getClient()->setFatalError(e);
185         }
186 }
187
188 bool ScriptApiClient::on_dignode(v3s16 p, MapNode node)
189 {
190         SCRIPTAPI_PRECHECKHEADER
191
192         const NodeDefManager *ndef = getClient()->ndef();
193
194         // Get core.registered_on_dignode
195         lua_getglobal(L, "core");
196         lua_getfield(L, -1, "registered_on_dignode");
197
198         // Push data
199         push_v3s16(L, p);
200         pushnode(L, node, ndef);
201
202         // Call functions
203         try {
204                 runCallbacks(2, RUN_CALLBACKS_MODE_OR);
205         } catch (LuaError &e) {
206                 getClient()->setFatalError(e);
207                 return true;
208         }
209         return lua_toboolean(L, -1);
210 }
211
212 bool ScriptApiClient::on_punchnode(v3s16 p, MapNode node)
213 {
214         SCRIPTAPI_PRECHECKHEADER
215
216         const NodeDefManager *ndef = getClient()->ndef();
217
218         // Get core.registered_on_punchnode
219         lua_getglobal(L, "core");
220         lua_getfield(L, -1, "registered_on_punchnode");
221
222         // Push data
223         push_v3s16(L, p);
224         pushnode(L, node, ndef);
225
226         // Call functions
227         try {
228                 runCallbacks(2, RUN_CALLBACKS_MODE_OR);
229         } catch (LuaError &e) {
230                 getClient()->setFatalError(e);
231                 return true;
232         }
233         return readParam<bool>(L, -1);
234 }
235
236 bool ScriptApiClient::on_placenode(const PointedThing &pointed, const ItemDefinition &item)
237 {
238         SCRIPTAPI_PRECHECKHEADER
239
240         // Get core.registered_on_placenode
241         lua_getglobal(L, "core");
242         lua_getfield(L, -1, "registered_on_placenode");
243
244         // Push data
245         push_pointed_thing(L, pointed, true);
246         push_item_definition(L, item);
247
248         // Call functions
249         try {
250                 runCallbacks(2, RUN_CALLBACKS_MODE_OR);
251         } catch (LuaError &e) {
252                 getClient()->setFatalError(e);
253                 return true;
254         }
255         return readParam<bool>(L, -1);
256 }
257
258 bool ScriptApiClient::on_item_use(const ItemStack &item, const PointedThing &pointed)
259 {
260         SCRIPTAPI_PRECHECKHEADER
261
262         // Get core.registered_on_item_use
263         lua_getglobal(L, "core");
264         lua_getfield(L, -1, "registered_on_item_use");
265
266         // Push data
267         LuaItemStack::create(L, item);
268         push_pointed_thing(L, pointed, true);
269
270         // Call functions
271         try {
272                 runCallbacks(2, RUN_CALLBACKS_MODE_OR);
273         } catch (LuaError &e) {
274                 getClient()->setFatalError(e);
275                 return true;
276         }
277         return readParam<bool>(L, -1);
278 }
279
280 bool ScriptApiClient::on_recieve_physics_override(float speed, float jump, float gravity, bool sneak, bool sneak_glitch, bool new_move)
281 {
282         SCRIPTAPI_PRECHECKHEADER
283
284         // Get core.registered_on_recieve_physics_override
285         lua_getglobal(L, "core");
286         lua_getfield(L, -1, "registered_on_recieve_physics_override");
287
288         // Push data
289         push_physics_override(L, speed, jump, gravity, sneak, sneak_glitch, new_move);
290
291         // Call functions
292         runCallbacks(1, RUN_CALLBACKS_MODE_OR);
293         return readParam<bool>(L, -1);
294 }
295
296 bool ScriptApiClient::on_play_sound(SimpleSoundSpec spec)
297 {
298         SCRIPTAPI_PRECHECKHEADER
299
300         // Get core.registered_on_play_sound
301         lua_getglobal(L, "core");
302         lua_getfield(L, -1, "registered_on_play_sound");
303
304         // Push data
305         push_soundspec(L, spec);
306
307         // Call functions
308         runCallbacks(1, RUN_CALLBACKS_MODE_OR);
309         return readParam<bool>(L, -1);
310 }
311
312 bool ScriptApiClient::on_spawn_particle(struct ParticleParameters param)
313 {
314         SCRIPTAPI_PRECHECKHEADER
315
316         // Get core.registered_on_play_sound
317
318         lua_getglobal(L, "core");
319         lua_getfield(L, -1, "registered_on_spawn_particle");
320
321         // Push data
322         lua_newtable(L);
323         push_v3f(L, param.pos);
324         lua_setfield(L, -2, "pos");
325         push_v3f(L, param.vel);
326         lua_setfield(L, -2, "velocity");
327         push_v3f(L, param.acc);
328         lua_setfield(L, -2, "acceleration");
329         setfloatfield(L, -1, "expirationtime", param.expirationtime);
330         setboolfield(L, -1, "collisiondetection", param.collisiondetection);
331         setboolfield(L, -1, "collision_removal", param.collision_removal);
332         setboolfield(L, -1, "object_collision", param.object_collision);
333         setboolfield(L, -1, "vertical", param.vertical);
334         push_animation_definition(L, param.animation);
335         lua_setfield(L, -2, "animation");
336         setstringfield(L, -1, "texture", param.texture);
337         setintfield(L, -1, "glow", param.glow);
338         if (param.node.getContent() != CONTENT_IGNORE) {
339                 pushnode(L, param.node, getGameDef()->ndef());
340                 lua_setfield(L, -2, "node");
341         }
342         setintfield(L, -1, "node_tile", param.node_tile);
343
344         // Call functions
345         runCallbacks(1, RUN_CALLBACKS_MODE_OR);
346         return readParam<bool>(L, -1);
347 }
348
349 void ScriptApiClient::on_object_properties_change(s16 id)
350 {
351         SCRIPTAPI_PRECHECKHEADER
352
353         // Get core.registered_on_object_properties_change
354         lua_getglobal(L, "core");
355         lua_getfield(L, -1, "registered_on_object_properties_change");
356
357         // Push data
358         push_objectRef(L, id);
359
360         // Call functions
361         runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
362 }
363
364 void ScriptApiClient::on_object_hp_change(s16 id)
365 {
366         SCRIPTAPI_PRECHECKHEADER
367
368         // Get core.registered_on_object_hp_change
369         lua_getglobal(L, "core");
370         lua_getfield(L, -1, "registered_on_object_hp_change");
371
372         // Push data
373         push_objectRef(L, id);
374
375         // Call functions
376         runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
377 }
378
379 bool ScriptApiClient::on_object_add(s16 id)
380 {
381         SCRIPTAPI_PRECHECKHEADER
382
383         // Get core.registered_on_object_add
384         lua_getglobal(L, "core");
385         lua_getfield(L, -1, "registered_on_object_add");
386
387         // Push data
388         push_objectRef(L, id);
389
390         // Call functions
391         runCallbacks(1, RUN_CALLBACKS_MODE_OR);
392         return readParam<bool>(L, -1);
393 }
394
395 bool ScriptApiClient::on_inventory_open(Inventory *inventory)
396 {
397         SCRIPTAPI_PRECHECKHEADER
398
399         lua_getglobal(L, "core");
400         lua_getfield(L, -1, "registered_on_inventory_open");
401
402         push_inventory_lists(L, *inventory);
403
404         try {
405                 runCallbacks(1, RUN_CALLBACKS_MODE_OR);
406         } catch (LuaError &e) {
407                 getClient()->setFatalError(e);
408                 return true;
409         }
410         return readParam<bool>(L, -1);
411 }
412
413 void ScriptApiClient::open_enderchest()
414 {
415         SCRIPTAPI_PRECHECKHEADER
416
417         PUSH_ERROR_HANDLER(L);
418         int error_handler = lua_gettop(L) - 1;
419         lua_insert(L, error_handler);
420
421         lua_getglobal(L, "core");
422         lua_getfield(L, -1, "open_enderchest");
423         if (lua_isfunction(L, -1))
424                 lua_pcall(L, 0, 0, error_handler);
425 }
426
427 v3f ScriptApiClient::get_send_speed(v3f speed)
428 {
429         SCRIPTAPI_PRECHECKHEADER
430
431         PUSH_ERROR_HANDLER(L);
432         int error_handler = lua_gettop(L) - 1;
433         lua_insert(L, error_handler);
434
435         lua_getglobal(L, "core");
436         lua_getfield(L, -1, "get_send_speed");
437         if (lua_isfunction(L, -1)) {
438                 speed /= BS;
439                 push_v3f(L, speed);
440                 lua_pcall(L, 1, 1, error_handler);
441                 speed = read_v3f(L, -1);
442                 speed *= BS;
443         }
444
445         return speed;
446 }
447
448 void ScriptApiClient::set_node_def(const ContentFeatures &f)
449 {
450         SCRIPTAPI_PRECHECKHEADER
451
452         lua_getglobal(L, "core");
453         lua_getfield(L, -1, "registered_nodes");
454
455         push_content_features(L, f);
456         lua_setfield(L, -2, f.name.c_str());
457 }
458
459 void ScriptApiClient::set_item_def(const ItemDefinition &i)
460 {
461         SCRIPTAPI_PRECHECKHEADER
462
463         lua_getglobal(L, "core");
464         lua_getfield(L, -1, "registered_items");
465
466         push_item_definition(L, i);
467         lua_setfield(L, -2, i.name.c_str());
468 }
469
470 void ScriptApiClient::setEnv(ClientEnvironment *env)
471 {
472         ScriptApiBase::setEnv(env);
473 }