From 75954df719c0276f7d84c2a95810ab45ecee4721 Mon Sep 17 00:00:00 2001
From: Allanis <allanis@saracraft.net>
Date: Fri, 17 May 2013 02:02:56 +0100
Subject: [PATCH] [Add] Now completed missions and mission variables are also
 loaded.

---
 src/misn_lua.c | 118 +++++++++++++++++++++++++++++++++++--------------
 src/mission.c  |   8 ++--
 src/mission.h  |   2 +-
 src/player.c   |   5 ++-
 src/save.c     |   2 +
 5 files changed, 95 insertions(+), 40 deletions(-)

diff --git a/src/misn_lua.c b/src/misn_lua.c
index b317409..66c0a05 100644
--- a/src/misn_lua.c
+++ b/src/misn_lua.c
@@ -48,6 +48,7 @@ static int var_mstack = 0;
 static Mission* cur_mission = NULL;
 static int misn_delete = 0; // If 1 delete current mission.
 
+static int var_add(misn_var* var);
 static void var_free(misn_var* var);
 static int  hook_generic(lua_State* L, char* stack);
 
@@ -258,6 +259,77 @@ int var_save(xmlTextWriterPtr writer) {
   return 0;
 }
 
+// Load the vars.
+int var_load(xmlNodePtr parent) {
+  char* str;
+  xmlNodePtr node, cur;
+  misn_var var;
+
+  var_cleanup();
+
+  node = parent->xmlChildrenNode;
+
+  do {
+    if(xml_isNode(node, "vars")) {
+      cur = node->xmlChildrenNode;
+      
+      do {
+        if(xml_isNode(cur, "var")) {
+          xmlr_attr(cur, "name", var.name);
+          xmlr_attr(cur, "type", str);
+          if(strcmp(str, "nil")==0)
+            var.type = MISN_VAR_NIL;
+          else if(strcmp(str, "num")==0) {
+            var.type = MISN_VAR_NUM;
+            var.d.num = atoi(xml_get(cur));
+          }
+          else if(strcmp(str, "bool")) {
+            var.type = MISN_VAR_BOOL;
+            var.d.b = atoi(xml_get(cur));
+          }
+          else if(strcmp(str, "str")) {
+            var.type = MISN_VAR_STR;
+            var.d.str = atoi(xml_get(cur));
+          } else {
+            // Supeh error checking.
+            WARN("Unknown var type '%s'", str);
+            free(var.name);
+            continue;
+          }
+          free(str);
+          var_add(&var);
+        }
+      } while(xml_nextNode(cur));
+    }
+  } while(xml_nextNode(node));
+
+  return 0;
+}
+
+// Add a var to the stack, strings will be SHARED, don't free!!!
+static int var_add(misn_var* new_var) {
+  int i;
+
+  if(var_nstack+1 > var_mstack) {
+    // More memory.
+    var_mstack += 64; // Overkill much??
+    var_stack = realloc(var_stack, var_mstack * sizeof(misn_var));
+  }
+
+  // Check if already exists.
+  for(i = 0; i < var_nstack; i++)
+    if(strcmp(new_var->name, var_stack[i].name)==0) {
+      var_free(&var_stack[i]);
+      memcpy(&var_stack[i], new_var, sizeof(misn_var));
+      return 0;
+    }
+
+  memcpy(&var_stack[var_nstack], new_var, sizeof(misn_var));
+  var_nstack++;
+
+  return 0;
+}
+
 // -- Lephisto. --
 static int lephisto_lang(lua_State* L) {
   // TODO: multilanguage stuff.
@@ -349,7 +421,7 @@ static int misn_finish(lua_State* L) {
   misn_delete = 1;
 
   if(b && mis_isFlag(cur_mission->data, MISSION_UNIQUE))
-    player_missionFinished(mission_getID(cur_mission->data));
+    player_missionFinished(mission_getID(cur_mission->data->name));
 
   lua_pushstring(L, "Mission Done");
   lua_error(L); // Should not return..
@@ -425,9 +497,8 @@ static int var_pop(lua_State* L) {
 
 static int var_push(lua_State* L) {
   MIN_ARGS(2);
-  int i;
   char* str;
-  misn_var* var;
+  misn_var var;
 
   if(lua_isstring(L, -2)) str = (char*) lua_tostring(L, -2);
   else {
@@ -435,50 +506,29 @@ static int var_push(lua_State* L) {
     return 0;
   }
 
-  if(var_nstack+1 > var_mstack) {
-    // More memory.
-    var_mstack += 10;
-    var_stack = realloc(var_stack, var_mstack*sizeof(misn_var));
-  }
-
-  // Check if already exists.
-  var = NULL;
-  for(i = 0; i < var_nstack; i++)
-    if(strcmp(str, var_stack[i].name)==0)
-      var = &var_stack[i];
-
-  if(var == NULL)
-    var = &var_stack[var_nstack];
-  else if((var->type == MISN_VAR_STR) && (var->d.str != NULL)) {
-    // Must free.
-    free(var->d.str);
-    var->d.str = NULL;
-  }
+  var.name = strdup(str);
 
   // Store appropriate data.
   if(lua_isnil(L, -1))
-    var->type = MISN_VAR_NIL;
+    var.type = MISN_VAR_NIL;
   else if(lua_isnumber(L, -1)) {
-    var->type = MISN_VAR_NUM;
-    var->d.num = (double)lua_tonumber(L, -1);
+    var.type = MISN_VAR_NUM;
+    var.d.num = (double)lua_tonumber(L, -1);
   }
   else if(lua_isboolean(L, -1)) {
-    var->type = MISN_VAR_BOOL;
-    var->d.b = lua_toboolean(L, -1);
+    var.type = MISN_VAR_BOOL;
+    var.d.b = lua_toboolean(L, -1);
   }
   else if(lua_isstring(L, -1)) {
-    var->type = MISN_VAR_STR;
-    var->d.str = strdup((char*)lua_tostring(L, -1));
+    var.type = MISN_VAR_STR;
+    var.d.str = strdup((char*)lua_tostring(L, -1));
   } else {
     MISN_DEBUG("Trying to push a var of invalid data type to stack");
     return 0;
   }
 
-  if(i >= var_nstack) {
-    // Var is new.
-    var->name = strdup(str);
-    var_nstack++;
-  }
+  var_add(&var);
+
   return 0;
 }
 
diff --git a/src/mission.c b/src/mission.c
index af0188b..fe112bc 100644
--- a/src/mission.c
+++ b/src/mission.c
@@ -45,14 +45,14 @@ static int  mission_matchFaction(MissionData* misn, int faction);
 static int  mission_location(char* loc);
 static MissionData* mission_parse(const xmlNodePtr parent);
 
-// Gets the ID of a MissionData.
-int mission_getID(MissionData* misn) {
+// Gets the ID from mission name.
+int mission_getID(char* name) {
   int i;
   for(i = 0; i < mission_nstack; i++)
-    if(misn == &mission_stack[i])
+    if(strcmp(name, mission_stack[i].name)==0)
       return i;
 
-  DEBUG("Mission '%s' not found in stack", misn->name);
+  DEBUG("Mission '%s' not found in stack", name);
   return -1;
 }
 
diff --git a/src/mission.h b/src/mission.h
index 02b1454..4b1d4cc 100644
--- a/src/mission.h
+++ b/src/mission.h
@@ -68,7 +68,7 @@ int mission_accept(Mission* mission);
 void missions_bar(int faction, char* planet, char* system);
 
 // Misc.
-int mission_getID(MissionData* misn);
+int mission_getID(char* name);
 MissionData* mission_get(int id);
 
 // Cargo stuff.
diff --git a/src/player.c b/src/player.c
index 3a05da2..8542acb 100644
--- a/src/player.c
+++ b/src/player.c
@@ -1580,6 +1580,8 @@ static int player_parse(xmlNodePtr parent) {
           player_parseShip(cur, 0);
       } while(xml_nextNode(cur));
     }
+    if(xml_isNode(node, "missions_done"))
+      player_parseDone(node);
   } while(xml_nextNode(node));
 
   // Set global thingies.
@@ -1607,7 +1609,8 @@ static int player_parseDone(xmlNodePtr parent) {
   node = parent->xmlChildrenNode;
 
   do {
-
+    if(xml_isNode(node, "done"))
+      player_missionFinished(mission_getID(xml_get(node)));
   } while(xml_nextNode(node));
 
   return 0;
diff --git a/src/save.c b/src/save.c
index a1025d9..3876a0c 100644
--- a/src/save.c
+++ b/src/save.c
@@ -18,6 +18,7 @@ extern int  player_save(xmlTextWriterPtr writer);
 extern int  missions_save(xmlTextWriterPtr writer);
 extern int  var_save(xmlTextWriterPtr writer); // misn var.
 extern int  player_load(xmlNodePtr parent);
+extern int  var_load(xmlNodePtr parent);
 extern void menu_main_close(void);
 // Static.
 static int  save_data(xmlTextWriterPtr writer);
@@ -161,6 +162,7 @@ static int load_game(char* file) {
   node = doc->xmlChildrenNode; // Base node.
 
   player_load(node);
+  var_load(node);
 
   xmlFreeDoc(doc);