From 233b8b96f0b18414e914f8e52f4cfac4d60d1161 Mon Sep 17 00:00:00 2001 From: Allanis <allanis@saracraft.net> Date: Wed, 9 Apr 2014 20:55:15 +0100 Subject: [PATCH] [Add] Initial implentation of licenses, licenses are to be purchased before given permission to buy various ships/weapons. --- dat/outfit.xml | 13 +++++- dat/ship.xml | 1 + gfx/outfit/store/license.png | Bin 0 -> 16438 bytes src/land.c | 67 +++++++++++++++++++++-------- src/outfit.c | 32 +++++++++++++- src/outfit.h | 3 ++ src/pilot.c | 10 ++++- src/player.c | 81 ++++++++++++++++++++++++++++++++--- src/player.h | 4 ++ src/ship.c | 5 ++- src/ship.h | 9 ++-- 11 files changed, 190 insertions(+), 35 deletions(-) create mode 100644 gfx/outfit/store/license.png diff --git a/dat/outfit.xml b/dat/outfit.xml index a64d6a7..8d39786 100644 --- a/dat/outfit.xml +++ b/dat/outfit.xml @@ -656,5 +656,16 @@ By adding quite a dense layer of Plasteel to your ship you can increase it's stu <specific type="fighter"> <ship>Lancelot</ship> </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> diff --git a/dat/ship.xml b/dat/ship.xml index 12059eb..351c55c 100644 --- a/dat/ship.xml +++ b/dat/ship.xml @@ -326,6 +326,7 @@ <price>900000</price> <fabricator>Melendez Corp</fabricator> <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> <movement> <thrust>100</thrust> diff --git a/gfx/outfit/store/license.png b/gfx/outfit/store/license.png new file mode 100644 index 0000000000000000000000000000000000000000..adb8406ae663b1d02201f421747a721f2e402b0b GIT binary patch literal 16438 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 literal 0 HcmV?d00001 diff --git a/src/land.c b/src/land.c index e6afc6c..a28a573 100644 --- a/src/land.c +++ b/src/land.c @@ -270,7 +270,7 @@ static void outfits_open(void) { /* The descriptive text. */ window_addText(wid, 40+300+20, -60, - 80, 140, 0, "txtSDesc", &gl_smallFont, &cDConsole, + 80, 160, 0, "txtSDesc", &gl_smallFont, &cDConsole, "Name:\n" "Type:\n" "Owned:\n" @@ -279,12 +279,13 @@ static void outfits_open(void) { "Free Space:\n" "\n" "Price:\n" - "Money:\n"); + "Money:\n" + "License:\n"); 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", &gl_smallFont, NULL, NULL); @@ -327,14 +328,14 @@ static void outfits_update(unsigned int wid, char* str) { (void)str; char* outfitname; Outfit* outfit; - char buf[128], buf2[16], buf3[16]; + char buf[PATH_MAX], buf2[16], buf3[16]; outfitname = toolkit_getList(wid, "iarOutfits"); if(strcmp(outfitname, "None")==0) { /* No outfits. */ window_modifyImage(wid, "imgOutfit", NULL); window_disableButton(wid, "btnBuyOutfit"); window_disableButton(wid, "btnSellOutfit"); - snprintf(buf, 128, + snprintf(buf, PATH_MAX, "None\n" "NA\n" "NA\n" @@ -343,6 +344,7 @@ static void outfits_update(unsigned int wid, char* str) { "%d\n" "\n" "NA\n" + "MA\m" "NA\n", pilot_freeSpace(player)); window_modifyText(wid, "txtDDesc", buf); @@ -368,7 +370,7 @@ static void outfits_update(unsigned int wid, char* str) { window_modifyText(wid, "txtDescription", outfit->description); credits2str(buf2, outfit->price, 2); credits2str(buf3, player->credits, 2); - snprintf(buf, 128, + snprintf(buf, PATH_MAX, "%s\n" "%s\n" "%d\n" @@ -377,14 +379,16 @@ static void outfits_update(unsigned int wid, char* str) { "%d\n" "\n" "%s SCred\n" - "%s SCred\n", + "%s SCred\n" + "%s\n", outfit->name, outfit_getType(outfit), player_outfitOwned(outfitname), outfit->mass, pilot_freeSpace(player), buf2, - buf3); + buf3, + (outfit->license != NULL) ? outfit->license : "None"); window_modifyText(wid, "txtDDesc", buf); } @@ -425,11 +429,25 @@ static int outfit_canBuy(Outfit* outfit, int q, int errmsg) { } return 0; } + /* Map alrady mapped. */ else if(outfit_isMap(outfit) && map_isMapped(NULL, outfit->u.map.radius)) { if(errmsg != 0) dialogue_alert("You already own this map."); 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; } @@ -561,23 +579,24 @@ static void shipyard_open(void) { /* Text. */ window_addText(wid, 40+300+40, -55, - 80, 96, 0, "txtSDesc", &gl_smallFont, &cDConsole, + 80, 128, 0, "txtSDesc", &gl_smallFont, &cDConsole, "Name:\n" "Class:\n" "Fabricator:\n" "\n" "Price:\n" - "Money:\n"); + "Money:\n" + "License:\n"); 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", &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); if(nships <= 0) { @@ -614,7 +633,7 @@ static void shipyard_update(unsigned int wid, char* str) { (void)str; char* shipname; Ship* ship; - char buf[80], buf2[16], buf3[16]; + char buf[PATH_MAX], buf2[16], buf3[16]; shipname = toolkit_getList(wid, "iarShipyard"); @@ -623,12 +642,13 @@ static void shipyard_update(unsigned int wid, char* str) { window_modifyImage(wid, "imgTarget", NULL); window_disableButton(wid, "btnBuyShip"); window_disableButton(wid, "btnInfoShip"); - snprintf(buf, 80, + snprintf(buf, PATH_MAX, "None\n" "NA\n" "NA\n" "\n" "NA\n" + "NA\n" "NA\n"); window_modifyText(wid, "txtDDesc", buf); return; @@ -644,18 +664,20 @@ static void shipyard_update(unsigned int wid, char* str) { credits2str(buf2, ship->price, 2); credits2str(buf3, player->credits, 2); - snprintf(buf, 80, + snprintf(buf, PATH_MAX, "%s\n" "%s\n" "%s\n" "\n" "%s SCred\n" - "%s SCred\n", + "%s SCred\n" + "%s\n", ship->name, ship_class(ship), ship->fabricator, buf2, - buf3); + buf3, + (ship->license != NULL) ? ship->license : "None"); window_modifyText(wid, "txtDDesc", buf); @@ -686,6 +708,13 @@ static void shipyard_buy(unsigned int wid, char* str) { 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) { dialogue_alert("You won't have space to move your current cargo onto the new ship."); return; diff --git a/src/outfit.c b/src/outfit.c index b6ee512..d3c05cc 100644 --- a/src/outfit.c +++ b/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_parseSFighter(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. */ Outfit* outfit_get(const char* name) { @@ -302,6 +303,14 @@ int outfit_isMap(const Outfit* o) { 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) @@ -446,7 +455,8 @@ const char* outfit_getType(const Outfit* o) { "Jammer", "Fighter Bay", "Fighter", - "Map" + "Map", + "License" }; 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_isFighter(o)) return "Fighter"; else if(outfit_isMap(o)) return "Map"; + else if(outfit_isLicense(o)) return "License"; 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("modification", OUTFIT_TYPE_MODIFICATION); O_CMP("afterburner", OUTFIT_TYPE_AFTERBURNER); - O_CMP("map", OUTFIT_TYPE_MAP); O_CMP("fighter bay", OUTFIT_TYPE_FIGHTER_BAY); O_CMP("fighter", OUTFIT_TYPE_FIGHTER); O_CMP("jammer", OUTFIT_TYPE_JAMMER); + O_CMP("map", OUTFIT_TYPE_MAP); + O_CMP("license", OUTFIT_TYPE_LICENSE); WARN("Invalid outfit type '%s'", buf); 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); } +/** + * @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. */ static void outfit_parseSJammer(Outfit* tmp, const xmlNodePtr parent) { xmlNodePtr node; @@ -876,6 +901,7 @@ static int outfit_parse(Outfit* tmp, const xmlNodePtr parent) { do { xmlr_int(cur, "max", tmp->max); xmlr_int(cur, "tech", tmp->tech); + xmlr_strd(cur, "license", tmp->license); xmlr_int(cur, "mass", tmp->mass); xmlr_int(cur, "price", tmp->price); xmlr_strd(cur, "description", tmp->description); @@ -923,6 +949,8 @@ static int outfit_parse(Outfit* tmp, const xmlNodePtr parent) { outfit_parseSFighter(tmp, node); else if(outfit_isMap(tmp)) outfit_parseSMap(tmp, node); + else if (outfit_isLicense(tmp)) + outfit_parseSLicense(tmp, node); } } while(xml_nextNode(node)); #define MELEMENT(o,s) if(o) WARN("Outfit '%s' missing '"s"' element", tmp->name) diff --git a/src/outfit.h b/src/outfit.h index b6ea718..daa958f 100644 --- a/src/outfit.h +++ b/src/outfit.h @@ -37,6 +37,7 @@ typedef enum OutfitType_ { OUTFIT_TYPE_FIGHTER_BAY, /**< Contains other ships. */ OUTFIT_TYPE_FIGHTER, /**< Ship contained in FIGHTER BAY. */ 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. */ } OutfitType; @@ -231,6 +232,7 @@ typedef struct Outfit_ { /* General specs. */ int max; /**< Max amount one can own. */ int tech; /**< Tech needed to sell it. */ + int license; /**< Licenses needed to buy it. */ int mass; /**< How much weapon capacity is needed. */ /* Store stuff. */ @@ -277,6 +279,7 @@ int outfit_isJammer(const Outfit* o); int outfit_isFighterBay(const Outfit* o); int outfit_isFighter(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_getTypeBroad(const Outfit* o); diff --git a/src/pilot.c b/src/pilot.c index 1289844..c493041 100644 --- a/src/pilot.c +++ b/src/pilot.c @@ -59,6 +59,7 @@ extern double player_faceHyperspace(void); extern void player_dead(void); extern void player_destroyed(void); extern int gui_load(const char* name); +extern void player_addLicense(char* license); /* Internal. */ static int pilot_getStackPos(const unsigned int id); 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. */ 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. */ } diff --git a/src/player.c b/src/player.c index 15536b3..7c75571 100644 --- a/src/player.c +++ b/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 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. */ @@ -226,6 +230,7 @@ static void gui_cleanup(void); static int player_saveShip(xmlTextWriterPtr writer, Pilot* ship, char* loc); static int player_parse(xmlNodePtr parent); static int player_parseDone(xmlNodePtr parent); +static int player_parseLicenses(xmlNodePtr parent); static int player_parseShip(xmlNodePtr parent, int is_player); /* Externed. */ @@ -631,6 +636,15 @@ void player_cleanup(void) { 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(); if(player != NULL) { pilot_free(player); @@ -2320,27 +2334,63 @@ int player_missionAlreadyDone(int id) { 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. */ int player_save(xmlTextWriterPtr writer) { int i; MissionData* m; xmlw_startElem(writer, "player"); + + /* Standard player details. */ xmlw_attr(writer, "name", player_name); - 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()); + /* Current ship. */ xmlw_elem(writer, "location", land_planet->name); player_saveShip(writer, player, NULL); /* Current ship. */ + /* Ships. */ xmlw_startElem(writer, "ships"); for(i = 0; i < player_nstack; i++) player_saveShip(writer, player_stack[i], player_lstack[i]); - 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. */ xmlw_startElem(writer, "missions_done"); @@ -2466,15 +2516,16 @@ static int player_parse(xmlNodePtr parent) { if(xml_isNode(node, "ship")) player_parseShip(node, 1); - if(xml_isNode(node, "ships")) { + else if(xml_isNode(node, "ships")) { cur = node->xmlChildrenNode; do { if(xml_isNode(cur, "ship")) player_parseShip(cur, 0); } while(xml_nextNode(cur)); } - if(xml_isNode(node, "missions_done")) - player_parseDone(node); + else if(xml_isNode(node, "licenses")) + player_parseLicenses(node); + } while(xml_nextNode(node)); /* Set global thingies. */ @@ -2513,6 +2564,24 @@ static int player_parseDone(xmlNodePtr parent) { 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) { char* name, *model, *loc, *q, *id; int i, n; diff --git a/src/player.h b/src/player.h index d44f496..293c0d2 100644 --- a/src/player.h +++ b/src/player.h @@ -71,6 +71,10 @@ void player_rmShip(char* shipname); void player_missionFinished(int id); int player_missionAlreadyDone(int id); +/* Licenses. */ +void player_addLicense(char* license); +int player_hasLicense(char* license); + /* Keybind actions. */ void player_targetHostile(void); void player_targetNext(void); diff --git a/src/ship.c b/src/ship.c index 4001c4e..5f29bcc 100644 --- a/src/ship.c +++ b/src/ship.c @@ -273,8 +273,9 @@ static Ship* ship_parse(xmlNodePtr parent) { if(xml_isNode(node, "class")) { tmp->class = ship_classFromString(xml_get(node)); } - xmlr_int(node, "price", tmp->price); - xmlr_int(node, "tech", tmp->tech); + xmlr_int( node, "price", tmp->price); + xmlr_int( node, "tech", tmp->tech); + xmlr_strd(node, "license", tmp->license); xmlr_strd(node, "fabricator", tmp->fabricator); xmlr_strd(node, "description", tmp->description); if(xml_isNode(node, "movement")) { diff --git a/src/ship.h b/src/ship.h index d4830ae..f42dc9e 100644 --- a/src/ship.h +++ b/src/ship.h @@ -52,10 +52,11 @@ typedef struct Ship_ { ShipClass class; /* Ship class. */ /* Store stuff. */ - unsigned int price; /* Price! */ - int tech; - char* fabricator; /* Manufacturer. */ - char* description; /* Sales pitch. */ + unsigned int price; /**< Price! */ + int tech; /**< Tech needed for it to be availabe. See space.c */ + char* license; /**< License needed to buy it. */ + char* fabricator; /**< Manufacturer. */ + char* description; /**< Sales pitch. */ /* Movement. */ double thrust, turn, speed;