Spawn level: Add 'get_spawn_level(x, z)' API
[oweals/minetest.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 "s_client.h"
22 #include "s_internal.h"
23 #include "client.h"
24 #include "common/c_converter.h"
25 #include "common/c_content.h"
26 #include "s_item.h"
27
28 void ScriptApiClient::on_shutdown()
29 {
30         SCRIPTAPI_PRECHECKHEADER
31
32         // Get registered shutdown hooks
33         lua_getglobal(L, "core");
34         lua_getfield(L, -1, "registered_on_shutdown");
35         // Call callbacks
36         runCallbacks(0, RUN_CALLBACKS_MODE_FIRST);
37 }
38
39 bool ScriptApiClient::on_sending_message(const std::string &message)
40 {
41         SCRIPTAPI_PRECHECKHEADER
42
43         // Get core.registered_on_chat_messages
44         lua_getglobal(L, "core");
45         lua_getfield(L, -1, "registered_on_sending_chat_message");
46         // Call callbacks
47         lua_pushstring(L, message.c_str());
48         runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC);
49         bool ate = lua_toboolean(L, -1);
50         return ate;
51 }
52
53 bool ScriptApiClient::on_receiving_message(const std::string &message)
54 {
55         SCRIPTAPI_PRECHECKHEADER
56
57         // Get core.registered_on_chat_messages
58         lua_getglobal(L, "core");
59         lua_getfield(L, -1, "registered_on_receiving_chat_message");
60         // Call callbacks
61         lua_pushstring(L, message.c_str());
62         runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC);
63         bool ate = lua_toboolean(L, -1);
64         return ate;
65 }
66
67 void ScriptApiClient::on_damage_taken(int32_t damage_amount)
68 {
69         SCRIPTAPI_PRECHECKHEADER
70
71         // Get core.registered_on_chat_messages
72         lua_getglobal(L, "core");
73         lua_getfield(L, -1, "registered_on_damage_taken");
74         // Call callbacks
75         lua_pushinteger(L, damage_amount);
76         runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC);
77 }
78
79 void ScriptApiClient::on_hp_modification(int32_t newhp)
80 {
81         SCRIPTAPI_PRECHECKHEADER
82
83         // Get core.registered_on_chat_messages
84         lua_getglobal(L, "core");
85         lua_getfield(L, -1, "registered_on_hp_modification");
86         // Call callbacks
87         lua_pushinteger(L, newhp);
88         runCallbacks(1, RUN_CALLBACKS_MODE_OR_SC);
89 }
90
91 void ScriptApiClient::on_death()
92 {
93         SCRIPTAPI_PRECHECKHEADER
94
95         // Get registered shutdown hooks
96         lua_getglobal(L, "core");
97         lua_getfield(L, -1, "registered_on_death");
98         // Call callbacks
99         runCallbacks(0, RUN_CALLBACKS_MODE_FIRST);
100 }
101
102 void ScriptApiClient::environment_step(float dtime)
103 {
104         SCRIPTAPI_PRECHECKHEADER
105
106         // Get core.registered_globalsteps
107         lua_getglobal(L, "core");
108         lua_getfield(L, -1, "registered_globalsteps");
109         // Call callbacks
110         lua_pushnumber(L, dtime);
111         try {
112                 runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
113         } catch (LuaError &e) {
114                 getClient()->setFatalError(std::string("Client environment_step: ") + e.what() + "\n"
115                                 + script_get_backtrace(L));
116         }
117 }
118
119 void ScriptApiClient::on_formspec_input(const std::string &formname,
120         const StringMap &fields)
121 {
122         SCRIPTAPI_PRECHECKHEADER
123
124         // Get core.registered_on_chat_messages
125         lua_getglobal(L, "core");
126         lua_getfield(L, -1, "registered_on_formspec_input");
127         // Call callbacks
128         // param 1
129         lua_pushstring(L, formname.c_str());
130         // param 2
131         lua_newtable(L);
132         StringMap::const_iterator it;
133         for (it = fields.begin(); it != fields.end(); ++it) {
134                 const std::string &name = it->first;
135                 const std::string &value = it->second;
136                 lua_pushstring(L, name.c_str());
137                 lua_pushlstring(L, value.c_str(), value.size());
138                 lua_settable(L, -3);
139         }
140         runCallbacks(2, RUN_CALLBACKS_MODE_OR_SC);
141 }
142
143 bool ScriptApiClient::on_dignode(v3s16 p, MapNode node)
144 {
145         SCRIPTAPI_PRECHECKHEADER
146
147         const NodeDefManager *ndef = getClient()->ndef();
148
149         // Get core.registered_on_dignode
150         lua_getglobal(L, "core");
151         lua_getfield(L, -1, "registered_on_dignode");
152
153         // Push data
154         push_v3s16(L, p);
155         pushnode(L, node, ndef);
156
157         // Call functions
158         runCallbacks(2, RUN_CALLBACKS_MODE_OR);
159         return lua_toboolean(L, -1);
160 }
161
162 bool ScriptApiClient::on_punchnode(v3s16 p, MapNode node)
163 {
164         SCRIPTAPI_PRECHECKHEADER
165
166         const NodeDefManager *ndef = getClient()->ndef();
167
168         // Get core.registered_on_punchgnode
169         lua_getglobal(L, "core");
170         lua_getfield(L, -1, "registered_on_punchnode");
171
172         // Push data
173         push_v3s16(L, p);
174         pushnode(L, node, ndef);
175
176         // Call functions
177         runCallbacks(2, RUN_CALLBACKS_MODE_OR);
178         bool blocked = lua_toboolean(L, -1);
179         return blocked;
180 }
181
182 bool ScriptApiClient::on_placenode(const PointedThing &pointed, const ItemDefinition &item)
183 {
184         SCRIPTAPI_PRECHECKHEADER
185
186         // Get core.registered_on_placenode
187         lua_getglobal(L, "core");
188         lua_getfield(L, -1, "registered_on_placenode");
189
190         // Push data
191         push_pointed_thing(L, pointed, true);
192         push_item_definition(L, item);
193
194         // Call functions
195         runCallbacks(2, RUN_CALLBACKS_MODE_OR);
196         return lua_toboolean(L, -1);
197 }
198
199 bool ScriptApiClient::on_item_use(const ItemStack &item, const PointedThing &pointed)
200 {
201         SCRIPTAPI_PRECHECKHEADER
202
203         // Get core.registered_on_item_use
204         lua_getglobal(L, "core");
205         lua_getfield(L, -1, "registered_on_item_use");
206
207         // Push data
208         LuaItemStack::create(L, item);
209         push_pointed_thing(L, pointed, true);
210
211         // Call functions
212         runCallbacks(2, RUN_CALLBACKS_MODE_OR);
213         return lua_toboolean(L, -1);
214 }
215
216 bool ScriptApiClient::on_inventory_open(Inventory *inventory)
217 {
218         SCRIPTAPI_PRECHECKHEADER
219
220         lua_getglobal(L, "core");
221         lua_getfield(L, -1, "registered_on_inventory_open");
222
223         std::vector<const InventoryList*> lists = inventory->getLists();
224         std::vector<const InventoryList*>::iterator iter = lists.begin();
225         lua_createtable(L, 0, lists.size());
226         for (; iter != lists.end(); iter++) {
227                 const char* name = (*iter)->getName().c_str();
228                 lua_pushstring(L, name);
229                 push_inventory_list(L, inventory, name);
230                 lua_rawset(L, -3);
231         }
232
233         runCallbacks(1, RUN_CALLBACKS_MODE_OR);
234         return lua_toboolean(L, -1);
235 }
236
237 void ScriptApiClient::setEnv(ClientEnvironment *env)
238 {
239         ScriptApiBase::setEnv(env);
240 }