[Add] Initial implentation of licenses, licenses are to be purchased
before given permission to buy various ships/weapons.
This commit is contained in:
parent
f8701e4bdc
commit
233b8b96f0
@ -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 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>
|
</outfit>
|
||||||
</Outfits>
|
</Outfits>
|
||||||
|
@ -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>
|
||||||
|
BIN
gfx/outfit/store/license.png
Normal file
BIN
gfx/outfit/store/license.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
65
src/land.c
65
src/land.c
@ -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,19 +579,20 @@ 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);
|
||||||
|
|
||||||
@ -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;
|
||||||
|
32
src/outfit.c
32
src/outfit.c
@ -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)
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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,9 +916,16 @@ 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)) {
|
||||||
|
if(pilot == player) /* Only player can get it. */
|
||||||
map_map(NULL, outfit->u.map.radius);
|
map_map(NULL, outfit->u.map.radius);
|
||||||
return 1; /* Must return 1 for paying purposes. */
|
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. */
|
||||||
|
}
|
||||||
|
|
||||||
/* Mod quantity down if it doesn't fit. */
|
/* Mod quantity down if it doesn't fit. */
|
||||||
if(q*outfit->mass > free_space)
|
if(q*outfit->mass > free_space)
|
||||||
|
81
src/player.c
81
src/player.c
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -275,6 +275,7 @@ static Ship* ship_parse(xmlNodePtr parent) {
|
|||||||
}
|
}
|
||||||
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")) {
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user