From a90f0d66c03d46c787afcb1337d305b9999709c0 Mon Sep 17 00:00:00 2001 From: Allanis Date: Sat, 25 May 2013 00:56:36 +0100 Subject: [PATCH] [Add] Missions are now loaded! Still need to load hooks for them to work. --- src/mission.c | 123 ++++++++++++++++++++++++++++++++++++++++++++------ src/player.c | 2 - src/save.c | 16 ++++--- 3 files changed, 119 insertions(+), 22 deletions(-) diff --git a/src/mission.c b/src/mission.c index 2e55968..be0575e 100644 --- a/src/mission.c +++ b/src/mission.c @@ -47,6 +47,7 @@ static int mission_meetReq(int mission, int faction, char* planet, char* system static int mission_matchFaction(MissionData* misn, int faction); static int mission_location(char* loc); static MissionData* mission_parse(const xmlNodePtr parent); +static int missions_parseActive(xmlNodePtr parent); // Generate a new id for the mission. static unsigned int mission_genID(void) { @@ -83,8 +84,11 @@ static int mission_init(Mission* mission, MissionData* misn) { char* buf; uint32_t bufsize; - mission->id = mission_genID(); - mission->data = misn; + if(misn != NULL) { + // Don't set the data either. + mission->id = mission_genID(); + mission->data = misn; + } // Sane defaults. mission->title = NULL; @@ -104,15 +108,17 @@ static int mission_init(Mission* mission, MissionData* misn) { luaopen_string(mission->L); // string.format can be very useful. misn_loadLibs(mission->L); // Load our custom libraries. - // Load the file. - buf = pack_readfile(DATA, misn->lua, &bufsize); - if(luaL_dobuffer(mission->L, buf, bufsize, misn->lua) != 0) { - ERR("Error loading mission file: %s", misn->lua); - ERR("%s", lua_tostring(mission->L, -1)); - WARN("Most likely Lua file has improper syntax, please check it"); - return -1; + // Don't load it with data. + if(misn != NULL) { + // Load the file. + buf = pack_readfile(DATA, misn->lua, &bufsize); + if(luaL_dobuffer(mission->L, buf, bufsize, misn->lua) != 0) { + ERR("Error loading mission file: %s", misn->lua); + ERR("%s", lua_tostring(mission->L, -1)); + WARN("Most likely Lua file has improper syntax, please check"); + return -1; + } } - free(buf); // Run create function. @@ -428,8 +434,8 @@ void missions_cleanup(void) { typedef struct MBuf_ { char* data; - int len, alloc; // Size of each data chunk, chunks to alloc when growing. - int ndata, mdata; // Buffer real length, memory length. + ssize_t len, alloc; // Size of each data chunk, chunks to alloc when growing. + size_t ndata, mdata; // Buffer real length, memory length. } MBuf; MBuf* mbuf_create(int len, int alloc) { @@ -476,7 +482,7 @@ static int mission_writeLua(lua_State* L, const void* p, size_t sz, void* ud) { return 0; } -int missions_save(xmlTextWriterPtr writer) { +int missions_saveActive(xmlTextWriterPtr writer) { MBuf* buf; char* data; int i, j; @@ -518,3 +524,94 @@ int missions_save(xmlTextWriterPtr writer) { return 0; } +const char* mission_readLua(lua_State* L, void* data, size_t* size) { + (void) L; + MBuf* dat; + char* pos; + char* buf; + + dat = (MBuf*) data; + pos = dat->data; + + buf = &pos[dat->ndata]; + if(dat->mdata >= dat->ndata) { + (*size) = 0; + return NULL; + } + if(dat->mdata < (dat->ndata + dat->alloc * dat->len)) { // Last chunk. + (*size) = dat->mdata - dat->ndata; + dat->ndata = dat->mdata; + } else { + (*size) = dat->alloc * dat->len; + dat->ndata += dat->alloc * dat->len; + } + return buf; +} + +int missions_loadActive(xmlNodePtr parent) { + xmlNodePtr node; + + // Cleanup old missions. + missions_cleanup(); + + node = parent->xmlChildrenNode; + do { + if(xml_isNode(node, "missions")) + if(missions_parseActive(node) < 0) return -1; + } while(xml_nextNode(node)); + + return 0; +} + +static int missions_parseActive(xmlNodePtr parent) { + Mission* misn; + int m; + char* buf; + MBuf dat; + + xmlNodePtr node, cur, nest; + + m = 0; // Start with mission 0. + node = parent->xmlChildrenNode; + do { + if(xml_isNode(node, "mission")) { + misn = &player_missions[m]; + mission_init(misn, NULL); // Won't set data nor id. + + cur = node->xmlChildrenNode; + do { + if(xml_isNode(cur, "data")) { + buf = xml_get(cur); + misn->data = mission_get(mission_getID(buf)); + } + xmlr_long(cur, "id", misn->id); + + xmlr_strd(cur, "title", misn->title); + xmlr_strd(cur, "desc", misn->desc); + xmlr_strd(cur, "reward", misn->reward); + + if(xml_isNode(cur, "cargos")) { + nest = cur->xmlChildrenNode; + do { + if(xml_isNode(nest, "cargo")) + mission_linkCargo(misn, xml_getLong(nest)); + } while(xml_nextNode(nest)); + } + + if(xml_isNode(cur, "lua")) { + buf = xml_get(cur); + dat.ndata = 0; + dat.len = 1; + dat.alloc = 128; + dat.data = base64_decode(&dat.mdata, buf, strlen(buf)); + pluto_unpersist(misn->L, mission_readLua, &dat); + } + } while(xml_nextNode(cur)); + + m++; + if(m >= MISSION_MAX) break; // Full of missions, must be an error. + } + } while(xml_nextNode(node)); + + return 0; +} diff --git a/src/player.c b/src/player.c index 2838823..a2f8463 100644 --- a/src/player.c +++ b/src/player.c @@ -1506,8 +1506,6 @@ static int player_saveShip(xmlTextWriterPtr writer, Pilot* ship, char* loc) { // Save the commodities. xmlw_startElem(writer, "commodities"); for(i = 0; i < ship->ncommodities; i++) { - // TODO: Load player missions, so that we can save mission commodities. - if(ship->commodities[i].id > 0) continue; xmlw_startElem(writer, "commodity"); diff --git a/src/save.c b/src/save.c index d5173df..9ff1bf7 100644 --- a/src/save.c +++ b/src/save.c @@ -14,12 +14,13 @@ #define BUTTON_HEIGHT 30 // Externs. -extern int player_save(xmlTextWriterPtr writer); +extern int player_save(xmlTextWriterPtr writer); // A lot of stuff. extern int player_load(xmlNodePtr parent); -extern int missions_save(xmlTextWriterPtr writer); +extern int missions_saveActive(xmlTextWriterPtr writer); // Active missions. +extern int missions_loadActive(xmlNodePtr parent); extern int var_save(xmlTextWriterPtr writer); // misn var. extern int var_load(xmlNodePtr parent); -extern int pfaction_save(xmlTextWriterPtr writer); +extern int pfaction_save(xmlTextWriterPtr writer); // Faction data. extern int pfaction_load(xmlNodePtr parent); extern void menu_main_close(void); // Static. @@ -31,10 +32,10 @@ static int load_game(char* file); // Save all the game data. static int save_data(xmlTextWriterPtr writer) { // The data itself. - if(player_save(writer) < 0) return -1; - if(missions_save(writer) < 0) return -1; - if(var_save(writer) < 0) return -1; - if(pfaction_save(writer) < 0) return -1; + if(player_save(writer) < 0) return -1; + if(missions_saveActive(writer) < 0) return -1; + if(var_save(writer) < 0) return -1; + if(pfaction_save(writer) < 0) return -1; return 0; } @@ -170,6 +171,7 @@ static int load_game(char* file) { player_load(node); var_load(node); + missions_loadActive(node); pfaction_load(node); xmlFreeDoc(doc);