diff --git a/src/lephisto.c b/src/lephisto.c index bd907be..d944513 100644 --- a/src/lephisto.c +++ b/src/lephisto.c @@ -414,6 +414,7 @@ static void update_routine(double dt) { weapons_update(dt); spfx_update(dt); pilots_update(dt); + missions_update(dt); } /** diff --git a/src/misn_lua.c b/src/misn_lua.c index 2891463..62e4d1b 100644 --- a/src/misn_lua.c +++ b/src/misn_lua.c @@ -69,6 +69,8 @@ static int misn_setMarker(lua_State* L); static int misn_factions(lua_State* L); static int misn_accept(lua_State* L); static int misn_finish(lua_State* L); +static int misn_timerStart(lua_State* L); +static int misn_timerStop(lua_State* L); static const luaL_reg misn_methods[] = { { "setTitle", misn_setTitle }, { "setDesc", misn_setDesc }, @@ -77,6 +79,8 @@ static const luaL_reg misn_methods[] = { { "factions", misn_factions }, { "accept", misn_accept }, { "finish", misn_finish }, + { "timerStart", misn_timerStart }, + { "timerStop", misn_timerStop }, { 0, 0 } }; @@ -455,6 +459,77 @@ static int misn_finish(lua_State* L) { return 0; } +/** + * @fn static int misn_timerStart(lua_State* L) + * + * @brief number timerStart( string func, number delay ) + * + * Start a timer. + * @param func Function to run when timer is up. + * @param delay Seconds to wait for timer. + * @return The timer being used. + */ +static int misn_timerStart(lua_State* L) { + LLUA_MIN_ARGS(2); + int i; + char* func; + double delay; + + /* Parse arguments. */ + if(lua_isstring(L,1)) + func = (char*)lua_tostring(L,1); + else LLUA_INVALID_PARAMETER(); + if(lua_isnumber(L,2)) + delay = lua_tonumber(L,2); + else LLUA_INVALID_PARAMETER(); + + /* Add timer. */ + for(i = 0; i < MISSION_TIMER_MAX; i++) { + if(cur_mission->timer[i] == 0.) { + cur_mission->timer[i] = delay; + cur_mission->tfunc[i] = strdup(func); + break; + } + } + + /* No timer found. */ + if(i >= MISSION_TIMER_MAX) { + return 0; + } + + /* Return the timer id. */ + lua_pushnumber(L, i); + return 1; +} + +/** + * @fn static int misn_timerStop(lua_State* L) + * + * @brief timerStop(number t) + * + * Stop a timer previously started with timerStart(). + * @param t Timer to stop. + */ +static int misn_timerStop(lua_State* L) { + LLUA_MIN_ARGS(1); + int t; + + /* Parse arguments. */ + if(lua_isnumber(L,1)) + t = (int)lua_tonumber(L,1); + else LLUA_INVALID_PARAMETER(); + + /* Stop the timer. */ + if(cur_mission->timer[t] != 0.) { + cur_mission->timer[t] = 0.; + if(cur_mission->tfunc[t] != NULL) { + free(cur_mission->tfunc[t]); + cur_mission->tfunc[t] = NULL; + } + } + return 0; +} + /* -- Var. -- */ /* Check if a variable exists. */ diff --git a/src/mission.c b/src/mission.c index ed32a17..8166917 100644 --- a/src/mission.c +++ b/src/mission.c @@ -297,6 +297,35 @@ void mission_unlinkCargo(Mission* misn, unsigned int cargo_id) { player_rmMissionCargo(cargo_id); } +/** + * @fn void missions_update(const double dt) + * + * @brief Update the missions triggering timers if needed. + * @param dt Curretn deltatick. + */ +void missions_update(const double dt) { + int i, j; + + for(i = 0; i < MISSION_MAX; i++) { + /* Mission must be active. */ + if(player_missions[i].id != 0) { + for(j = 0; j < MISSION_TIMER_MAX; i++) { + /* Timer must be active. */ + if(player_missions[i].timer[j] != 0.) { + player_missions[i].timer[j] -= dt; + + if(player_missions[i].timer[j] < 0.) { + misn_run(&player_missions[i], player_missions[i].tfunc[j]); + player_missions[i].timer[j] = 0.; + free(player_missions[i].tfunc[j]); + player_missions[i].tfunc[j] = NULL; + } + } + } + } + } +} + /* Clean up a mission. */ void mission_cleanup(Mission* misn) { int i; @@ -327,6 +356,13 @@ void mission_cleanup(Mission* misn) { misn->cargo = NULL; misn->ncargo = 0; } + for(i = 0; i < MISSION_TIMER_MAX; i++) { + misn->timer[i] = 0.; + if(misn->tfunc[i] != NULL) { + free(misn->tfunc[i]); + misn->tfunc[i] = NULL; + } + } if(misn->L) { lua_close(misn->L); misn->L = NULL; diff --git a/src/mission.h b/src/mission.h index f82fe17..60c9ea3 100644 --- a/src/mission.h +++ b/src/mission.h @@ -17,6 +17,8 @@ #define MISSION_UNIQUE 1 /* Unique missions can't be repeated. */ +#define MISSION_TIMER_MAX 4 /**< Maximum amount of timers in a mission. */ + /* Static mission data. */ typedef struct MissionData_ { char* name; /* the name of the mission. */ @@ -59,6 +61,10 @@ typedef struct Mission_ { char* sys_marker; /* Marked system. */ + /* Timers. */ + double timer[MISSION_TIMER_MAX]; + char* tfunc[MISSION_TIMER_MAX]; + lua_State* L; /* The state of the running lua code. */ } Mission; @@ -72,6 +78,7 @@ int mission_accept(Mission* mission); void missions_bar(int faction, char* planet, char* sysname); /* Misc. */ +void missions_update(const double dt); int mission_getID(char* name); MissionData* mission_get(int id); void mission_sysMark(void);