[Add] Initial implentation of licenses, licenses are to be purchased

before given permission to buy various ships/weapons.
This commit is contained in:
Allanis 2014-04-09 20:55:15 +01:00
parent f8701e4bdc
commit 233b8b96f0
11 changed files with 190 additions and 35 deletions

View File

@ -656,5 +656,16 @@ By adding quite a dense layer of Plasteel to your ship you can increase it's stu
<specific type="fighter"> <specific type="fighter">
<ship>Lancelot</ship> <ship>Lancelot</ship>
</specific> </specific>
</outfit> </outfit>
<outfit name="Large Civilian Vessel License">
<general>
<max>1</max>
<tech>8</tech>
<mass>0</mass>
<price>75000</price>
<gfx_store>license</gfx_store>
<description>This license will authorize you to buy Cruise Ship and Bulk Carrier class ships.</description>
</general>
<specific type="license" />
</outfit>
</Outfits> </Outfits>

View File

@ -326,6 +326,7 @@
<price>900000</price> <price>900000</price>
<fabricator>Melendez Corp</fabricator> <fabricator>Melendez Corp</fabricator>
<tech>5</tech> <tech>5</tech>
<license>Large Civilian Vessel License</license>
<description>A heavy liner specialized in freighting cargo all over the universe. Also has good accomodations for passengers depending on the model allowing for enjoyable cruises. Was a favorite target of pirates until they added stock turrets to the new models which can now defend themselves properly.</description> <description>A heavy liner specialized in freighting cargo all over the universe. Also has good accomodations for passengers depending on the model allowing for enjoyable cruises. Was a favorite target of pirates until they added stock turrets to the new models which can now defend themselves properly.</description>
<movement> <movement>
<thrust>100</thrust> <thrust>100</thrust>

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -270,7 +270,7 @@ static void outfits_open(void) {
/* The descriptive text. */ /* The descriptive text. */
window_addText(wid, 40+300+20, -60, window_addText(wid, 40+300+20, -60,
80, 140, 0, "txtSDesc", &gl_smallFont, &cDConsole, 80, 160, 0, "txtSDesc", &gl_smallFont, &cDConsole,
"Name:\n" "Name:\n"
"Type:\n" "Type:\n"
"Owned:\n" "Owned:\n"
@ -279,12 +279,13 @@ static void outfits_open(void) {
"Free Space:\n" "Free Space:\n"
"\n" "\n"
"Price:\n" "Price:\n"
"Money:\n"); "Money:\n"
"License:\n");
window_addText(wid, 40+300+40+60, -60, window_addText(wid, 40+300+40+60, -60,
250, 140, 0, "txtDDesc", &gl_smallFont, &cBlack, NULL); 250, 160, 0, "txtDDesc", &gl_smallFont, &cBlack, NULL);
window_addText(wid, 20+300+40, -220, window_addText(wid, 20+300+40, -240,
OUTFITS_WIDTH-400, 180, 0, "txtDescription", OUTFITS_WIDTH-400, 180, 0, "txtDescription",
&gl_smallFont, NULL, NULL); &gl_smallFont, NULL, NULL);
@ -327,14 +328,14 @@ static void outfits_update(unsigned int wid, char* str) {
(void)str; (void)str;
char* outfitname; char* outfitname;
Outfit* outfit; Outfit* outfit;
char buf[128], buf2[16], buf3[16]; char buf[PATH_MAX], buf2[16], buf3[16];
outfitname = toolkit_getList(wid, "iarOutfits"); outfitname = toolkit_getList(wid, "iarOutfits");
if(strcmp(outfitname, "None")==0) { /* No outfits. */ if(strcmp(outfitname, "None")==0) { /* No outfits. */
window_modifyImage(wid, "imgOutfit", NULL); window_modifyImage(wid, "imgOutfit", NULL);
window_disableButton(wid, "btnBuyOutfit"); window_disableButton(wid, "btnBuyOutfit");
window_disableButton(wid, "btnSellOutfit"); window_disableButton(wid, "btnSellOutfit");
snprintf(buf, 128, snprintf(buf, PATH_MAX,
"None\n" "None\n"
"NA\n" "NA\n"
"NA\n" "NA\n"
@ -343,6 +344,7 @@ static void outfits_update(unsigned int wid, char* str) {
"%d\n" "%d\n"
"\n" "\n"
"NA\n" "NA\n"
"MA\m"
"NA\n", "NA\n",
pilot_freeSpace(player)); pilot_freeSpace(player));
window_modifyText(wid, "txtDDesc", buf); window_modifyText(wid, "txtDDesc", buf);
@ -368,7 +370,7 @@ static void outfits_update(unsigned int wid, char* str) {
window_modifyText(wid, "txtDescription", outfit->description); window_modifyText(wid, "txtDescription", outfit->description);
credits2str(buf2, outfit->price, 2); credits2str(buf2, outfit->price, 2);
credits2str(buf3, player->credits, 2); credits2str(buf3, player->credits, 2);
snprintf(buf, 128, snprintf(buf, PATH_MAX,
"%s\n" "%s\n"
"%s\n" "%s\n"
"%d\n" "%d\n"
@ -377,14 +379,16 @@ static void outfits_update(unsigned int wid, char* str) {
"%d\n" "%d\n"
"\n" "\n"
"%s SCred\n" "%s SCred\n"
"%s SCred\n", "%s SCred\n"
"%s\n",
outfit->name, outfit->name,
outfit_getType(outfit), outfit_getType(outfit),
player_outfitOwned(outfitname), player_outfitOwned(outfitname),
outfit->mass, outfit->mass,
pilot_freeSpace(player), pilot_freeSpace(player),
buf2, buf2,
buf3); buf3,
(outfit->license != NULL) ? outfit->license : "None");
window_modifyText(wid, "txtDDesc", buf); window_modifyText(wid, "txtDDesc", buf);
} }
@ -425,11 +429,25 @@ static int outfit_canBuy(Outfit* outfit, int q, int errmsg) {
} }
return 0; return 0;
} }
/* Map alrady mapped. */
else if(outfit_isMap(outfit) && map_isMapped(NULL, outfit->u.map.radius)) { else if(outfit_isMap(outfit) && map_isMapped(NULL, outfit->u.map.radius)) {
if(errmsg != 0) if(errmsg != 0)
dialogue_alert("You already own this map."); dialogue_alert("You already own this map.");
return 0; return 0;
} }
/* Already has license. */
else if(outfit_isLicense(outfit) && player_hasLicense(outfit->name)) {
if(errmsg != 0)
dialogue_alert("You already have this license.");
return 0;
}
/* Needs license. */
else if((outfit->license != NULL) && !player_hasLicense(outfit->name)) {
if(errmsg != 0)
dialogue_alert("You need the '%s' license to buy this outfit.",
outfit->license);
return 0;
}
return 1; return 1;
} }
@ -561,23 +579,24 @@ static void shipyard_open(void) {
/* Text. */ /* Text. */
window_addText(wid, 40+300+40, -55, window_addText(wid, 40+300+40, -55,
80, 96, 0, "txtSDesc", &gl_smallFont, &cDConsole, 80, 128, 0, "txtSDesc", &gl_smallFont, &cDConsole,
"Name:\n" "Name:\n"
"Class:\n" "Class:\n"
"Fabricator:\n" "Fabricator:\n"
"\n" "\n"
"Price:\n" "Price:\n"
"Money:\n"); "Money:\n"
"License:\n");
window_addText(wid, 40+300+40+80, -55, window_addText(wid, 40+300+40+80, -55,
130, 96, 0, "txtDDesc", &gl_smallFont, &cBlack, NULL); 130, 128, 0, "txtDDesc", &gl_smallFont, &cBlack, NULL);
window_addText(wid, 20+310+40, -175, window_addText(wid, 20+310+40, -55-128-20,
SHIPYARD_WIDTH-(20+310+40) - 20, 185, 0, "txtDescription", SHIPYARD_WIDTH-(20+310+40) - 20, 185, 0, "txtDescription",
&gl_smallFont, NULL, NULL); &gl_smallFont, NULL, NULL);
/* Setup the ships to buy/sell. */ /* Set up the ships to buy/sell. */
ships = ship_getTech(&nships, land_planet->tech, PLANET_TECH_MAX); ships = ship_getTech(&nships, land_planet->tech, PLANET_TECH_MAX);
if(nships <= 0) { if(nships <= 0) {
@ -614,7 +633,7 @@ static void shipyard_update(unsigned int wid, char* str) {
(void)str; (void)str;
char* shipname; char* shipname;
Ship* ship; Ship* ship;
char buf[80], buf2[16], buf3[16]; char buf[PATH_MAX], buf2[16], buf3[16];
shipname = toolkit_getList(wid, "iarShipyard"); shipname = toolkit_getList(wid, "iarShipyard");
@ -623,12 +642,13 @@ static void shipyard_update(unsigned int wid, char* str) {
window_modifyImage(wid, "imgTarget", NULL); window_modifyImage(wid, "imgTarget", NULL);
window_disableButton(wid, "btnBuyShip"); window_disableButton(wid, "btnBuyShip");
window_disableButton(wid, "btnInfoShip"); window_disableButton(wid, "btnInfoShip");
snprintf(buf, 80, snprintf(buf, PATH_MAX,
"None\n" "None\n"
"NA\n" "NA\n"
"NA\n" "NA\n"
"\n" "\n"
"NA\n" "NA\n"
"NA\n"
"NA\n"); "NA\n");
window_modifyText(wid, "txtDDesc", buf); window_modifyText(wid, "txtDDesc", buf);
return; return;
@ -644,18 +664,20 @@ static void shipyard_update(unsigned int wid, char* str) {
credits2str(buf2, ship->price, 2); credits2str(buf2, ship->price, 2);
credits2str(buf3, player->credits, 2); credits2str(buf3, player->credits, 2);
snprintf(buf, 80, snprintf(buf, PATH_MAX,
"%s\n" "%s\n"
"%s\n" "%s\n"
"%s\n" "%s\n"
"\n" "\n"
"%s SCred\n" "%s SCred\n"
"%s SCred\n", "%s SCred\n"
"%s\n",
ship->name, ship->name,
ship_class(ship), ship_class(ship),
ship->fabricator, ship->fabricator,
buf2, buf2,
buf3); buf3,
(ship->license != NULL) ? ship->license : "None");
window_modifyText(wid, "txtDDesc", buf); window_modifyText(wid, "txtDDesc", buf);
@ -686,6 +708,13 @@ static void shipyard_buy(unsigned int wid, char* str) {
return; return;
} }
/* Must have enough credits. */
if((ship->license != NULL) && !player_hasLicense(ship->license)) {
dialogue_alert("You do not have the '%s' license required to buy this ship.",
ship->license);
return;
}
if(pilot_cargoUsed(player) > ship->cap_cargo) { if(pilot_cargoUsed(player) > ship->cap_cargo) {
dialogue_alert("You won't have space to move your current cargo onto the new ship."); dialogue_alert("You won't have space to move your current cargo onto the new ship.");
return; return;

View File

@ -40,6 +40,7 @@ static void outfit_parseSJammer(Outfit* tmp, const xmlNodePtr parent);
static void outfit_parseSFighterBay(Outfit* tmp, const xmlNodePtr parent); static void outfit_parseSFighterBay(Outfit* tmp, const xmlNodePtr parent);
static void outfit_parseSFighter(Outfit* tmp, const xmlNodePtr parent); static void outfit_parseSFighter(Outfit* tmp, const xmlNodePtr parent);
static void outfit_parseSMap(Outfit* tmp, const xmlNodePtr parent); static void outfit_parseSMap(Outfit* tmp, const xmlNodePtr parent);
static void outfit_parseSLicense(Outfit* tmp, const xmlNodePtr parent);
/* Return an outfit. */ /* Return an outfit. */
Outfit* outfit_get(const char* name) { Outfit* outfit_get(const char* name) {
@ -302,6 +303,14 @@ int outfit_isMap(const Outfit* o) {
return(o->type == OUTFIT_TYPE_MAP); return(o->type == OUTFIT_TYPE_MAP);
} }
/**
* @brief Check if outfit is a licence.
* @param o Outfit to check.
* @return 1 if o is a map.
*/
int outfit_isLicense(const Outfit* o) {
return (o->type == OUTFIT_TYPE_LICENSE);
}
/** /**
* @fn glTexture* outfit_gfx(const Outfit* o) * @fn glTexture* outfit_gfx(const Outfit* o)
@ -446,7 +455,8 @@ const char* outfit_getType(const Outfit* o) {
"Jammer", "Jammer",
"Fighter Bay", "Fighter Bay",
"Fighter", "Fighter",
"Map" "Map",
"License"
}; };
return outfit_typename[o->type]; return outfit_typename[o->type];
@ -471,6 +481,7 @@ const char* outfit_getTypeBroad(const Outfit* o) {
else if(outfit_isFighterBay(o)) return "Fighter Bay"; else if(outfit_isFighterBay(o)) return "Fighter Bay";
else if(outfit_isFighter(o)) return "Fighter"; else if(outfit_isFighter(o)) return "Fighter";
else if(outfit_isMap(o)) return "Map"; else if(outfit_isMap(o)) return "Map";
else if(outfit_isLicense(o)) return "License";
else return "Unknown"; else return "Unknown";
} }
@ -505,10 +516,11 @@ static OutfitType outfit_strToOutfitType(char* buf) {
O_CMP("missile swarm smart ammo", OUTFIT_TYPE_MISSILE_SWARM_SMART_AMMO); O_CMP("missile swarm smart ammo", OUTFIT_TYPE_MISSILE_SWARM_SMART_AMMO);
O_CMP("modification", OUTFIT_TYPE_MODIFICATION); O_CMP("modification", OUTFIT_TYPE_MODIFICATION);
O_CMP("afterburner", OUTFIT_TYPE_AFTERBURNER); O_CMP("afterburner", OUTFIT_TYPE_AFTERBURNER);
O_CMP("map", OUTFIT_TYPE_MAP);
O_CMP("fighter bay", OUTFIT_TYPE_FIGHTER_BAY); O_CMP("fighter bay", OUTFIT_TYPE_FIGHTER_BAY);
O_CMP("fighter", OUTFIT_TYPE_FIGHTER); O_CMP("fighter", OUTFIT_TYPE_FIGHTER);
O_CMP("jammer", OUTFIT_TYPE_JAMMER); O_CMP("jammer", OUTFIT_TYPE_JAMMER);
O_CMP("map", OUTFIT_TYPE_MAP);
O_CMP("license", OUTFIT_TYPE_LICENSE);
WARN("Invalid outfit type '%s'", buf); WARN("Invalid outfit type '%s'", buf);
return OUTFIT_TYPE_NULL; return OUTFIT_TYPE_NULL;
@ -835,6 +847,19 @@ static void outfit_parseSMap(Outfit* tmp, const xmlNodePtr parent) {
WARN("Outfit '%s' missing/invalid 'radius' element", tmp->name); WARN("Outfit '%s' missing/invalid 'radius' element", tmp->name);
} }
/**
* @brief Parses the license tidbits of the outfit.
* @param tmp Outfit to finish loading.
* @param parent Outfit's parent node.
*/
static void outfit_parseSLicense(Outfit* tmp, const xmlNodePtr parent) {
/* Licenses have no specific tidbits. */
(void)tmp;
(void)parent;
}
/* Parses the jammer tidbits of the outfit. */ /* Parses the jammer tidbits of the outfit. */
static void outfit_parseSJammer(Outfit* tmp, const xmlNodePtr parent) { static void outfit_parseSJammer(Outfit* tmp, const xmlNodePtr parent) {
xmlNodePtr node; xmlNodePtr node;
@ -876,6 +901,7 @@ static int outfit_parse(Outfit* tmp, const xmlNodePtr parent) {
do { do {
xmlr_int(cur, "max", tmp->max); xmlr_int(cur, "max", tmp->max);
xmlr_int(cur, "tech", tmp->tech); xmlr_int(cur, "tech", tmp->tech);
xmlr_strd(cur, "license", tmp->license);
xmlr_int(cur, "mass", tmp->mass); xmlr_int(cur, "mass", tmp->mass);
xmlr_int(cur, "price", tmp->price); xmlr_int(cur, "price", tmp->price);
xmlr_strd(cur, "description", tmp->description); xmlr_strd(cur, "description", tmp->description);
@ -923,6 +949,8 @@ static int outfit_parse(Outfit* tmp, const xmlNodePtr parent) {
outfit_parseSFighter(tmp, node); outfit_parseSFighter(tmp, node);
else if(outfit_isMap(tmp)) else if(outfit_isMap(tmp))
outfit_parseSMap(tmp, node); outfit_parseSMap(tmp, node);
else if (outfit_isLicense(tmp))
outfit_parseSLicense(tmp, node);
} }
} while(xml_nextNode(node)); } while(xml_nextNode(node));
#define MELEMENT(o,s) if(o) WARN("Outfit '%s' missing '"s"' element", tmp->name) #define MELEMENT(o,s) if(o) WARN("Outfit '%s' missing '"s"' element", tmp->name)

View File

@ -37,6 +37,7 @@ typedef enum OutfitType_ {
OUTFIT_TYPE_FIGHTER_BAY, /**< Contains other ships. */ OUTFIT_TYPE_FIGHTER_BAY, /**< Contains other ships. */
OUTFIT_TYPE_FIGHTER, /**< Ship contained in FIGHTER BAY. */ OUTFIT_TYPE_FIGHTER, /**< Ship contained in FIGHTER BAY. */
OUTFIT_TYPE_MAP, /**< Give the player more knowledge about systems. */ OUTFIT_TYPE_MAP, /**< Give the player more knowledge about systems. */
OUTFIT_TYPE_LICENSE, /**< License that allows player to buy special stuff. */
OUTFIT_TYPE_SENTINEL /**< Indicates last type. */ OUTFIT_TYPE_SENTINEL /**< Indicates last type. */
} OutfitType; } OutfitType;
@ -231,6 +232,7 @@ typedef struct Outfit_ {
/* General specs. */ /* General specs. */
int max; /**< Max amount one can own. */ int max; /**< Max amount one can own. */
int tech; /**< Tech needed to sell it. */ int tech; /**< Tech needed to sell it. */
int license; /**< Licenses needed to buy it. */
int mass; /**< How much weapon capacity is needed. */ int mass; /**< How much weapon capacity is needed. */
/* Store stuff. */ /* Store stuff. */
@ -277,6 +279,7 @@ int outfit_isJammer(const Outfit* o);
int outfit_isFighterBay(const Outfit* o); int outfit_isFighterBay(const Outfit* o);
int outfit_isFighter(const Outfit* o); int outfit_isFighter(const Outfit* o);
int outfit_isMap(const Outfit* o); int outfit_isMap(const Outfit* o);
int outfit_isLicense(const Outfit* o);
const char* outfit_getType(const Outfit* o); const char* outfit_getType(const Outfit* o);
const char* outfit_getTypeBroad(const Outfit* o); const char* outfit_getTypeBroad(const Outfit* o);

View File

@ -59,6 +59,7 @@ extern double player_faceHyperspace(void);
extern void player_dead(void); extern void player_dead(void);
extern void player_destroyed(void); extern void player_destroyed(void);
extern int gui_load(const char* name); extern int gui_load(const char* name);
extern void player_addLicense(char* license);
/* Internal. */ /* Internal. */
static int pilot_getStackPos(const unsigned int id); static int pilot_getStackPos(const unsigned int id);
static void pilot_shootWeapon(Pilot* p, PilotOutfit* w); static void pilot_shootWeapon(Pilot* p, PilotOutfit* w);
@ -915,7 +916,14 @@ int pilot_addOutfit(Pilot* pilot, Outfit* outfit, int quantity) {
/* Special case if it's a map. */ /* Special case if it's a map. */
if(outfit_isMap(outfit)) { if(outfit_isMap(outfit)) {
map_map(NULL, outfit->u.map.radius); if(pilot == player) /* Only player can get it. */
map_map(NULL, outfit->u.map.radius);
return 1; /* Must return 1 for paying purposes. */
}
/* Special case if it's a license. */
else if(outfit_isLicense(outfit)) {
if(pilot == player) /* Only player can get it. */
player_addLicense(outfit->name);
return 1; /* Must return 1 for paying purposes. */ return 1; /* Must return 1 for paying purposes. */
} }

View File

@ -58,6 +58,10 @@ static double player_px, player_py, player_vx, player_vy, player_dir; /**< More
static int player_credits = 0; /**< Temp hack on create. */ static int player_credits = 0; /**< Temp hack on create. */
static char* player_mission = NULL; /**< More hack. */ static char* player_mission = NULL; /**< More hack. */
/* Licenses. */
static char** player_licenses = NULL; /**< Licenses player has. */
static int player_nlicenses = 0; /**< Number of licenses player has. */
/* /*
* Player sounds. * Player sounds.
*/ */
@ -226,6 +230,7 @@ static void gui_cleanup(void);
static int player_saveShip(xmlTextWriterPtr writer, Pilot* ship, char* loc); static int player_saveShip(xmlTextWriterPtr writer, Pilot* ship, char* loc);
static int player_parse(xmlNodePtr parent); static int player_parse(xmlNodePtr parent);
static int player_parseDone(xmlNodePtr parent); static int player_parseDone(xmlNodePtr parent);
static int player_parseLicenses(xmlNodePtr parent);
static int player_parseShip(xmlNodePtr parent, int is_player); static int player_parseShip(xmlNodePtr parent, int is_player);
/* Externed. */ /* Externed. */
@ -631,6 +636,15 @@ void player_cleanup(void) {
missions_mdone = 0; missions_mdone = 0;
} }
/* Clean up licenses. */
if(player_nlicenses > 0) {
for(i = 0; i < player_nlicenses; i++)
free(player_licenses[i]);
free(player_licenses);
player_licenses = NULL;
player_nlicenses = 0;
}
pilots_cleanAll(); pilots_cleanAll();
if(player != NULL) { if(player != NULL) {
pilot_free(player); pilot_free(player);
@ -2320,27 +2334,63 @@ int player_missionAlreadyDone(int id) {
return 0; return 0;
} }
/**
* @brief Check to see if player has license.
* @param license License to check to see if the player has.
* @return 1 if has license, 0 if doesn't.
*/
int player_hasLicense(char* license) {
int i;
for(i = 0; i < player_nlicenses; i++)
if(strcmp(license, player_licenses[i])==0)
return 1;
return 0;
}
/**
* @brief Give the player a license.
* @brief license License to give the player.
*/
void player_addLicense(char* license) {
/* Player already has license. */
if(player_hasLicense(license))
return;
/* Add the license. */
player_nlicenses++;
player_licenses = realloc(player_licenses, sizeof(char*)*player_nlicenses);
player_licenses[player_nlicenses-1] = strdup(license);
}
/* Save the player in a freaking xmlfile. */ /* Save the player in a freaking xmlfile. */
int player_save(xmlTextWriterPtr writer) { int player_save(xmlTextWriterPtr writer) {
int i; int i;
MissionData* m; MissionData* m;
xmlw_startElem(writer, "player"); xmlw_startElem(writer, "player");
xmlw_attr(writer, "name", player_name);
/* Standard player details. */
xmlw_attr(writer, "name", player_name);
xmlw_elem(writer, "rating", "%f", player_crating); xmlw_elem(writer, "rating", "%f", player_crating);
xmlw_elem(writer, "scred", "%d", player->credits); xmlw_elem(writer, "credits", "%d", player->credits);
xmlw_elem(writer, "time", "%d", ltime_get()); xmlw_elem(writer, "time", "%d", ltime_get());
/* Current ship. */
xmlw_elem(writer, "location", land_planet->name); xmlw_elem(writer, "location", land_planet->name);
player_saveShip(writer, player, NULL); /* Current ship. */ player_saveShip(writer, player, NULL); /* Current ship. */
/* Ships. */
xmlw_startElem(writer, "ships"); xmlw_startElem(writer, "ships");
for(i = 0; i < player_nstack; i++) for(i = 0; i < player_nstack; i++)
player_saveShip(writer, player_stack[i], player_lstack[i]); player_saveShip(writer, player_stack[i], player_lstack[i]);
xmlw_endElem(writer); /* Player. */ xmlw_endElem(writer); /* Player. */
/* Licenses. */
xmlw_startElem(writer, "licenses");
for(i = 0; i < player_nlicenses; i++)
xmlw_elem(writer, "license", player_licenses[i]);
xmlw_endElem(writer) /* "license" */
/* Mission the player has done. */ /* Mission the player has done. */
xmlw_startElem(writer, "missions_done"); xmlw_startElem(writer, "missions_done");
@ -2466,15 +2516,16 @@ static int player_parse(xmlNodePtr parent) {
if(xml_isNode(node, "ship")) if(xml_isNode(node, "ship"))
player_parseShip(node, 1); player_parseShip(node, 1);
if(xml_isNode(node, "ships")) { else if(xml_isNode(node, "ships")) {
cur = node->xmlChildrenNode; cur = node->xmlChildrenNode;
do { do {
if(xml_isNode(cur, "ship")) if(xml_isNode(cur, "ship"))
player_parseShip(cur, 0); player_parseShip(cur, 0);
} while(xml_nextNode(cur)); } while(xml_nextNode(cur));
} }
if(xml_isNode(node, "missions_done")) else if(xml_isNode(node, "licenses"))
player_parseDone(node); player_parseLicenses(node);
} while(xml_nextNode(node)); } while(xml_nextNode(node));
/* Set global thingies. */ /* Set global thingies. */
@ -2513,6 +2564,24 @@ static int player_parseDone(xmlNodePtr parent) {
return 0; return 0;
} }
/**
* @brief Parse player's licenses.
* @param parent Node of the licenses.
* @return 0 on success.
*/
static int player_parseLicenses(xmlNodePtr parent) {
xmlNodePtr node;
node = parent->xmlChildrenNode;
do {
if(xml_isNode(node, "license"))
player_addLicense(xml_get(node));
} while(xml_nextNode(node));
return 0;
}
static int player_parseShip(xmlNodePtr parent, int is_player) { static int player_parseShip(xmlNodePtr parent, int is_player) {
char* name, *model, *loc, *q, *id; char* name, *model, *loc, *q, *id;
int i, n; int i, n;

View File

@ -71,6 +71,10 @@ void player_rmShip(char* shipname);
void player_missionFinished(int id); void player_missionFinished(int id);
int player_missionAlreadyDone(int id); int player_missionAlreadyDone(int id);
/* Licenses. */
void player_addLicense(char* license);
int player_hasLicense(char* license);
/* Keybind actions. */ /* Keybind actions. */
void player_targetHostile(void); void player_targetHostile(void);
void player_targetNext(void); void player_targetNext(void);

View File

@ -273,8 +273,9 @@ static Ship* ship_parse(xmlNodePtr parent) {
if(xml_isNode(node, "class")) { if(xml_isNode(node, "class")) {
tmp->class = ship_classFromString(xml_get(node)); tmp->class = ship_classFromString(xml_get(node));
} }
xmlr_int(node, "price", tmp->price); xmlr_int( node, "price", tmp->price);
xmlr_int(node, "tech", tmp->tech); xmlr_int( node, "tech", tmp->tech);
xmlr_strd(node, "license", tmp->license);
xmlr_strd(node, "fabricator", tmp->fabricator); xmlr_strd(node, "fabricator", tmp->fabricator);
xmlr_strd(node, "description", tmp->description); xmlr_strd(node, "description", tmp->description);
if(xml_isNode(node, "movement")) { if(xml_isNode(node, "movement")) {

View File

@ -52,10 +52,11 @@ typedef struct Ship_ {
ShipClass class; /* Ship class. */ ShipClass class; /* Ship class. */
/* Store stuff. */ /* Store stuff. */
unsigned int price; /* Price! */ unsigned int price; /**< Price! */
int tech; int tech; /**< Tech needed for it to be availabe. See space.c */
char* fabricator; /* Manufacturer. */ char* license; /**< License needed to buy it. */
char* description; /* Sales pitch. */ char* fabricator; /**< Manufacturer. */
char* description; /**< Sales pitch. */
/* Movement. */ /* Movement. */
double thrust, turn, speed; double thrust, turn, speed;