From 6ad8d75d2dbb59bc1159429a3088cc00af29aff0 Mon Sep 17 00:00:00 2001
From: Allanis <allanis@saracraft.net>
Date: Sun, 17 Nov 2013 14:58:33 +0000
Subject: [PATCH] [Add] Mission timers added.

---
 src/lephisto.c |  1 +
 src/misn_lua.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/mission.c  | 36 ++++++++++++++++++++++++
 src/mission.h  |  7 +++++
 4 files changed, 119 insertions(+)

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);