From 99857ba716d7cf0b4c949dc19c8e109e231f8422 Mon Sep 17 00:00:00 2001 From: Allanis Date: Fri, 22 Mar 2013 23:28:16 +0000 Subject: [PATCH] [Add] Can now change ships once purchased more, and also have them transported to another planet. --- src/land.c | 169 ++++++++++++++++++++++++++++++++++++++++++++++++--- src/menu.c | 15 +---- src/pilot.c | 32 ++++++++++ src/pilot.h | 2 + src/player.c | 39 +++++++++--- src/player.h | 7 ++- 6 files changed, 236 insertions(+), 28 deletions(-) diff --git a/src/land.c b/src/land.c index 9da8276..5b35653 100644 --- a/src/land.c +++ b/src/land.c @@ -44,10 +44,6 @@ static int secondary_wid = 0; static int terciary_wid = 0; // For fancy things like news, your ship etc.. Planet* land_planet = NULL; -// Extern. -extern char** player_ships(int* nships); -extern Pilot* player_getShip(char* shipname); -// Static. // Commodity excahnge. static void commodity_exchange(void); static void commodity_exchange_close(char* str); @@ -71,6 +67,10 @@ static void shipyard_buy(char* str); // Your ship. static void shipyard_yours(char* str); static void shipyard_yoursClose(char* str); +static void shipyard_yoursUpdate(char* str); +static void shipyard_yoursChange(char* str); +static void shipyard_yoursTransport(char* str); +static char shipyard_yoursTransportPrice(char* shipname); // Spaceport bar. static void spaceport_bar(void); static void spaceport_bar_close(char* str); @@ -284,7 +284,7 @@ static void outfits_update(char* str) { outfit_getType(outfit), player_outfitOwned(outfitname), outfit->mass, - player_freeSpace(), + pilot_freeSpace(player), buf2, buf3); @@ -304,9 +304,9 @@ static void outfits_buy(char* str) { q = outfits_getMod(); // Can player actually fit the outfit? - if((player_freeSpace() - outfit->mass) < 0) { + if((pilot_freeSpace(player) - outfit->mass) < 0) { toolkit_alert("No enough free space (you need %d more slots).", - outfit->mass - player_freeSpace()); + outfit->mass - pilot_freeSpace(player)); return; } else if(player_outfitOwned(outfitname) >= outfit->max) { @@ -505,10 +505,50 @@ static void shipyard_yours(char* str) { BUTTON_WIDTH, BUTTON_HEIGHT, "btnCloseYourShips", "Shipyard", shipyard_yoursClose); + window_addButton(terciary_wid, -40-BUTTON_WIDTH, 20, + BUTTON_WIDTH, BUTTON_HEIGHT, "btnChangeShip", + "Change Ship", shipyard_yoursChange); + + window_addButton(terciary_wid, -40-BUTTON_WIDTH, 40+BUTTON_HEIGHT, + BUTTON_WIDTH, BUTTON_HEIGHT, "btnTransportShip", + "Transport Ship", shipyard_yoursTransport); + + window_addRect(terciary_wid, -40, -50, + 128, 96, "rctTarget", &cBlack, 0); + + window_addImage(terciary_wid, -40-128, -50-96, + "imgTarget", NULL, 1); + + window_addText(terciary_wid, 40+200+40, -55, + 100, 96, 0, "txtSDesc", &gl_smallFont, &cDConsole, + "Name:\n" + "Ship:\n" + "Class:\n" + "Location:\n" + "\n" + "Cargo free:\n" + "Weapons free\n" + "\n" + "Transportation\n" + "Sell price\n"); + + window_addText(terciary_wid, 40+200+40+100, -55, + 130, 96, 0, "txtDDesc", &gl_smallFont, &cBlack, NULL); + + window_addText(terciary_wid, 40+200+40, -215, + 100, 20, 0, "txtSOutfits", &gl_smallFont, &cDConsole, + "Outfits:\n"); + + window_addText(terciary_wid, 40+200+40, -215-gl_smallFont.h-5, + SHIPYARD_WIDTH-40-200-40-20, 200, 0, "txtDOutfits", + &gl_smallFont, &cBlack, NULL); + ships = player_ships(&nships); window_addList(terciary_wid, 20, 40, 200, SHIPYARD_HEIGHT-80, "lstYourShips", - ships, nships, 0, NULL); + ships, nships, 0, shipyard_yoursUpdate); + + shipyard_yoursUpdate(NULL); } static void shipyard_yoursClose(char* str) { @@ -516,6 +556,119 @@ static void shipyard_yoursClose(char* str) { window_destroy(terciary_wid); } +static void shipyard_yoursUpdate(char* str) { + (void)str; + char buf[256], buf2[16], buf3[16], *buf4; + char* shipname; + Pilot* ship; + char* loc; + + shipname = toolkit_getList(terciary_wid, "lstYourShips"); + if(strcmp(shipname, "None")==0) return; // No ships. + ship = player_getShip(shipname); + loc = player_getLoc(ship->name); + + // Update the image. + window_modifyImage(terciary_wid, "imgTarget", ship->ship->gfx_target); + + credits2str(buf2, (strcmp(loc, land_planet->name)==0) ? 0 : + shipyard_yoursTransportPrice(shipname), 2); // Transport. + + credits2str(buf3, 0, 2); // Sell price. + snprintf(buf, 80, + "%s\n" + "%s\n" + "%s\n" + "%s\n" + "\n" + "%d tons\n" + "%d tons\n" + "\n" + "%s scred\n" + "%s scred\n", + ship->name, + ship->ship->name, + ship_class(ship->ship), + loc, + ship->cargo_free, + pilot_freeSpace(ship), + buf2, + buf3); + + window_modifyText(terciary_wid, "txtDDesc", buf); + + buf4 = pilot_getOutfits(ship); + window_modifyText(terciary_wid, "txtDOutfits", buf4); + free(buf4); +} + +static void shipyard_yoursChange(char* str) { + (void)str; + char* shipname, *loc; + + shipname = toolkit_getList(terciary_wid, "lstYourShips"); + if(strcmp(shipname, "None")==0) { + // No ships. + toolkit_alert("You need another ship to change to!"); + return; + } + + loc = player_getLoc(shipname); + + if(strcmp(loc, land_planet->name)) { + toolkit_alert("You must transport the ship to %s to be able to get in.", + land_planet->name); + return; + } + + player_swapShip(shipname); + + // Recreate the window. + shipyard_yoursClose(NULL); + shipyard_yours(NULL); +} + +static void shipyard_yoursTransport(char* str) { + (void)str; + int price; + char* shipname, buf[16]; + + shipname = toolkit_getList(terciary_wid, "lstYourShips"); + if(strcmp(shipname, "None")==0) { // No ships. + toolkit_alert("You can't transport nothing here!"); + return; + } + + price = shipyard_yoursTransportPrice(shipname); + if(price == 0) { + // Already here. + toolkit_alert("Your ship '%s' is already here.", shipname); + return; + } + else if(player->credits < price) { + // You are broke. + credits2str(buf, price-player->credits, 2); + toolkit_alert("You need %d more credits to transport '%s' here.", + buf, shipname); + return; + } + + player->credits -= price; + player_setLoc(shipname, land_planet->name); +} + +static char shipyard_yoursTransportPrice(char* shipname) { + char* loc; + Pilot* ship; + + ship = player_getShip(shipname); + loc = player_getLoc(shipname); + if(strcmp(loc, land_planet->name)==0) // Already here. + return 0; + + return ship->solid->mass*500; +} + // Spaceport bar. static void spaceport_bar(void) { secondary_wid = window_create("SpacePort Bar", -1, -1, BAR_WIDTH, BAR_HEIGHT); diff --git a/src/menu.c b/src/menu.c index 084711f..b602d30 100644 --- a/src/menu.c +++ b/src/menu.c @@ -189,8 +189,7 @@ static void menu_info_close(char* str) { static void info_outfits_menu(char* str) { (void) str; - int i; - char buf[1024], buf2[64]; + char* buf; unsigned int wid; wid = window_create("Outfits", -1, -1, OUTFITS_WIDTH, OUTFITS_HEIGHT); @@ -198,20 +197,12 @@ static void info_outfits_menu(char* str) { 0, "txtLabel", &gl_smallFont, &cDConsole, "Ship Outfits:"); - buf[0] = '\0'; - if(player->noutfits > 0) - snprintf(buf, 1024, "%dx %s", - player->outfits[0].quantity, player->outfits[0].outfit->name); - - for(i = 1; i < player->noutfits; i++) { - snprintf(buf2, 64, ", %dx %s", - player->outfits[i].quantity, player->outfits[i].outfit->name); - strcat(buf, buf2); - } + buf = pilot_getOutfits(player); window_addText(wid, 20, -45-gl_smallFont.h, OUTFITS_WIDTH-40, OUTFITS_HEIGHT-60, 0, "txtOutfits", &gl_smallFont, &cBlack, buf); + free(buf); window_addButton(wid, -20, 20, BUTTON_WIDTH, BUTTON_HEIGHT, diff --git a/src/pilot.c b/src/pilot.c index cd81117..d32aadf 100644 --- a/src/pilot.c +++ b/src/pilot.c @@ -144,6 +144,17 @@ static int pilot_oquantity(Pilot* p, PilotOutfit* w) { p->secondary->quantity : w->quantity; } +// Get pilot's free weapon space. +int pilot_freeSpace(Pilot* p) { + int i, s; + + s = p->ship->cap_weapon; + for(i = 0; i < p->noutfits; i++) + s -= p->outfits[i].quantity * p->outfits[i].outfit->mass; + + return s; +} + // Mkay, this is how we shoot. Listen up. void pilot_shoot(Pilot* p, const unsigned int target, const int secondary) { int i; @@ -517,6 +528,27 @@ int pilot_rmOutfit(Pilot* pilot, Outfit* outfit, int quantity) { return 0; } +// Return all the outfits in a nice text form. +char* pilot_getOutfits(Pilot* pilot) { + int i; + char buf[64], *str; + + str = malloc(sizeof(char)*1024); + buf[0] = '\0'; + // First outfit. + if(pilot->noutfits > 0) + snprintf(str, 1024, "%dx %s", + pilot->outfits[0].quantity, pilot->outfits[0].outfit->name); + + // Rest of the outfits. + for(i = 1; i < pilot->noutfits; i++) { + snprintf(buf, 64, ", %dx %s", + pilot->outfits[i].quantity, pilot->outfits[i].outfit->name); + strcat(str, buf); + } + return str; +} + // Recalculate the pilot's stats based on her outfits. static void pilot_calcStats(Pilot* pilot) { int i; diff --git a/src/pilot.h b/src/pilot.h index ad43473..349a28c 100644 --- a/src/pilot.h +++ b/src/pilot.h @@ -135,8 +135,10 @@ void pilot_hit(Pilot* p, const Solid* w, const unsigned int shooter, void pilot_setSecondary(Pilot* p, const char* secondary); void pilot_setAmmo(Pilot* p); double pilot_face(Pilot* p, const float dir); +int pilot_freeSpace(Pilot* p); int pilot_addOutfit(Pilot* pilot, Outfit* outfit, int quantity); int pilot_rmOutfit(Pilot* pilot, Outfit* outfit, int quantity); +char* pilot_getOutfits(Pilot* pilot); int pilot_addCargo(Pilot* pilot, Commodity* cargo, int quantity); int pilot_rmCargo(Pilot* pilot, Commodity* cargo, int quantity); diff --git a/src/player.c b/src/player.c index 1964368..97abdf8 100644 --- a/src/player.c +++ b/src/player.c @@ -137,9 +137,6 @@ static void gui_renderBar(const glColour* c, const Rect* r, const double w); // Externed. void player_dead(void); void player_destroyed(void); -char** player_ships(int* nships); -Pilot* player_getShip(char* shipname); -char* player_getLoc(char* shipname); // Prompt player name. void player_new(void) { @@ -332,6 +329,25 @@ static void player_newShipMake(char* name) { gl_bindCamera(&player->solid->pos); // Set opengl camera. } +// Swaps the current ship with shipname. +void player_swapShip(char* shipname) { + int i; + Pilot* ship; + + for(i = 0; i < player_nstack; i++) { + if(strcmp(shipname, player_stack[i]->name)==0) { + // Swap player and ship. + ship = player_stack[i]; + ship->credits = player->credits; + player_stack[i] = player; + pilot_stack[0] = player = ship; + gl_bindCamera(&player->solid->pos); // Let's not forget the camera. + return; + } + } + WARN("Unable to swap player with ship '%s': Ship does not exist!", shipname); +} + // Clean up player stuff like player_stack. void player_cleanup(void) { int i; @@ -406,10 +422,6 @@ const char* player_rating(void) { else return player_ratings[7]; } -int player_freeSpace(void) { - // TODO: Get rid of it. -} - // Return amount of outfits the player owns. int player_outfitOwned(const char* outfitname) { int i; @@ -1378,3 +1390,16 @@ char* player_getLoc(char* shipname) { return NULL; } +void player_setLoc(char* shipname, char* loc) { + int i; + + for(i = 0; i < player_nstack; i++) { + if(strcmp(player_stack[i]->name, shipname)==0) { + free(player_lstack[i]); + player_lstack[i] = strdup(loc); + return; + } + } + WARN("Player ship '%s' not found in stack", shipname); +} + diff --git a/src/player.h b/src/player.h index ce529eb..2e67be2 100644 --- a/src/player.h +++ b/src/player.h @@ -46,10 +46,15 @@ void player_message(const char* fmt, ...); void player_clear(void); void player_warp(const double x, const double y); const char* player_rating(void); -int player_freeSpace(void); int player_outfitOwned(const char* outfitname); int player_cargoOwned(const char* commodityname); +char** player_ships(int* nships); +Pilot* player_getShip(char* shipname); +char* player_getLoc(char* shipname); +void player_setLoc(char* shipname, char* loc); +void player_swapShip(char* shipname); + // Keybind actions. void player_setRadarRel(int mod); void player_secondaryNext(void);