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 s16 ScriptApiPlayer::on_player_hpchange(ServerActiveObject *player,
81 s16 hp_change, const PlayerHPChangeReason &reason)
83 SCRIPTAPI_PRECHECKHEADER
85 int error_handler = PUSH_ERROR_HANDLER(L);
87 // Get core.registered_on_player_hpchange
88 lua_getglobal(L, "core");
89 lua_getfield(L, -1, "registered_on_player_hpchange");
93 objectrefGetOrCreate(L, player);
94 lua_pushnumber(L, hp_change);
95 pushPlayerHPChangeReason(L, reason);
98 PCALL_RES(lua_pcall(L, 3, 1, error_handler));
99 hp_change = lua_tointeger(L, -1);
100 lua_pop(L, 2); // Pop result and error handler
104 bool ScriptApiPlayer::on_respawnplayer(ServerActiveObject *player)
106 SCRIPTAPI_PRECHECKHEADER
108 // Get core.registered_on_respawnplayers
109 lua_getglobal(L, "core");
110 lua_getfield(L, -1, "registered_on_respawnplayers");
112 objectrefGetOrCreate(L, player);
113 runCallbacks(1, RUN_CALLBACKS_MODE_OR);
114 return readParam<bool>(L, -1);
117 bool ScriptApiPlayer::on_prejoinplayer(
118 const std::string &name,
119 const std::string &ip,
122 SCRIPTAPI_PRECHECKHEADER
124 // Get core.registered_on_prejoinplayers
125 lua_getglobal(L, "core");
126 lua_getfield(L, -1, "registered_on_prejoinplayers");
127 lua_pushstring(L, name.c_str());
128 lua_pushstring(L, ip.c_str());
129 runCallbacks(2, RUN_CALLBACKS_MODE_OR);
130 if (lua_isstring(L, -1)) {
131 reason->assign(readParam<std::string>(L, -1));
137 bool ScriptApiPlayer::can_bypass_userlimit(const std::string &name, const std::string &ip)
139 SCRIPTAPI_PRECHECKHEADER
141 // Get core.registered_on_prejoinplayers
142 lua_getglobal(L, "core");
143 lua_getfield(L, -1, "registered_can_bypass_userlimit");
144 lua_pushstring(L, name.c_str());
145 lua_pushstring(L, ip.c_str());
146 runCallbacks(2, RUN_CALLBACKS_MODE_OR);
147 return lua_toboolean(L, -1);
150 void ScriptApiPlayer::on_joinplayer(ServerActiveObject *player)
152 SCRIPTAPI_PRECHECKHEADER
154 // Get core.registered_on_joinplayers
155 lua_getglobal(L, "core");
156 lua_getfield(L, -1, "registered_on_joinplayers");
158 objectrefGetOrCreate(L, player);
159 runCallbacks(1, RUN_CALLBACKS_MODE_FIRST);
162 void ScriptApiPlayer::on_leaveplayer(ServerActiveObject *player,
165 SCRIPTAPI_PRECHECKHEADER
167 // Get core.registered_on_leaveplayers
168 lua_getglobal(L, "core");
169 lua_getfield(L, -1, "registered_on_leaveplayers");
171 objectrefGetOrCreate(L, player);
172 lua_pushboolean(L, timeout);
173 runCallbacks(2, RUN_CALLBACKS_MODE_FIRST);
176 void ScriptApiPlayer::on_cheat(ServerActiveObject *player,
177 const std::string &cheat_type)
179 SCRIPTAPI_PRECHECKHEADER
181 // Get core.registered_on_cheats
182 lua_getglobal(L, "core");
183 lua_getfield(L, -1, "registered_on_cheats");
185 objectrefGetOrCreate(L, player);
187 lua_pushlstring(L, cheat_type.c_str(), cheat_type.size());
188 lua_setfield(L, -2, "type");
189 runCallbacks(2, RUN_CALLBACKS_MODE_FIRST);
192 void ScriptApiPlayer::on_playerReceiveFields(ServerActiveObject *player,
193 const std::string &formname,
194 const StringMap &fields)
196 SCRIPTAPI_PRECHECKHEADER
198 // Get core.registered_on_chat_messages
199 lua_getglobal(L, "core");
200 lua_getfield(L, -1, "registered_on_player_receive_fields");
203 objectrefGetOrCreate(L, player);
205 lua_pushstring(L, formname.c_str());
208 StringMap::const_iterator it;
209 for (it = fields.begin(); it != fields.end(); ++it) {
210 const std::string &name = it->first;
211 const std::string &value = it->second;
212 lua_pushstring(L, name.c_str());
213 lua_pushlstring(L, value.c_str(), value.size());
216 runCallbacks(3, RUN_CALLBACKS_MODE_OR_SC);
219 void ScriptApiPlayer::on_auth_failure(const std::string &name, const std::string &ip)
221 SCRIPTAPI_PRECHECKHEADER
223 // Get core.registered_on_auth_failure
224 lua_getglobal(L, "core");
225 lua_getfield(L, -1, "registered_on_auth_fail");
226 lua_pushstring(L, name.c_str());
227 lua_pushstring(L, ip.c_str());
228 runCallbacks(2, RUN_CALLBACKS_MODE_FIRST);
231 void ScriptApiPlayer::pushMoveArguments(
232 const MoveAction &ma, int count,
233 ServerActiveObject *player)
235 lua_State *L = getStack();
236 objectrefGetOrCreate(L, player); // player
237 lua_pushstring(L, "move"); // action
238 InvRef::create(L, ma.from_inv); // inventory
241 // Table containing the action information
242 lua_pushstring(L, ma.from_list.c_str());
243 lua_setfield(L, -2, "from_list");
244 lua_pushstring(L, ma.to_list.c_str());
245 lua_setfield(L, -2, "to_list");
247 lua_pushinteger(L, ma.from_i + 1);
248 lua_setfield(L, -2, "from_index");
249 lua_pushinteger(L, ma.to_i + 1);
250 lua_setfield(L, -2, "to_index");
252 lua_pushinteger(L, count);
253 lua_setfield(L, -2, "count");
257 void ScriptApiPlayer::pushPutTakeArguments(
258 const char *method, const InventoryLocation &loc,
259 const std::string &listname, int index, const ItemStack &stack,
260 ServerActiveObject *player)
262 lua_State *L = getStack();
263 objectrefGetOrCreate(L, player); // player
264 lua_pushstring(L, method); // action
265 InvRef::create(L, loc); // inventory
268 // Table containing the action information
269 lua_pushstring(L, listname.c_str());
270 lua_setfield(L, -2, "listname");
272 lua_pushinteger(L, index + 1);
273 lua_setfield(L, -2, "index");
275 LuaItemStack::create(L, stack);
276 lua_setfield(L, -2, "stack");
280 // Return number of accepted items to be moved
281 int ScriptApiPlayer::player_inventory_AllowMove(
282 const MoveAction &ma, int count,
283 ServerActiveObject *player)
285 SCRIPTAPI_PRECHECKHEADER
287 lua_getglobal(L, "core");
288 lua_getfield(L, -1, "registered_allow_player_inventory_actions");
289 pushMoveArguments(ma, count, player);
290 runCallbacks(4, RUN_CALLBACKS_MODE_OR_SC);
292 return lua_type(L, -1) == LUA_TNUMBER ? lua_tonumber(L, -1) : count;
295 // Return number of accepted items to be put
296 int ScriptApiPlayer::player_inventory_AllowPut(
297 const MoveAction &ma, const ItemStack &stack,
298 ServerActiveObject *player)
300 SCRIPTAPI_PRECHECKHEADER
302 lua_getglobal(L, "core");
303 lua_getfield(L, -1, "registered_allow_player_inventory_actions");
304 pushPutTakeArguments("put", ma.to_inv, ma.to_list, ma.to_i, stack, player);
305 runCallbacks(4, RUN_CALLBACKS_MODE_OR_SC);
307 return lua_type(L, -1) == LUA_TNUMBER ? lua_tonumber(L, -1) : stack.count;
310 // Return number of accepted items to be taken
311 int ScriptApiPlayer::player_inventory_AllowTake(
312 const MoveAction &ma, const ItemStack &stack,
313 ServerActiveObject *player)
315 SCRIPTAPI_PRECHECKHEADER
317 lua_getglobal(L, "core");
318 lua_getfield(L, -1, "registered_allow_player_inventory_actions");
319 pushPutTakeArguments("take", ma.from_inv, ma.from_list, ma.from_i, stack, player);
320 runCallbacks(4, RUN_CALLBACKS_MODE_OR_SC);
322 return lua_type(L, -1) == LUA_TNUMBER ? lua_tonumber(L, -1) : stack.count;
325 // Report moved items
326 void ScriptApiPlayer::player_inventory_OnMove(
327 const MoveAction &ma, int count,
328 ServerActiveObject *player)
330 SCRIPTAPI_PRECHECKHEADER
332 lua_getglobal(L, "core");
333 lua_getfield(L, -1, "registered_on_player_inventory_actions");
334 pushMoveArguments(ma, count, player);
335 runCallbacks(4, RUN_CALLBACKS_MODE_FIRST);
339 void ScriptApiPlayer::player_inventory_OnPut(
340 const MoveAction &ma, const ItemStack &stack,
341 ServerActiveObject *player)
343 SCRIPTAPI_PRECHECKHEADER
345 lua_getglobal(L, "core");
346 lua_getfield(L, -1, "registered_on_player_inventory_actions");
347 pushPutTakeArguments("put", ma.to_inv, ma.to_list, ma.to_i, stack, player);
348 runCallbacks(4, RUN_CALLBACKS_MODE_FIRST);
351 // Report taken items
352 void ScriptApiPlayer::player_inventory_OnTake(
353 const MoveAction &ma, const ItemStack &stack,
354 ServerActiveObject *player)
356 SCRIPTAPI_PRECHECKHEADER
358 lua_getglobal(L, "core");
359 lua_getfield(L, -1, "registered_on_player_inventory_actions");
360 pushPutTakeArguments("take", ma.from_inv, ma.from_list, ma.from_i, stack, player);
361 runCallbacks(4, RUN_CALLBACKS_MODE_FIRST);