Merge branch 'master' of git://github.com/BTAxis/naev into testmission
[naev.git] / src / nlua_hook.c
blob9b231f8c67a8e23901a55e379c243adabdb7aac8
1 /*
2 * See Licensing and Copyright notice in naev.h
3 */
5 /**
6 * @file nlua_hook.c
8 * @brief Lua hook module.
9 */
12 #include "nlua_hook.h"
14 #include "naev.h"
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include <math.h>
21 #include "lua.h"
22 #include "lauxlib.h"
24 #include "nlua.h"
25 #include "nluadef.h"
26 #include "nlua_pilot.h"
27 #include "hook.h"
28 #include "log.h"
29 #include "mission.h"
33 * Needed.
35 static Mission *running_mission = NULL; /**< Current running mission. */
36 static Event_t *running_event = NULL; /**< Current running event. */
39 /* hooks */
40 static int hookL_rm( lua_State *L );
41 static int hook_land( lua_State *L );
42 static int hook_takeoff( lua_State *L );
43 static int hook_time( lua_State *L );
44 static int hook_jumpout( lua_State *L );
45 static int hook_jumpin( lua_State *L );
46 static int hook_enter( lua_State *L );
47 static int hook_pilot( lua_State *L );
48 static const luaL_reg hook_methods[] = {
49 { "rm", hookL_rm },
50 { "land", hook_land },
51 { "takeoff", hook_takeoff },
52 { "time", hook_time },
53 { "jumpout", hook_jumpout },
54 { "jumpin", hook_jumpin },
55 { "enter", hook_enter },
56 { "pilot", hook_pilot },
57 {0,0}
58 }; /**< Hook Lua methods. */
62 * Prototypes.
64 static unsigned int hook_generic( lua_State *L, const char* stack, int pos );
67 /**
68 * @brief Loads the hook lua library.
69 * @param L Lua state.
70 * @return 0 on success.
72 int nlua_loadHook( lua_State *L )
74 luaL_register(L, "hook", hook_methods);
75 return 0;
79 /**
80 * @brief Sets the hook target.
82 * The hooks will attach to these targets. Set one to NULL always.
84 * @param m Mission target.
85 * @param ev Event target.
87 void nlua_hookTarget( Mission *m, Event_t *ev )
89 running_mission = m;
90 running_event = ev;
94 /**
95 * @brief Lua bindings to manipulate hooks.
97 * Hooks allow you to trigger functions to certain actions like when the player
98 * jumps or a pilot dies.
100 * Example usage would be:
101 * @code
102 * function penter ()
103 * -- Function to run when player enters a system
104 * end
106 * hookid = hook.enter( "penter" )
107 * @endcode
109 * @luamod hook
114 * @brief Removes a hook previously created.
116 * @usage hook.rm( h ) -- Hook is removed
118 * @luaparam h Identifier of the hook to remove.
119 * @luareturn true if the hook was removed.
120 * @luafunc rm( h )
122 static int hookL_rm( lua_State *L )
124 unsigned int h;
125 int ret;
127 h = luaL_checklong( L, 1 );
128 ret = hook_rm( h );
130 lua_pushboolean( L, ret );
131 return 1;
136 * @brief Creates a mission hook to a certain stack.
138 * Basically a generic approach to hooking.
140 * @param L Lua state.
141 * @param stack Stack to put the hook in.
142 * @param pos Position in the stack of the function name.
143 * @return The hook ID or 0 on error.
145 static unsigned int hook_generic( lua_State *L, const char* stack, int pos )
147 int i;
148 const char *func;
150 /* Last parameter must be function to hook */
151 func = luaL_checkstring(L,pos);
153 if (running_mission != NULL) {
154 /* make sure mission is a player mission */
155 for (i=0; i<MISSION_MAX; i++)
156 if (player_missions[i].id == running_mission->id)
157 break;
158 if (i>=MISSION_MAX) {
159 WARN("Mission not in stack trying to hook");
160 return 0;
163 return hook_addMisn( running_mission->id, func, stack );
165 else if (running_event != NULL) {
166 return hook_addEvent( running_event->id, func, stack );
169 NLUA_ERROR(L,"No hook target was set.");
170 return 0;
173 * @brief Hooks the function to the player landing.
175 * Can also be used to hook the various subparts of the landing menu. Possible targets
176 * for where are:<br />
177 * - "land" - when landed (default with no parameter )<br />
178 * - "outfits" - when visited outfitter<br />
179 * - "shipyard" - when visited shipyard<br />
180 * - "bar" - when visited bar<br />
181 * - "mission" - when visited mission computer<br />
182 * - "commodity" - when visited commodity exchange<br />
183 * - "equipment" - when visiting equipment place<br />
185 * @usage hook.land( "my_function" ) -- Land calls my_function
186 * @usage hook.land( "my_function", "equipment" ) -- Calls my_function at equipment screen
188 * @luaparam funcname Name of function to run when hook is triggered.
189 * @luaparam where Optional argument to specify where to hook the function.
190 * @luareturn Hook identifier.
191 * @luafunc land( funcname, where )
193 static int hook_land( lua_State *L )
195 const char *where;
196 unsigned int h;
198 if (lua_gettop(L) < 2)
199 h = hook_generic( L, "land", 1 );
200 else {
201 where = luaL_checkstring(L, 2);
202 h = hook_generic( L, where, 1 );
205 lua_pushnumber( L, h );
206 return 1;
209 * @brief Hooks the function to the player taking off.
211 * @luaparam funcname Name of function to run when hook is triggered.
212 * @luareturn Hook identifier.
213 * @luafunc takeoff( funcname )
215 static int hook_takeoff( lua_State *L )
217 unsigned int h;
218 h = hook_generic( L, "takeoff", 1 );
219 lua_pushnumber( L, h );
220 return 1;
223 * @brief Hooks the function to a time change.
225 * @luaparam funcname Name of function to run when hook is triggered.
226 * @luareturn Hook identifier.
227 * @luafunc time( funcname )
229 static int hook_time( lua_State *L )
231 unsigned int h;
232 h = hook_generic( L, "time", 1 );
233 lua_pushnumber( L, h );
234 return 1;
237 * @brief Hooks the function to the player jumping (before changing systems).
239 * @luaparam funcname Name of function to run when hook is triggered.
240 * @luareturn Hook identifier.
241 * @luafunc jumpout( funcname )
243 static int hook_jumpout( lua_State *L )
245 unsigned int h;
246 h = hook_generic( L, "jumpout", 1 );
247 lua_pushnumber( L, h );
248 return 1;
251 * @brief Hooks the function to the player jumping (after changing systems).
253 * @luaparam funcname Name of function to run when hook is triggered.
254 * @luareturn Hook identifier.
255 * @luafunc jumpin( funcname )
257 static int hook_jumpin( lua_State *L )
259 unsigned int h;
260 h = hook_generic( L, "jumpin", 1 );
261 lua_pushnumber( L, h );
262 return 1;
265 * @brief Hooks the function to the player entering a system (triggers when taking
266 * off too).
268 * @luaparam funcname Name of function to run when hook is triggered.
269 * @luareturn Hook identifier.
270 * @luafunc enter( funcname )
272 static int hook_enter( lua_State *L )
274 unsigned int h;
275 h = hook_generic( L, "enter", 1 );
276 lua_pushnumber( L, h );
277 return 1;
280 * @brief Hooks the function to a specific pilot.
282 * You can hook to different actions. Curently hook system only supports:<br />
283 * - "death" : triggered when pilot dies.<br />
284 * - "board" : triggered when pilot is boarded.<br />
285 * - "disable" : triggered when pilot is disabled.<br />
286 * - "jump" : triggered when pilot jumps to hyperspace.<br />
287 * - "hail" : triggered when pilot is hailed.<br />
288 * - "attacked" : triggered when the pilot is attacked in manual control <br />
289 * - "idle" : triggered when the pilot becomes idle in manual control <br />
291 * These hooks are run right after the action that triggers them happens, so when the death
292 * or jump hook is run, the pilot won't be in the system at that time.
294 * @luaparam pilot Pilot identifier to hook.
295 * @luaparam type One of the supported hook types.
296 * @luaparam funcname Name of function to run when hook is triggered.
297 * @luareturn Hook identifier.
298 * @luafunc pilot( pilot, type, funcname )
300 static int hook_pilot( lua_State *L )
302 unsigned int h;
303 LuaPilot *p;
304 int type;
305 const char *hook_type;
307 /* Parameters. */
308 p = luaL_checkpilot(L,1);
309 hook_type = luaL_checkstring(L,2);
311 /* Check to see if hook_type is valid */
312 if (strcmp(hook_type,"death")==0) type = PILOT_HOOK_DEATH;
313 else if (strcmp(hook_type,"board")==0) type = PILOT_HOOK_BOARD;
314 else if (strcmp(hook_type,"disable")==0) type = PILOT_HOOK_DISABLE;
315 else if (strcmp(hook_type,"jump")==0) type = PILOT_HOOK_JUMP;
316 else if (strcmp(hook_type,"hail")==0) type = PILOT_HOOK_HAIL;
317 else if (strcmp(hook_type,"attacked")==0) type = PILOT_HOOK_ATTACKED;
318 else if (strcmp(hook_type,"idle")==0) type = PILOT_HOOK_IDLE;
319 else { /* hook_type not valid */
320 NLUA_DEBUG("Invalid pilot hook type: '%s'", hook_type);
321 return 0;
324 /* actually add the hook */
325 h = hook_generic( L, hook_type, 3 );
326 pilot_addHook( pilot_get(p->pilot), type, h );
328 lua_pushnumber( L, h );
329 return 1;