Merge branch 'master' of git://github.com/BTAxis/naev into testmission
[naev.git] / src / nlua_evt.c
blob5712b734e9d880b72afef5b5d5fc3ec68fab330d
1 /*
2 * See Licensing and Copyright notice in naev.h
3 */
5 /**
6 * @file nlua_evt.c
8 * @brief Handles the event lua bindings.
9 */
12 #include "nlua_evt.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_hook.h"
27 #include "log.h"
28 #include "event.h"
29 #include "mission.h"
30 #include "player.h"
31 #include "npc.h"
34 /**
35 * @brief Event system Lua bindings.
37 * An example would be:
38 * @code
39 * evt.finish() -- finishes the event
40 * @endcode
42 * @luamod evt
49 * current mission
51 static Event_t *cur_event = NULL; /**< Contains the current event for a running script. */
52 static int evt_delete = 0; /**< if 1 delete current event */
56 * libraries
58 /* evt */
59 static int evt_misnStart( lua_State *L );
60 static int evt_timerStart( lua_State *L );
61 static int evt_timerStop( lua_State *L );
62 static int evt_npcAdd( lua_State *L );
63 static int evt_npcRm( lua_State *L );
64 static int evt_finish( lua_State *L );
65 static const luaL_reg evt_methods[] = {
66 { "misnStart", evt_misnStart },
67 { "timerStart", evt_timerStart },
68 { "timerStop", evt_timerStop },
69 { "npcAdd", evt_npcAdd },
70 { "npcRm", evt_npcRm },
71 { "finish", evt_finish },
72 {0,0}
73 }; /**< Mission lua methods. */
77 * individual library loading
79 /**
80 * @brief Loads the event lua library.
81 * @param L Lua state.
83 int nlua_loadEvt( lua_State *L )
85 luaL_register(L, "evt", evt_methods);
86 return 0;
90 /**
91 * @brief Sets up the Lua environment to run a function.
93 lua_State *event_setupLua( Event_t *ev, const char *func )
95 lua_State *L;
97 /* Load event. */
98 L = ev->L;
99 cur_event = ev;
100 evt_delete = 0;
101 nlua_hookTarget( NULL, cur_event );
103 /* Get function. */
104 lua_getglobal(L, func );
106 return L;
111 * @brief Runs the Lua for an event.
113 int event_runLua( Event_t *ev, const char *func )
115 event_setupLua( ev, func );
116 return event_runLuaFunc( ev, func, 0 );
121 * @brief Runs a Lua func with nargs.
123 * @return -1 on error, 1 on misn.finish() call, 2 if mission got deleted
124 * and 0 normally.
126 int event_runLuaFunc( Event_t *ev, const char *func, int nargs )
128 int ret;
129 const char* err;
130 lua_State *L;
132 /* Comfortability. */
133 L = ev->L;
135 ret = lua_pcall(L, nargs, 0, 0);
136 if (ret != 0) { /* error has occured */
137 err = (lua_isstring(L,-1)) ? lua_tostring(L,-1) : NULL;
138 if ((err==NULL) || (strcmp(err,"Event Done")!=0)) {
139 WARN("Event '%s' -> '%s': %s",
140 event_getData(ev->id), func, (err) ? err : "unknown error");
141 ret = -1;
143 else
144 ret = 1;
145 lua_pop(L, 1);
148 /* Time to remove the event. */
149 if (evt_delete) {
150 ret = 2;
151 event_remove( cur_event->id );
154 /* Unload event. */
155 cur_event = NULL;
156 nlua_hookTarget( NULL, NULL );
158 return ret;
163 * @brief Starts a mission.
165 * @usage evt.misnStart( "Tutorial" ) -- Starts the tutorial
167 * @luaparam misn Name of the mission to start, should match mission in dat/mission.xml.
168 * @luafunc misnStart( misn )
170 static int evt_misnStart( lua_State *L )
172 const char *str;
174 str = luaL_checkstring(L, 1);
175 if (mission_start( str )) {
176 /* Reset the hook. */
177 nlua_hookTarget( NULL, cur_event );
178 NLUA_ERROR(L,"Failed to start mission.");
181 /* Has to reset the hook target since mission overrides. */
182 nlua_hookTarget( NULL, cur_event );
184 return 0;
189 * @brief Starts a timer.
191 * @luaparam funcname Name of the function to run when timer is up.
192 * @luaparam delay Milliseconds to wait for timer.
193 * @luareturn The timer being used.
194 * @luafunc timerStart( funcname, delay )
196 static int evt_timerStart( lua_State *L )
198 int i;
199 const char *func;
200 double delay;
202 /* Parse arguments. */
203 func = luaL_checkstring(L,1);
204 delay = luaL_checknumber(L,2);
206 /* Add timer */
207 for (i=0; i<EVENT_TIMER_MAX; i++) {
208 if (cur_event->timer[i] == 0.) {
209 cur_event->timer[i] = delay / 1000.;
210 cur_event->tfunc[i] = strdup(func);
211 break;
215 /* No timer found. */
216 if (i >= EVENT_TIMER_MAX) {
217 return 0;
220 /* Returns the timer id. */
221 lua_pushnumber(L,i);
222 return 1;
226 * @brief Stops a timer previously started with timerStart().
228 * @luaparam t Timer to stop.
229 * @luafunc timerStop( t )
231 static int evt_timerStop( lua_State *L )
233 int t;
235 /* Parse parameters. */
236 t = luaL_checkint(L,1);
238 /* Stop the timer. */
239 if (cur_event->timer[t] != 0.) {
240 cur_event->timer[t] = 0.;
241 if (cur_event->tfunc[t] != NULL) {
242 free(cur_event->tfunc[t]);
243 cur_event->tfunc[t] = NULL;
247 return 0;
252 * @brief Adds an NPC.
254 * @usage npc_id = evt.npcAdd( "my_func", "Mr. Test", "none", "A test." ) -- Creates an NPC.
256 * @luaparam func Name of the function to run when approaching.
257 * @luaparam name Name of the NPC
258 * @luaparam portrait Portrait to use for the NPC (from gfx/portraits*.png).
259 * @luaparam desc Description assosciated to the NPC.
260 * @luaparam priority Optional priority argument (defaults to 5, highest is 0, lowest is 10).
261 * @luareturn The ID of the NPC to pass to npcRm.
262 * @luafunc npcAdd( func, name, portrait, desc, priority )
264 static int evt_npcAdd( lua_State *L )
266 unsigned int id;
267 int priority;
268 const char *func, *name, *gfx, *desc;
269 char portrait[PATH_MAX];
271 /* Handle parameters. */
272 func = luaL_checkstring(L, 1);
273 name = luaL_checkstring(L, 2);
274 gfx = luaL_checkstring(L, 3);
275 desc = luaL_checkstring(L, 4);
277 /* Optional priority. */
278 if (lua_gettop(L) > 4)
279 priority = luaL_checkint( L, 5 );
280 else
281 priority = 5;
283 /* Set path. */
284 snprintf( portrait, PATH_MAX, "gfx/portraits/%s.png", gfx );
286 /* Add npc. */
287 id = npc_add_event( cur_event->id, func, name, priority, portrait, desc );
289 /* Return ID. */
290 if (id > 0) {
291 lua_pushnumber( L, id );
292 return 1;
294 return 0;
299 * @brief Removes an NPC.
301 * @usage evt.npcRm( npc_id )
303 * @luaparam id ID of the NPC to remove.
304 * @luafunc npcRm( id )
306 static int evt_npcRm( lua_State *L )
308 unsigned int id;
309 int ret;
311 id = luaL_checklong(L, 1);
312 ret = npc_rm_event( id, cur_event->id );
314 if (ret != 0)
315 NLUA_ERROR(L, "Invalid NPC ID!");
316 return 0;
321 * @brief Finishes the event.
323 * @luaparam properly If true and the event is unique it marks the event
324 * as completed. If false or nil it deletes the event but
325 * doesn't mark it as completed.
326 * @luafunc finish( properly )
328 static int evt_finish( lua_State *L )
330 int b;
332 b = lua_toboolean(L,1);
333 evt_delete = 1;
335 if (b && event_isUnique(cur_event->id))
336 player_eventFinished( cur_event->data );
338 lua_pushstring(L, "Event Done");
339 lua_error(L); /* shouldn't return */
341 return 0;