From 493f67691e800166c426d6a516ab65b054fab676 Mon Sep 17 00:00:00 2001 From: Allanis Date: Mon, 3 Jun 2013 22:22:50 +0100 Subject: [PATCH] [Change] New philosophy. When you swap ships, your cargo should stay with you, will fix issues. Also, major outfit add/rm cleanup. --- src/ai.c | 2 +- src/board.c | 2 +- src/land.c | 130 ++++++++++++++++++++++++++++++++++--------------- src/misn_lua.c | 2 +- src/pilot.c | 36 +++++++++----- src/pilot.h | 4 +- src/player.c | 22 ++++++++- 7 files changed, 141 insertions(+), 57 deletions(-) diff --git a/src/ai.c b/src/ai.c index 9588a0f..d863278 100644 --- a/src/ai.c +++ b/src/ai.c @@ -587,7 +587,7 @@ static int ai_minbrakedist(lua_State* L) { } static int ai_cargofree(lua_State* L) { - lua_pushnumber(L, cur_pilot->cargo_free); + lua_pushnumber(L, pilot_cargoFree(cur_pilot)); return 1; } diff --git a/src/board.c b/src/board.c index 55484c6..7660551 100644 --- a/src/board.c +++ b/src/board.c @@ -116,7 +116,7 @@ static void board_stealCargo(char* str) { player_message("The ship has no cargo."); return; } - else if(player->cargo_free <= 0) { + else if(pilot_cargoFree(player) <= 0) { player_message("You have no room for cargo."); return; } diff --git a/src/land.c b/src/land.c index f97ad81..f4c4906 100644 --- a/src/land.c +++ b/src/land.c @@ -86,7 +86,9 @@ static void commodity_sell(char* str); static void outfits(void); static void outfits_close(char* str); static void outfits_update(char* str); +static int outfit_canBuy(Outfit* outfit, int q, int errmsg); static void outfits_buy(char* str); +static int outfit_canSell(Outfit* outfit, int q, int errmsg); static void outfits_sell(char* str); static int outfits_getMod(void); static void outfits_renderMod(double bx, double by, double w, double h); @@ -190,7 +192,7 @@ static void commodity_update(char* str) { "%d tons\n", player_cargoOwned(comname), com->medium, - player->cargo_free); + pilot_cargoFree(player)); window_modifyText(secondary_wid, "txtDInfo", buf); window_modifyText(secondary_wid, "txtDesc", com->description); @@ -211,7 +213,7 @@ static void commodity_buy(char* str) { dialogue_alert("Not enough Scred!"); return; } - else if(player->cargo_free <= 0) { + else if(pilot_cargoFree(player) <= 0) { dialogue_alert("not enough free space!"); return; } @@ -320,11 +322,16 @@ static void outfits_update(char* str) { window_modifyImage(secondary_wid, "imgOutfit", outfit->gfx_store); - // Gray out sell button. - if(player_outfitOwned(outfitname) == 0) - window_disableButton(secondary_wid, "btnSellOutfit"); + if(outfit_canBuy(outfit, 1, 0) > 0) + window_enableButton(secondary_wid, "btnBuyOutfit"); else + window_disableButton(secondary_wid, "btnBuyOutfit"); + + // Gray out sell button. + if(outfit_canSell(outfit, 1, 0) > 0) window_enableButton(secondary_wid, "btnSellOutfit"); + else + window_disableButton(secondary_wid, "btnSellOutfit"); // New text. window_modifyText(secondary_wid, "txtDescription", outfit->description); @@ -351,45 +358,87 @@ static void outfits_update(char* str) { window_modifyText(secondary_wid, "txtDDesc", buf); } +static int outfit_canBuy(Outfit* outfit, int q, int errmsg) { + char buf[16]; + + // Can player actually fit the outfit? + if((pilot_freeSpace(player) - outfit->mass) < 0) { + if(errmsg != 0) + dialogue_alert("No enough free space (you need %d more slots).", + outfit->mass - pilot_freeSpace(player)); + return 0; + } + else if(player_outfitOwned(outfit->name) >= outfit->max) { + // Already has too many. + if(errmsg != 0) + dialogue_alert("You can only carry %d of this outfit.", outfit->max); + return 0; + } + else if(outfit_isAfterburner(outfit) && (player->afterburner != NULL)) { + if(errmsg != 0) + dialogue_alert("You can only have one afterburner."); + return 0; + } + // Takes away cargo space but you don't have any. + else if(outfit_isMod(outfit) && (outfit->u.mod.cargo < 0) + && (pilot_cargoFree(player) < -outfit->u.mod.cargo)) { + if(errmsg != 0) + dialogue_alert("You need to empty your cargo first."); + return 0; + } + // Not enough $$. + else if(q*(int)outfit->price >= player->credits) { + if(errmsg != 0) { + credits2str(buf, q*outfit->price - player->credits, 2); + dialogue_alert("You need %s more SCred.", buf); + } + return 0; + } + + return 1; +} + static void outfits_buy(char* str) { (void)str; char* outfitname; Outfit* outfit; int q; - char buf[16]; outfitname = toolkit_getList(secondary_wid, "lstOutfits"); outfit = outfit_get(outfitname); q = outfits_getMod(); - // Can player actually fit the outfit? - if((pilot_freeSpace(player) - outfit->mass) < 0) { - dialogue_alert("No enough free space (you need %d more slots).", - outfit->mass - pilot_freeSpace(player)); - return; - } - else if(player_outfitOwned(outfitname) >= outfit->max) { - // Already has too many. - dialogue_alert("You can only carry %d of this outfit.", outfit->max); - return; - } - else if(outfit_isAfterburner(outfit) && (player->afterburner != NULL)) { - dialogue_alert("You can only have one afterburner."); - return; - } - // Not enough $$. - else if(q*(int)outfit->price >= player->credits) { - credits2str(buf, q*outfit->price - player->credits, 2); - dialogue_alert("You need %s more SCred.", buf); - return; - } + // Can buy the outfit? + if(outfit_canBuy(outfit, q, 1) == 0) return; player->credits -= outfit->price * pilot_addOutfit(player, outfit, - MIN(q, outfit->max)); + MIN(q, outfit->max)); outfits_update(NULL); } +static int outfit_canSell(Outfit* outfit, int q, int errmsg) { + // No outfits to sell. + if(player_outfitOwned(outfit->name) <= 0) { + if(errmsg != 0) + dialogue_alert("You can't sell something you don't have!"); + return 0; + } + // Can't sell when you are using it. + else if(outfit_isMod(outfit) && (pilot_cargoFree(player) < outfit->u.mod.cargo * q)) { + if(errmsg != 0) + dialogue_alert("You currently have cargo in this modification."); + return 0; + } + else if((outfit->mass < 0) && (pilot_freeSpace(player) < -outfit->mass)) { + if(errmsg != 0) + dialogue_alert("Get rid of other outfits first."); + return 0; + } + + return 1; +} + static void outfits_sell(char* str) { (void)str; char* outfitname; @@ -401,16 +450,8 @@ static void outfits_sell(char* str) { q = outfits_getMod(); - if(player_outfitOwned(outfitname) <= 0) { - // No outfits to sell. - dialogue_alert("You can't sell something you don't have!"); - return; - } - // Can't sell when you are using it. - else if(outfit_isMod(outfit) && (player->cargo_free < outfit->u.mod.cargo * q)) { - dialogue_alert("You currently have cargo in this modification."); - return; - } + // Has no outfits to sell. + if(outfit_canSell(outfit, q, 1) == 0) return; player->credits += outfit->price * pilot_rmOutfit(player, outfit, q); outfits_update(NULL); @@ -567,6 +608,11 @@ static void shipyard_buy(char* str) { shipname = toolkit_getList(secondary_wid, "lstShipyard"); ship = ship_get(shipname); + if(pilot_cargoUsed(player) > ship->cap_cargo) { + dialogue_alert("You won't have space to move your current cargo onto the new ship."); + return; + } + credits2str(buf, ship->price, 2); if(dialogue_YesNo("Are you sure?", "Do you really want to spend %s on a new ship?", buf)==0) @@ -685,7 +731,7 @@ static void shipyard_yoursUpdate(char* str) { ship->ship->name, ship_class(ship->ship), loc, - ship->cargo_free, + pilot_cargoFree(ship), pilot_freeSpace(ship), buf2, buf3); @@ -712,8 +758,10 @@ static void shipyard_yoursUpdate(char* str) { static void shipyard_yoursChange(char* str) { (void)str; char* shipname, *loc; + Pilot* newship; shipname = toolkit_getList(terciary_wid, "lstYourShips"); + newship = player_getShip(shipname); if(strcmp(shipname, "None")==0) { // No ships. dialogue_alert("You need another ship to change to!"); @@ -727,6 +775,10 @@ static void shipyard_yoursChange(char* str) { land_planet->name); return; } + else if(pilot_cargoUsed(player) > pilot_cargoFree(newship)) { + dialogue_alert("You won't be able to fit your current cago in the new ship."); + return; + } player_swapShip(shipname); diff --git a/src/misn_lua.c b/src/misn_lua.c index d9110a1..b6a8115 100644 --- a/src/misn_lua.c +++ b/src/misn_lua.c @@ -727,7 +727,7 @@ static int player_shipname(lua_State* L) { } static int player_freeSpace(lua_State* L) { - lua_pushnumber(L, pilot_freeCargo(player)); + lua_pushnumber(L, pilot_cargoFree(player)); return 1; } diff --git a/src/pilot.c b/src/pilot.c index e1d8759..6ef7894 100644 --- a/src/pilot.c +++ b/src/pilot.c @@ -54,7 +54,6 @@ static void pilot_shootWeapon(Pilot* p, PilotOutfit* w, const unsigned int t); static void pilot_update(Pilot* pilot, const double dt); static void pilot_hyperspace(Pilot* pilot); void pilot_render(Pilot* pilot); -static void pilot_calcStats(Pilot* pilot); static void pilot_calcCargo(Pilot* pilot); void pilot_free(Pilot* p); static Fleet* fleet_parse(const xmlNodePtr parent); @@ -537,9 +536,10 @@ int pilot_addOutfit(Pilot* pilot, Outfit* outfit, int quantity) { // Remove an outfit from the pilot. int pilot_rmOutfit(Pilot* pilot, Outfit* outfit, int quantity) { - int i, q; + int i, q, c; char* s; + c = (outfit_isMod(outfit)) ? outfit->u.mod.cargo : 0; q = quantity; for(i = 0; i < pilot->noutfits; i++) @@ -564,6 +564,7 @@ int pilot_rmOutfit(Pilot* pilot, Outfit* outfit, int quantity) { pilot_setSecondary(pilot, s); } pilot_calcStats(pilot); // Recalculate stats. + pilot->cargo_free -= c; return q; } WARN("Failure attempting to remove %d '%s' from pilot '%s'", @@ -594,7 +595,7 @@ char* pilot_getOutfits(Pilot* pilot) { } // Recalculate the pilot's stats based on her outfits. -static void pilot_calcStats(Pilot* pilot) { +void pilot_calcStats(Pilot* pilot) { int i; double q; Outfit* o; @@ -657,7 +658,7 @@ static void pilot_calcStats(Pilot* pilot) { } // Pilot free cargo space. -int pilot_freeCargo(Pilot* p) { +int pilot_cargoFree(Pilot* p) { return p->cargo_free; } @@ -668,8 +669,8 @@ int pilot_addCargo(Pilot* pilot, Commodity* cargo, int quantity) { q = quantity; for(i = 0; i < pilot->ncommodities; i++) if(!pilot->commodities[i].id && (pilot->commodities[i].commodity == cargo)) { - if(pilot->cargo_free < quantity) - q = pilot->cargo_free; + if(pilot_cargoFree(pilot) < quantity) + q = pilot_cargoFree(pilot); pilot->commodities[i].quantity += q; pilot->cargo_free -= q; pilot->solid->mass += q; @@ -680,8 +681,8 @@ int pilot_addCargo(Pilot* pilot, Commodity* cargo, int quantity) { pilot->commodities = realloc(pilot->commodities, sizeof(PilotCommodity) * (pilot->ncommodities+1)); pilot->commodities[pilot->ncommodities].commodity = cargo; - if(pilot->cargo_free < quantity) - q = pilot->cargo_free; + if(pilot_cargoFree(pilot) < quantity) + q = pilot_cargoFree(pilot); pilot->commodities[pilot->ncommodities].id = 0; pilot->commodities[pilot->ncommodities].quantity = q; pilot->cargo_free -= q; @@ -690,13 +691,24 @@ int pilot_addCargo(Pilot* pilot, Commodity* cargo, int quantity) { return q; } -static void pilot_calcCargo(Pilot* pilot) { +// Return the amount of cargo onboard the ship. +int pilot_cargoUsed(Pilot* pilot) { int i, q; + q = 0; pilot->cargo_free = pilot->ship->cap_cargo; for(i = 0; i < pilot->ncommodities; i++) q += pilot->commodities[i].quantity; + return q; +} + +// Calculate how much cargo ship has left etc. +static void pilot_calcCargo(Pilot* pilot) { + int q; + + q = pilot_cargoUsed(pilot); + pilot->cargo_free -= q; // Reduce space left. pilot->solid->mass = pilot->ship->mass + q; // Cargo affects weight. } @@ -708,8 +720,8 @@ unsigned int pilot_addMissionCargo(Pilot* pilot, Commodity* cargo, int quantity) pilot->commodities = realloc(pilot->commodities, sizeof(PilotCommodity) * (pilot->ncommodities+1)); pilot->commodities[pilot->ncommodities].commodity = cargo; - if(pilot->cargo_free < quantity) - q = pilot->cargo_free; + if(pilot_cargoFree(pilot) < quantity) + q = pilot_cargoFree(pilot); pilot->commodities[pilot->ncommodities].id = ++mission_cargo_id; pilot->commodities[pilot->ncommodities].quantity = q; pilot->cargo_free -= q; @@ -837,7 +849,7 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, int faction, pilot->credits = 0; pilot->commodities = NULL; pilot->ncommodities = 0; - pilot->cargo_free = pilot->ship->cap_cargo; + pilot->cargo_free = pilot->ship->cap_cargo; // should get redone with calcCargo. // Set the pilot stats based on her ship and outfits. // Hack to have full armour/shield/energy/fuel. diff --git a/src/pilot.h b/src/pilot.h index e9c4ceb..a1fa3e2 100644 --- a/src/pilot.h +++ b/src/pilot.h @@ -154,8 +154,10 @@ int pilot_freeSpace(Pilot* p); // Pilot space. int pilot_addOutfit(Pilot* pilot, Outfit* outfit, int quantity); int pilot_rmOutfit(Pilot* pilot, Outfit* outfit, int quantity); char* pilot_getOutfits(Pilot* pilot); +void pilot_calcStats(Pilot* pilot); // Normal cargo. -int pilot_freeCargo(Pilot* p); // Cargo space. +int pilot_cagoUsed(Pilot* pilot); // Get amount of cargo onboard. +int pilot_cargoFree(Pilot* p); // Cargo space. int pilot_addCargo(Pilot* pilot, Commodity* cargo, int quantity); int pilot_rmCargo(Pilot* pilot, Commodity* cargo, int quantity); // Mission cargo - Not to be confused with normal cargo. diff --git a/src/player.c b/src/player.c index 00a396e..1b1c734 100644 --- a/src/player.c +++ b/src/player.c @@ -285,6 +285,8 @@ void player_newShip(Ship* ship, double px, double py, // Change the players ship. static void player_newShipMake(char* name) { Vec2 vp, vv; + + // Store the current ship if it exists. if(player) { player_stack = realloc(player_stack, sizeof(Pilot*)*(player_nstack+1)); player_stack[player_nstack] = pilot_copy(player); @@ -313,14 +315,30 @@ static void player_newShipMake(char* name) { // Swaps the current ship with shipname. void player_swapShip(char* shipname) { - int i; + int i, j; 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]; + + // Move credits over. ship->credits = player->credits; + + // Move cargo over. + for(j = 0; j < player->ncommodities; j++) { + pilot_addCargo(ship, player->commodities[j].commodity, + player->commodities[j].quantity); + pilot_rmCargo(player, player->commodities[j].commodity, + player->commodities[j].quantity); + } + + // Extra pass to calculate stats. + pilot_calcStats(ship); + pilot_calcStats(player); + + // Now swap the players. player_stack[i] = player; pilot_stack[0] = player = ship; gl_bindCamera(&player->solid->pos); // Let's not forget the camera. @@ -720,7 +738,7 @@ void player_render(void) { i = gl_printWidth(&gl_smallFont, "%d", player->ship->cap_cargo); gl_print(&gl_smallFont, gui.misc.x + gui.misc.w - 8 - i, j, - NULL, "%d", player->cargo_free); + NULL, "%d", pilot_cargoFree(player)); // Messages. x = gui.msg.x;