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.
22 #include "s_internal.h"
23 #include "client/client.h"
24 #include "common/c_converter.h"
25 #include "common/c_content.h"
28 void ScriptApiClient::on_mods_loaded()
30 SCRIPTAPI_PRECHECKHEADER
32 // Get registered shutdown hooks
33 lua_getglobal(L, "core");
34 lua_getfield(L, -1, "registered_on_mods_loaded");
36 runCallbacks(0, RUN_CALLBACKS_MODE_FIRST);
39 void ScriptApiClient::on_shutdown()
41 SCRIPTAPI_PRECHECKHEADER
43 // Get registered shutdown hooks
44 lua_getglobal(L, "core");
45 lua_getfield(L, -1, "registered_on_shutdown");
47 runCallbacks(0, RUN_CALLBACKS_MODE_FIRST);
50 bool ScriptApiClient::on_sending_message(const std::string &message)
52 SCRIPTAPI_PRECHECKHEADER
54 // Get core.registered_on_chat_messages
55 lua_getglobal(L, "core");
56 lua_getfield(L, -1, "registered_on_sending_chat_message");
58 lua_pushstring(L, message.c_str());
59 runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC);
60 return readParam<bool>(L, -1);
63 bool ScriptApiClient::on_receiving_message(const std::string &message)
65 SCRIPTAPI_PRECHECKHEADER
67 // Get core.registered_on_chat_messages
68 lua_getglobal(L, "core");
69 lua_getfield(L, -1, "registered_on_receiving_chat_message");
71 lua_pushstring(L, message.c_str());
72 runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC);
73 return readParam<bool>(L, -1);
76 void ScriptApiClient::on_damage_taken(int32_t damage_amount)
78 SCRIPTAPI_PRECHECKHEADER
80 // Get core.registered_on_chat_messages
81 lua_getglobal(L, "core");
82 lua_getfield(L, -1, "registered_on_damage_taken");
84 lua_pushinteger(L, damage_amount);
85 runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC);
88 void ScriptApiClient::on_hp_modification(int32_t newhp)
90 SCRIPTAPI_PRECHECKHEADER
92 // Get core.registered_on_chat_messages
93 lua_getglobal(L, "core");
94 lua_getfield(L, -1, "registered_on_hp_modification");
96 lua_pushinteger(L, newhp);
97 runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC);
100 void ScriptApiClient::on_death()
102 SCRIPTAPI_PRECHECKHEADER
104 // Get registered shutdown hooks
105 lua_getglobal(L, "core");
106 lua_getfield(L, -1, "registered_on_death");
108 runCallbacks(0, RUN_CALLBACKS_MODE_FIRST);
111 void ScriptApiClient::environment_step(float dtime)
113 SCRIPTAPI_PRECHECKHEADER
115 // Get core.registered_globalsteps
116 lua_getglobal(L, "core");
117 lua_getfield(L, -1, "registered_globalsteps");
119 lua_pushnumber(L, dtime);
121 runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
122 } catch (LuaError &e) {
123 getClient()->setFatalError(std::string("Client environment_step: ") + e.what() + "\n"
124 + script_get_backtrace(L));
128 void ScriptApiClient::on_formspec_input(const std::string &formname,
129 const StringMap &fields)
131 SCRIPTAPI_PRECHECKHEADER
133 // Get core.registered_on_chat_messages
134 lua_getglobal(L, "core");
135 lua_getfield(L, -1, "registered_on_formspec_input");
138 lua_pushstring(L, formname.c_str());
141 StringMap::const_iterator it;
142 for (it = fields.begin(); it != fields.end(); ++it) {
143 const std::string &name = it->first;
144 const std::string &value = it->second;
145 lua_pushstring(L, name.c_str());
146 lua_pushlstring(L, value.c_str(), value.size());
149 runCallbacks(2, RUN_CALLBACKS_MODE_OR_SC);
152 bool ScriptApiClient::on_dignode(v3s16 p, MapNode node)
154 SCRIPTAPI_PRECHECKHEADER
156 const NodeDefManager *ndef = getClient()->ndef();
158 // Get core.registered_on_dignode
159 lua_getglobal(L, "core");
160 lua_getfield(L, -1, "registered_on_dignode");
164 pushnode(L, node, ndef);
167 runCallbacks(2, RUN_CALLBACKS_MODE_OR);
168 return lua_toboolean(L, -1);
171 bool ScriptApiClient::on_punchnode(v3s16 p, MapNode node)
173 SCRIPTAPI_PRECHECKHEADER
175 const NodeDefManager *ndef = getClient()->ndef();
177 // Get core.registered_on_punchgnode
178 lua_getglobal(L, "core");
179 lua_getfield(L, -1, "registered_on_punchnode");
183 pushnode(L, node, ndef);
186 runCallbacks(2, RUN_CALLBACKS_MODE_OR);
187 return readParam<bool>(L, -1);
190 bool ScriptApiClient::on_placenode(const PointedThing &pointed, const ItemDefinition &item)
192 SCRIPTAPI_PRECHECKHEADER
194 // Get core.registered_on_placenode
195 lua_getglobal(L, "core");
196 lua_getfield(L, -1, "registered_on_placenode");
199 push_pointed_thing(L, pointed, true);
200 push_item_definition(L, item);
203 runCallbacks(2, RUN_CALLBACKS_MODE_OR);
204 return readParam<bool>(L, -1);
207 bool ScriptApiClient::on_item_use(const ItemStack &item, const PointedThing &pointed)
209 SCRIPTAPI_PRECHECKHEADER
211 // Get core.registered_on_item_use
212 lua_getglobal(L, "core");
213 lua_getfield(L, -1, "registered_on_item_use");
216 LuaItemStack::create(L, item);
217 push_pointed_thing(L, pointed, true);
220 runCallbacks(2, RUN_CALLBACKS_MODE_OR);
221 return readParam<bool>(L, -1);
224 bool ScriptApiClient::on_recieve_physics_override(float speed, float jump, float gravity, bool sneak, bool sneak_glitch, bool new_move)
226 SCRIPTAPI_PRECHECKHEADER
228 // Get core.registered_on_recieve_physics_override
229 lua_getglobal(L, "core");
230 lua_getfield(L, -1, "registered_on_recieve_physics_override");
233 push_physics_override(L, speed, jump, gravity, sneak, sneak_glitch, new_move);
236 runCallbacks(1, RUN_CALLBACKS_MODE_OR);
237 return readParam<bool>(L, -1);
240 bool ScriptApiClient::on_play_sound(SimpleSoundSpec spec)
242 SCRIPTAPI_PRECHECKHEADER
244 // Get core.registered_on_play_sound
245 lua_getglobal(L, "core");
246 lua_getfield(L, -1, "registered_on_play_sound");
249 push_soundspec(L, spec);
252 runCallbacks(1, RUN_CALLBACKS_MODE_OR);
253 return readParam<bool>(L, -1);
256 bool ScriptApiClient::on_spawn_particle(struct ParticleParameters param)
258 SCRIPTAPI_PRECHECKHEADER
260 // Get core.registered_on_play_sound
262 lua_getglobal(L, "core");
263 lua_getfield(L, -1, "registered_on_spawn_particle");
267 push_v3f(L, param.pos);
268 lua_setfield(L, -2, "pos");
269 push_v3f(L, param.vel);
270 lua_setfield(L, -2, "velocity");
271 push_v3f(L, param.acc);
272 lua_setfield(L, -2, "acceleration");
273 setfloatfield(L, -1, "expirationtime", param.expirationtime);
274 setboolfield(L, -1, "collisiondetection", param.collisiondetection);
275 setboolfield(L, -1, "collision_removal", param.collision_removal);
276 setboolfield(L, -1, "object_collision", param.object_collision);
277 setboolfield(L, -1, "vertical", param.vertical);
278 push_animation_definition(L, param.animation);
279 lua_setfield(L, -2, "animation");
280 setstringfield(L, -1, "texture", param.texture);
281 setintfield(L, -1, "glow", param.glow);
282 if (param.node.getContent() != CONTENT_IGNORE) {
283 pushnode(L, param.node, getGameDef()->ndef());
284 lua_setfield(L, -2, "node");
286 setintfield(L, -1, "node_tile", param.node_tile);
289 runCallbacks(1, RUN_CALLBACKS_MODE_OR);
290 return readParam<bool>(L, -1);
293 bool ScriptApiClient::on_inventory_open(Inventory *inventory)
295 SCRIPTAPI_PRECHECKHEADER
297 lua_getglobal(L, "core");
298 lua_getfield(L, -1, "registered_on_inventory_open");
300 push_inventory(L, inventory);
302 runCallbacks(1, RUN_CALLBACKS_MODE_OR);
303 return readParam<bool>(L, -1);
306 void ScriptApiClient::open_enderchest()
308 SCRIPTAPI_PRECHECKHEADER
310 PUSH_ERROR_HANDLER(L);
311 int error_handler = lua_gettop(L) - 1;
312 lua_insert(L, error_handler);
314 lua_getglobal(L, "core");
315 lua_getfield(L, -1, "open_enderchest");
316 if (lua_isfunction(L, -1))
317 lua_pcall(L, 0, 0, error_handler);
320 void ScriptApiClient::setEnv(ClientEnvironment *env)
322 ScriptApiBase::setEnv(env);