3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4 Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr>
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.
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.
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.
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"
31 void ScriptApiClient::on_mods_loaded()
33 SCRIPTAPI_PRECHECKHEADER
35 // Get registered shutdown hooks
36 lua_getglobal(L, "core");
37 lua_getfield(L, -1, "registered_on_mods_loaded");
40 runCallbacks(0, RUN_CALLBACKS_MODE_FIRST);
41 } catch (LuaError &e) {
42 getClient()->setFatalError(e);
46 void ScriptApiClient::on_shutdown()
48 SCRIPTAPI_PRECHECKHEADER
50 // Get registered shutdown hooks
51 lua_getglobal(L, "core");
52 lua_getfield(L, -1, "registered_on_shutdown");
55 runCallbacks(0, RUN_CALLBACKS_MODE_FIRST);
56 } catch (LuaError &e) {
57 getClient()->setFatalError(e);
61 bool ScriptApiClient::on_sending_message(const std::string &message)
63 SCRIPTAPI_PRECHECKHEADER
65 // Get core.registered_on_chat_messages
66 lua_getglobal(L, "core");
67 lua_getfield(L, -1, "registered_on_sending_chat_message");
69 lua_pushstring(L, message.c_str());
71 runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC);
72 } catch (LuaError &e) {
73 getClient()->setFatalError(e);
76 return readParam<bool>(L, -1);
79 bool ScriptApiClient::on_receiving_message(const std::string &message)
81 SCRIPTAPI_PRECHECKHEADER
83 // Get core.registered_on_chat_messages
84 lua_getglobal(L, "core");
85 lua_getfield(L, -1, "registered_on_receiving_chat_message");
87 lua_pushstring(L, message.c_str());
89 runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC);
90 } catch (LuaError &e) {
91 getClient()->setFatalError(e);
94 return readParam<bool>(L, -1);
97 void ScriptApiClient::on_damage_taken(int32_t damage_amount)
99 SCRIPTAPI_PRECHECKHEADER
101 // Get core.registered_on_chat_messages
102 lua_getglobal(L, "core");
103 lua_getfield(L, -1, "registered_on_damage_taken");
105 lua_pushinteger(L, damage_amount);
107 runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC);
108 } catch (LuaError &e) {
109 getClient()->setFatalError(e);
113 void ScriptApiClient::on_hp_modification(int32_t newhp)
115 SCRIPTAPI_PRECHECKHEADER
117 // Get core.registered_on_chat_messages
118 lua_getglobal(L, "core");
119 lua_getfield(L, -1, "registered_on_hp_modification");
121 lua_pushinteger(L, newhp);
123 runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC);
124 } catch (LuaError &e) {
125 getClient()->setFatalError(e);
129 void ScriptApiClient::on_death()
131 SCRIPTAPI_PRECHECKHEADER
133 // Get registered shutdown hooks
134 lua_getglobal(L, "core");
135 lua_getfield(L, -1, "registered_on_death");
138 runCallbacks(0, RUN_CALLBACKS_MODE_FIRST);
139 } catch (LuaError &e) {
140 getClient()->setFatalError(e);
144 void ScriptApiClient::environment_step(float dtime)
146 SCRIPTAPI_PRECHECKHEADER
148 // Get core.registered_globalsteps
149 lua_getglobal(L, "core");
150 lua_getfield(L, -1, "registered_globalsteps");
152 lua_pushnumber(L, dtime);
154 runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
155 } catch (LuaError &e) {
156 getClient()->setFatalError(e);
160 void ScriptApiClient::on_formspec_input(const std::string &formname,
161 const StringMap &fields)
163 SCRIPTAPI_PRECHECKHEADER
165 // Get core.registered_on_chat_messages
166 lua_getglobal(L, "core");
167 lua_getfield(L, -1, "registered_on_formspec_input");
170 lua_pushstring(L, formname.c_str());
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());
182 runCallbacks(2, RUN_CALLBACKS_MODE_OR_SC);
183 } catch (LuaError &e) {
184 getClient()->setFatalError(e);
188 bool ScriptApiClient::on_dignode(v3s16 p, MapNode node)
190 SCRIPTAPI_PRECHECKHEADER
192 const NodeDefManager *ndef = getClient()->ndef();
194 // Get core.registered_on_dignode
195 lua_getglobal(L, "core");
196 lua_getfield(L, -1, "registered_on_dignode");
200 pushnode(L, node, ndef);
204 runCallbacks(2, RUN_CALLBACKS_MODE_OR);
205 } catch (LuaError &e) {
206 getClient()->setFatalError(e);
209 return lua_toboolean(L, -1);
212 bool ScriptApiClient::on_punchnode(v3s16 p, MapNode node)
214 SCRIPTAPI_PRECHECKHEADER
216 const NodeDefManager *ndef = getClient()->ndef();
218 // Get core.registered_on_punchnode
219 lua_getglobal(L, "core");
220 lua_getfield(L, -1, "registered_on_punchnode");
224 pushnode(L, node, ndef);
228 runCallbacks(2, RUN_CALLBACKS_MODE_OR);
229 } catch (LuaError &e) {
230 getClient()->setFatalError(e);
233 return readParam<bool>(L, -1);
236 bool ScriptApiClient::on_placenode(const PointedThing &pointed, const ItemDefinition &item)
238 SCRIPTAPI_PRECHECKHEADER
240 // Get core.registered_on_placenode
241 lua_getglobal(L, "core");
242 lua_getfield(L, -1, "registered_on_placenode");
245 push_pointed_thing(L, pointed, true);
246 push_item_definition(L, item);
250 runCallbacks(2, RUN_CALLBACKS_MODE_OR);
251 } catch (LuaError &e) {
252 getClient()->setFatalError(e);
255 return readParam<bool>(L, -1);
258 bool ScriptApiClient::on_item_use(const ItemStack &item, const PointedThing &pointed)
260 SCRIPTAPI_PRECHECKHEADER
262 // Get core.registered_on_item_use
263 lua_getglobal(L, "core");
264 lua_getfield(L, -1, "registered_on_item_use");
267 LuaItemStack::create(L, item);
268 push_pointed_thing(L, pointed, true);
272 runCallbacks(2, RUN_CALLBACKS_MODE_OR);
273 } catch (LuaError &e) {
274 getClient()->setFatalError(e);
277 return readParam<bool>(L, -1);
280 bool ScriptApiClient::on_recieve_physics_override(float speed, float jump, float gravity, bool sneak, bool sneak_glitch, bool new_move)
282 SCRIPTAPI_PRECHECKHEADER
284 // Get core.registered_on_recieve_physics_override
285 lua_getglobal(L, "core");
286 lua_getfield(L, -1, "registered_on_recieve_physics_override");
289 push_physics_override(L, speed, jump, gravity, sneak, sneak_glitch, new_move);
292 runCallbacks(1, RUN_CALLBACKS_MODE_OR);
293 return readParam<bool>(L, -1);
296 bool ScriptApiClient::on_play_sound(SimpleSoundSpec spec)
298 SCRIPTAPI_PRECHECKHEADER
300 // Get core.registered_on_play_sound
301 lua_getglobal(L, "core");
302 lua_getfield(L, -1, "registered_on_play_sound");
305 push_soundspec(L, spec);
308 runCallbacks(1, RUN_CALLBACKS_MODE_OR);
309 return readParam<bool>(L, -1);
312 bool ScriptApiClient::on_spawn_particle(struct ParticleParameters param)
314 SCRIPTAPI_PRECHECKHEADER
316 // Get core.registered_on_play_sound
318 lua_getglobal(L, "core");
319 lua_getfield(L, -1, "registered_on_spawn_particle");
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");
342 setintfield(L, -1, "node_tile", param.node_tile);
345 runCallbacks(1, RUN_CALLBACKS_MODE_OR);
346 return readParam<bool>(L, -1);
349 void ScriptApiClient::on_object_properties_change(s16 id)
351 SCRIPTAPI_PRECHECKHEADER
353 // Get core.registered_on_object_properties_change
354 lua_getglobal(L, "core");
355 lua_getfield(L, -1, "registered_on_object_properties_change");
358 push_objectRef(L, id);
361 runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
364 void ScriptApiClient::on_object_hp_change(s16 id)
366 SCRIPTAPI_PRECHECKHEADER
368 // Get core.registered_on_object_hp_change
369 lua_getglobal(L, "core");
370 lua_getfield(L, -1, "registered_on_object_hp_change");
373 push_objectRef(L, id);
376 runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
379 bool ScriptApiClient::on_object_add(s16 id)
381 SCRIPTAPI_PRECHECKHEADER
383 // Get core.registered_on_object_add
384 lua_getglobal(L, "core");
385 lua_getfield(L, -1, "registered_on_object_add");
388 push_objectRef(L, id);
391 runCallbacks(1, RUN_CALLBACKS_MODE_OR);
392 return readParam<bool>(L, -1);
395 bool ScriptApiClient::on_inventory_open(Inventory *inventory)
397 SCRIPTAPI_PRECHECKHEADER
399 lua_getglobal(L, "core");
400 lua_getfield(L, -1, "registered_on_inventory_open");
402 push_inventory_lists(L, *inventory);
405 runCallbacks(1, RUN_CALLBACKS_MODE_OR);
406 } catch (LuaError &e) {
407 getClient()->setFatalError(e);
410 return readParam<bool>(L, -1);
413 void ScriptApiClient::open_enderchest()
415 SCRIPTAPI_PRECHECKHEADER
417 PUSH_ERROR_HANDLER(L);
418 int error_handler = lua_gettop(L) - 1;
419 lua_insert(L, error_handler);
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);
427 v3f ScriptApiClient::get_send_speed(v3f speed)
429 SCRIPTAPI_PRECHECKHEADER
431 PUSH_ERROR_HANDLER(L);
432 int error_handler = lua_gettop(L) - 1;
433 lua_insert(L, error_handler);
435 lua_getglobal(L, "core");
436 lua_getfield(L, -1, "get_send_speed");
437 if (lua_isfunction(L, -1)) {
440 lua_pcall(L, 1, 1, error_handler);
441 speed = read_v3f(L, -1);
448 void ScriptApiClient::set_node_def(const ContentFeatures &f)
450 SCRIPTAPI_PRECHECKHEADER
452 lua_getglobal(L, "core");
453 lua_getfield(L, -1, "registered_nodes");
455 push_content_features(L, f);
456 lua_setfield(L, -2, f.name.c_str());
459 void ScriptApiClient::set_item_def(const ItemDefinition &i)
461 SCRIPTAPI_PRECHECKHEADER
463 lua_getglobal(L, "core");
464 lua_getfield(L, -1, "registered_items");
466 push_item_definition(L, i);
467 lua_setfield(L, -2, i.name.c_str());
470 void ScriptApiClient::setEnv(ClientEnvironment *env)
472 ScriptApiBase::setEnv(env);