3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
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.
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.
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.
20 #include "cpp_api/s_player.h"
21 #include "cpp_api/s_internal.h"
22 #include "common/c_converter.h"
23 #include "common/c_content.h"
25 #include "inventorymanager.h"
26 #include "lua_api/l_inventory.h"
27 #include "lua_api/l_item.h"
28 #include "util/string.h"
30 void ScriptApiPlayer::on_newplayer(ServerActiveObject *player)
32 SCRIPTAPI_PRECHECKHEADER
34 // Get core.registered_on_newplayers
35 lua_getglobal(L, "core");
36 lua_getfield(L, -1, "registered_on_newplayers");
38 objectrefGetOrCreate(L, player);
39 runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
42 void ScriptApiPlayer::on_dieplayer(ServerActiveObject *player, const PlayerHPChangeReason &reason)
44 SCRIPTAPI_PRECHECKHEADER
47 lua_getglobal(L, "core");
48 lua_getfield(L, -1, "registered_on_dieplayers");
51 objectrefGetOrCreate(L, player);
52 pushPlayerHPChangeReason(L, reason);
55 runCallbacks(2, RUN_CALLBACKS_MODE_FIRST);
58 bool ScriptApiPlayer::on_punchplayer(ServerActiveObject *player,
59 ServerActiveObject *hitter,
60 float time_from_last_punch,
61 const ToolCapabilities *toolcap,
65 SCRIPTAPI_PRECHECKHEADER
66 // Get core.registered_on_punchplayers
67 lua_getglobal(L, "core");
68 lua_getfield(L, -1, "registered_on_punchplayers");
70 objectrefGetOrCreate(L, player);
71 objectrefGetOrCreate(L, hitter);
72 lua_pushnumber(L, time_from_last_punch);
73 push_tool_capabilities(L, *toolcap);
75 lua_pushnumber(L, damage);
76 runCallbacks(6, RUN_CALLBACKS_MODE_OR);
77 return readParam<bool>(L, -1);
80 void ScriptApiPlayer::on_rightclickplayer(ServerActiveObject *player,
81 ServerActiveObject *clicker)
83 SCRIPTAPI_PRECHECKHEADER
84 // Get core.registered_on_rightclickplayers
85 lua_getglobal(L, "core");
86 lua_getfield(L, -1, "registered_on_rightclickplayers");
88 objectrefGetOrCreate(L, player);
89 objectrefGetOrCreate(L, clicker);
90 runCallbacks(2, RUN_CALLBACKS_MODE_FIRST);
93 s32 ScriptApiPlayer::on_player_hpchange(ServerActiveObject *player,
94 s32 hp_change, const PlayerHPChangeReason &reason)
96 SCRIPTAPI_PRECHECKHEADER
98 int error_handler = PUSH_ERROR_HANDLER(L);
100 // Get core.registered_on_player_hpchange
101 lua_getglobal(L, "core");
102 lua_getfield(L, -1, "registered_on_player_hpchange");
106 objectrefGetOrCreate(L, player);
107 lua_pushnumber(L, hp_change);
108 pushPlayerHPChangeReason(L, reason);
111 PCALL_RES(lua_pcall(L, 3, 1, error_handler));
112 hp_change = lua_tointeger(L, -1);
113 lua_pop(L, 2); // Pop result and error handler
117 bool ScriptApiPlayer::on_respawnplayer(ServerActiveObject *player)
119 SCRIPTAPI_PRECHECKHEADER
121 // Get core.registered_on_respawnplayers
122 lua_getglobal(L, "core");
123 lua_getfield(L, -1, "registered_on_respawnplayers");
125 objectrefGetOrCreate(L, player);
126 runCallbacks(1, RUN_CALLBACKS_MODE_OR);
127 return readParam<bool>(L, -1);
130 bool ScriptApiPlayer::on_prejoinplayer(
131 const std::string &name,
132 const std::string &ip,
135 SCRIPTAPI_PRECHECKHEADER
137 // Get core.registered_on_prejoinplayers
138 lua_getglobal(L, "core");
139 lua_getfield(L, -1, "registered_on_prejoinplayers");
140 lua_pushstring(L, name.c_str());
141 lua_pushstring(L, ip.c_str());
142 runCallbacks(2, RUN_CALLBACKS_MODE_OR);
143 if (lua_isstring(L, -1)) {
144 reason->assign(readParam<std::string>(L, -1));
150 bool ScriptApiPlayer::can_bypass_userlimit(const std::string &name, const std::string &ip)
152 SCRIPTAPI_PRECHECKHEADER
154 // Get core.registered_on_prejoinplayers
155 lua_getglobal(L, "core");
156 lua_getfield(L, -1, "registered_can_bypass_userlimit");
157 lua_pushstring(L, name.c_str());
158 lua_pushstring(L, ip.c_str());
159 runCallbacks(2, RUN_CALLBACKS_MODE_OR);
160 return lua_toboolean(L, -1);
163 void ScriptApiPlayer::on_joinplayer(ServerActiveObject *player, s64 last_login)
165 SCRIPTAPI_PRECHECKHEADER
167 // Get core.registered_on_joinplayers
168 lua_getglobal(L, "core");
169 lua_getfield(L, -1, "registered_on_joinplayers");
171 objectrefGetOrCreate(L, player);
172 if (last_login != -1)
173 lua_pushinteger(L, last_login);
176 runCallbacks(2, RUN_CALLBACKS_MODE_FIRST);
179 void ScriptApiPlayer::on_leaveplayer(ServerActiveObject *player,
182 SCRIPTAPI_PRECHECKHEADER
184 // Get core.registered_on_leaveplayers
185 lua_getglobal(L, "core");
186 lua_getfield(L, -1, "registered_on_leaveplayers");
188 objectrefGetOrCreate(L, player);
189 lua_pushboolean(L, timeout);
190 runCallbacks(2, RUN_CALLBACKS_MODE_FIRST);
193 void ScriptApiPlayer::on_cheat(ServerActiveObject *player,
194 const std::string &cheat_type)
196 SCRIPTAPI_PRECHECKHEADER
198 // Get core.registered_on_cheats
199 lua_getglobal(L, "core");
200 lua_getfield(L, -1, "registered_on_cheats");
202 objectrefGetOrCreate(L, player);
204 lua_pushlstring(L, cheat_type.c_str(), cheat_type.size());
205 lua_setfield(L, -2, "type");
206 runCallbacks(2, RUN_CALLBACKS_MODE_FIRST);
209 void ScriptApiPlayer::on_playerReceiveFields(ServerActiveObject *player,
210 const std::string &formname,
211 const StringMap &fields)
213 SCRIPTAPI_PRECHECKHEADER
215 // Get core.registered_on_player_receive_fields
216 lua_getglobal(L, "core");
217 lua_getfield(L, -1, "registered_on_player_receive_fields");
220 objectrefGetOrCreate(L, player);
222 lua_pushstring(L, formname.c_str());
225 StringMap::const_iterator it;
226 for (it = fields.begin(); it != fields.end(); ++it) {
227 const std::string &name = it->first;
228 const std::string &value = it->second;
229 lua_pushstring(L, name.c_str());
230 lua_pushlstring(L, value.c_str(), value.size());
233 runCallbacks(3, RUN_CALLBACKS_MODE_OR_SC);
236 void ScriptApiPlayer::on_authplayer(const std::string &name, const std::string &ip, bool is_success)
238 SCRIPTAPI_PRECHECKHEADER
240 // Get core.registered_on_authplayers
241 lua_getglobal(L, "core");
242 lua_getfield(L, -1, "registered_on_authplayers");
245 lua_pushstring(L, name.c_str());
246 lua_pushstring(L, ip.c_str());
247 lua_pushboolean(L, is_success);
248 runCallbacks(3, RUN_CALLBACKS_MODE_FIRST);
251 void ScriptApiPlayer::pushMoveArguments(
252 const MoveAction &ma, int count,
253 ServerActiveObject *player)
255 lua_State *L = getStack();
256 objectrefGetOrCreate(L, player); // player
257 lua_pushstring(L, "move"); // action
258 InvRef::create(L, ma.from_inv); // inventory
261 // Table containing the action information
262 lua_pushstring(L, ma.from_list.c_str());
263 lua_setfield(L, -2, "from_list");
264 lua_pushstring(L, ma.to_list.c_str());
265 lua_setfield(L, -2, "to_list");
267 lua_pushinteger(L, ma.from_i + 1);
268 lua_setfield(L, -2, "from_index");
269 lua_pushinteger(L, ma.to_i + 1);
270 lua_setfield(L, -2, "to_index");
272 lua_pushinteger(L, count);
273 lua_setfield(L, -2, "count");
277 void ScriptApiPlayer::pushPutTakeArguments(
278 const char *method, const InventoryLocation &loc,
279 const std::string &listname, int index, const ItemStack &stack,
280 ServerActiveObject *player)
282 lua_State *L = getStack();
283 objectrefGetOrCreate(L, player); // player
284 lua_pushstring(L, method); // action
285 InvRef::create(L, loc); // inventory
288 // Table containing the action information
289 lua_pushstring(L, listname.c_str());
290 lua_setfield(L, -2, "listname");
292 lua_pushinteger(L, index + 1);
293 lua_setfield(L, -2, "index");
295 LuaItemStack::create(L, stack);
296 lua_setfield(L, -2, "stack");
300 // Return number of accepted items to be moved
301 int ScriptApiPlayer::player_inventory_AllowMove(
302 const MoveAction &ma, int count,
303 ServerActiveObject *player)
305 SCRIPTAPI_PRECHECKHEADER
307 lua_getglobal(L, "core");
308 lua_getfield(L, -1, "registered_allow_player_inventory_actions");
309 pushMoveArguments(ma, count, player);
310 runCallbacks(4, RUN_CALLBACKS_MODE_OR_SC);
312 return lua_type(L, -1) == LUA_TNUMBER ? lua_tonumber(L, -1) : count;
315 // Return number of accepted items to be put
316 int ScriptApiPlayer::player_inventory_AllowPut(
317 const MoveAction &ma, const ItemStack &stack,
318 ServerActiveObject *player)
320 SCRIPTAPI_PRECHECKHEADER
322 lua_getglobal(L, "core");
323 lua_getfield(L, -1, "registered_allow_player_inventory_actions");
324 pushPutTakeArguments("put", ma.to_inv, ma.to_list, ma.to_i, stack, player);
325 runCallbacks(4, RUN_CALLBACKS_MODE_OR_SC);
327 return lua_type(L, -1) == LUA_TNUMBER ? lua_tonumber(L, -1) : stack.count;
330 // Return number of accepted items to be taken
331 int ScriptApiPlayer::player_inventory_AllowTake(
332 const MoveAction &ma, const ItemStack &stack,
333 ServerActiveObject *player)
335 SCRIPTAPI_PRECHECKHEADER
337 lua_getglobal(L, "core");
338 lua_getfield(L, -1, "registered_allow_player_inventory_actions");
339 pushPutTakeArguments("take", ma.from_inv, ma.from_list, ma.from_i, stack, player);
340 runCallbacks(4, RUN_CALLBACKS_MODE_OR_SC);
342 return lua_type(L, -1) == LUA_TNUMBER ? lua_tonumber(L, -1) : stack.count;
345 // Report moved items
346 void ScriptApiPlayer::player_inventory_OnMove(
347 const MoveAction &ma, int count,
348 ServerActiveObject *player)
350 SCRIPTAPI_PRECHECKHEADER
352 lua_getglobal(L, "core");
353 lua_getfield(L, -1, "registered_on_player_inventory_actions");
354 pushMoveArguments(ma, count, player);
355 runCallbacks(4, RUN_CALLBACKS_MODE_FIRST);
359 void ScriptApiPlayer::player_inventory_OnPut(
360 const MoveAction &ma, const ItemStack &stack,
361 ServerActiveObject *player)
363 SCRIPTAPI_PRECHECKHEADER
365 lua_getglobal(L, "core");
366 lua_getfield(L, -1, "registered_on_player_inventory_actions");
367 pushPutTakeArguments("put", ma.to_inv, ma.to_list, ma.to_i, stack, player);
368 runCallbacks(4, RUN_CALLBACKS_MODE_FIRST);
371 // Report taken items
372 void ScriptApiPlayer::player_inventory_OnTake(
373 const MoveAction &ma, const ItemStack &stack,
374 ServerActiveObject *player)
376 SCRIPTAPI_PRECHECKHEADER
378 lua_getglobal(L, "core");
379 lua_getfield(L, -1, "registered_on_player_inventory_actions");
380 pushPutTakeArguments("take", ma.from_inv, ma.from_list, ma.from_i, stack, player);
381 runCallbacks(4, RUN_CALLBACKS_MODE_FIRST);