2 * See Licensing and Copyright notice in naev.h
8 * @brief Handles the event lua bindings.
26 #include "nlua_hook.h"
35 * @brief Event system Lua bindings.
37 * An example would be:
39 * evt.finish() -- finishes the event
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 */
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
},
73 }; /**< Mission lua methods. */
77 * individual library loading
80 * @brief Loads the event lua library.
83 int nlua_loadEvt( lua_State
*L
)
85 luaL_register(L
, "evt", evt_methods
);
91 * @brief Sets up the Lua environment to run a function.
93 lua_State
*event_setupLua( Event_t
*ev
, const char *func
)
101 nlua_hookTarget( NULL
, cur_event
);
104 lua_getglobal(L
, func
);
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
126 int event_runLuaFunc( Event_t
*ev
, const char *func
, int nargs
)
132 /* Comfortability. */
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");
148 /* Time to remove the event. */
151 event_remove( cur_event
->id
);
156 nlua_hookTarget( NULL
, NULL
);
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
)
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
);
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
)
202 /* Parse arguments. */
203 func
= luaL_checkstring(L
,1);
204 delay
= luaL_checknumber(L
,2);
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
);
215 /* No timer found. */
216 if (i
>= EVENT_TIMER_MAX
) {
220 /* Returns the timer id. */
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
)
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
;
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
)
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 );
284 snprintf( portrait
, PATH_MAX
, "gfx/portraits/%s.png", gfx
);
287 id
= npc_add_event( cur_event
->id
, func
, name
, priority
, portrait
, desc
);
291 lua_pushnumber( L
, id
);
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
)
311 id
= luaL_checklong(L
, 1);
312 ret
= npc_rm_event( id
, cur_event
->id
);
315 NLUA_ERROR(L
, "Invalid NPC ID!");
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
)
332 b
= lua_toboolean(L
,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 */