From e152d40fb271fdc9b045ee2cd81bfc3180c091f5 Mon Sep 17 00:00:00 2001 From: Allanis Date: Mon, 8 Apr 2013 23:29:44 +0100 Subject: [PATCH] [Add] Track cargo missions so they get cleaned on abort. --- src/misn_lua.c | 2 ++ src/mission.c | 39 +++++++++++++++++++++++++++++++++++++++ src/mission.h | 10 +++++++++- src/player.c | 10 ++++++++++ src/player.h | 2 ++ 5 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/misn_lua.c b/src/misn_lua.c index 5cdf187..37fc530 100644 --- a/src/misn_lua.c +++ b/src/misn_lua.c @@ -300,6 +300,7 @@ static int player_addCargo(lua_State* L) { else return 0; ret = pilot_addMissionCargo(player, cargo, quantity); + mission_linkCargo(cur_mission, ret); lua_pushnumber(L, ret); return 1; @@ -315,6 +316,7 @@ static int player_rmCargo(lua_State* L) { else return 0; ret = pilot_rmMissionCargo(player, id); + mission_unlinkCargo(cur_mission, id); lua_pushboolean(L, !ret); return 0; diff --git a/src/mission.c b/src/mission.c index e1fccb7..7a2cbec 100644 --- a/src/mission.c +++ b/src/mission.c @@ -13,6 +13,7 @@ #include "pack.h" #include "xml.h" #include "faction.h" +#include "player.h" #include "mission.h" #define XML_MISSION_ID "Missions" // XML section identifier. @@ -54,6 +55,8 @@ static int mission_init(Mission* mission, MissionData* misn) { mission->title = NULL; mission->desc = NULL; mission->reward = NULL; + mission->cargo = NULL; + mission->ncargo = 0; // Init lua. mission->L = luaL_newstate(); @@ -111,12 +114,48 @@ void missions_bar(int faction, char* planet, char* system) { } } +// Links cargo to the mission for posterior cleanup. +void mission_linkCargo(Mission* misn, unsigned int cargo_id) { + misn->ncargo++; + misn->cargo = realloc(misn->cargo, sizeof(unsigned int) * misn->ncargo); + misn->cargo[misn->ncargo-1] = cargo_id; +} + +// Unlink cargo from the mission, removes it from the player. +void mission_unlinkCargo(Mission* misn, unsigned int cargo_id) { + int i; + + for(i = 0; i < misn->ncargo; i++) + if(misn->cargo[i] == cargo_id) + break; + + if(i >= misn->cargo) { + DEBUG("Mission '%s' attempting to unlink in existant cargo %d.", + misn->title, cargo_id); + return; + } + + // Shrink cargo size - No need to realloc. + memmove(&misn->cargo[i], &misn->cargo[i+1], + sizeof(unsigned int) * (misn->ncargo-i-1)); + + misn->ncargo--; + player_rmMissionCargo(cargo_id); +} + // Clean up a mission. void mission_cleanup(Mission* misn) { + int i; if(misn->id) hook_rmParent(misn->id); // Remove existing hooks. if(misn->title) free(misn->title); if(misn->desc) free(misn->desc); if(misn->reward) free(misn->reward); + if(misn->cargo) { + for(i = 0; i < misn->ncargo; i++) + mission_unlinkCargo(misn, misn->cargo[i]); + free(misn->cargo); + misn->ncargo = 0; + } if(misn->L) lua_close(misn->L); memset(misn, 0, sizeof(Mission)); } diff --git a/src/mission.h b/src/mission.h index 5339454..add1471 100644 --- a/src/mission.h +++ b/src/mission.h @@ -49,7 +49,11 @@ typedef struct Mission_ { char* desc; // Description of the mission. char* reward; // Rewards - in text. - lua_State* L; + // Mission cargo give to the player - Need to cleanup. + unsigned int* cargo; + int ncargo; + + lua_State* L; // The state of the running lua code. } Mission; #define MISSION_MAX 6 // No sense in the player having unlimited missions.. @@ -61,6 +65,10 @@ Mission* missions_computer(int* n, int faction, char* planet, char* system); void mission_accept(Mission* mission); void mission_bar(int faction, char* planet, char* system); +// Cargo stuff. +void mission_linkCargo(Mission* misn, unsigned int cargo_id); +void mission_unlinkCargo(Mission* misn, unsigned int cargo_id); + // Load/Quit. int missions_load(void); void mission_cleanup(Mission* misn); diff --git a/src/player.c b/src/player.c index 5729616..76321f6 100644 --- a/src/player.c +++ b/src/player.c @@ -388,6 +388,16 @@ int player_cargoOwned(const char* commodityname) { return 0; } +void player_rmMissionCargo(unsigned int cargo_id) { + int i; + + if(!pilot_rmMissionCargo(player, cargo_id)) return; // Already done. + + for(i = 0; i < player_nstack; i++) + if(!pilot_rmMissionCargo(player_stack[i], cargo_id)) + return; // Success. +} + // Render the background player stuff, namely planet target void player_renderBG(void) { double x, y; diff --git a/src/player.h b/src/player.h index 5532a0d..d985c0d 100644 --- a/src/player.h +++ b/src/player.h @@ -45,8 +45,10 @@ void player_message(const char* fmt, ...); void player_clear(void); void player_warp(const double x, const double y); const char* player_rating(void); +// Cargo. int player_outfitOwned(const char* outfitname); int player_cargoOwned(const char* commodityname); +void player_rmMissionCargo(unsigned int cargo_id); // Pilot ships. char** player_ships(int* nships);