[Change] New philosophy. When you swap ships, your cargo should stay with you, will fix issues. Also, major outfit add/rm cleanup.

This commit is contained in:
Allanis 2013-06-03 22:22:50 +01:00
parent f749e6b10f
commit 493f67691e
7 changed files with 141 additions and 57 deletions

View File

@ -587,7 +587,7 @@ static int ai_minbrakedist(lua_State* L) {
} }
static int ai_cargofree(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; return 1;
} }

View File

@ -116,7 +116,7 @@ static void board_stealCargo(char* str) {
player_message("The ship has no cargo."); player_message("The ship has no cargo.");
return; return;
} }
else if(player->cargo_free <= 0) { else if(pilot_cargoFree(player) <= 0) {
player_message("You have no room for cargo."); player_message("You have no room for cargo.");
return; return;
} }

View File

@ -86,7 +86,9 @@ static void commodity_sell(char* str);
static void outfits(void); static void outfits(void);
static void outfits_close(char* str); static void outfits_close(char* str);
static void outfits_update(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 void outfits_buy(char* str);
static int outfit_canSell(Outfit* outfit, int q, int errmsg);
static void outfits_sell(char* str); static void outfits_sell(char* str);
static int outfits_getMod(void); static int outfits_getMod(void);
static void outfits_renderMod(double bx, double by, double w, double h); 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", "%d tons\n",
player_cargoOwned(comname), player_cargoOwned(comname),
com->medium, com->medium,
player->cargo_free); pilot_cargoFree(player));
window_modifyText(secondary_wid, "txtDInfo", buf); window_modifyText(secondary_wid, "txtDInfo", buf);
window_modifyText(secondary_wid, "txtDesc", com->description); window_modifyText(secondary_wid, "txtDesc", com->description);
@ -211,7 +213,7 @@ static void commodity_buy(char* str) {
dialogue_alert("Not enough Scred!"); dialogue_alert("Not enough Scred!");
return; return;
} }
else if(player->cargo_free <= 0) { else if(pilot_cargoFree(player) <= 0) {
dialogue_alert("not enough free space!"); dialogue_alert("not enough free space!");
return; return;
} }
@ -320,11 +322,16 @@ static void outfits_update(char* str) {
window_modifyImage(secondary_wid, "imgOutfit", outfit->gfx_store); window_modifyImage(secondary_wid, "imgOutfit", outfit->gfx_store);
// Gray out sell button. if(outfit_canBuy(outfit, 1, 0) > 0)
if(player_outfitOwned(outfitname) == 0) window_enableButton(secondary_wid, "btnBuyOutfit");
window_disableButton(secondary_wid, "btnSellOutfit");
else else
window_disableButton(secondary_wid, "btnBuyOutfit");
// Gray out sell button.
if(outfit_canSell(outfit, 1, 0) > 0)
window_enableButton(secondary_wid, "btnSellOutfit"); window_enableButton(secondary_wid, "btnSellOutfit");
else
window_disableButton(secondary_wid, "btnSellOutfit");
// New text. // New text.
window_modifyText(secondary_wid, "txtDescription", outfit->description); window_modifyText(secondary_wid, "txtDescription", outfit->description);
@ -351,45 +358,87 @@ static void outfits_update(char* str) {
window_modifyText(secondary_wid, "txtDDesc", buf); 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) { static void outfits_buy(char* str) {
(void)str; (void)str;
char* outfitname; char* outfitname;
Outfit* outfit; Outfit* outfit;
int q; int q;
char buf[16];
outfitname = toolkit_getList(secondary_wid, "lstOutfits"); outfitname = toolkit_getList(secondary_wid, "lstOutfits");
outfit = outfit_get(outfitname); outfit = outfit_get(outfitname);
q = outfits_getMod(); q = outfits_getMod();
// Can player actually fit the outfit? // Can buy the outfit?
if((pilot_freeSpace(player) - outfit->mass) < 0) { if(outfit_canBuy(outfit, q, 1) == 0) return;
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;
}
player->credits -= outfit->price * pilot_addOutfit(player, outfit, player->credits -= outfit->price * pilot_addOutfit(player, outfit,
MIN(q, outfit->max)); MIN(q, outfit->max));
outfits_update(NULL); 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) { static void outfits_sell(char* str) {
(void)str; (void)str;
char* outfitname; char* outfitname;
@ -401,16 +450,8 @@ static void outfits_sell(char* str) {
q = outfits_getMod(); q = outfits_getMod();
if(player_outfitOwned(outfitname) <= 0) { // Has no outfits to sell.
// No outfits to sell. if(outfit_canSell(outfit, q, 1) == 0) return;
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;
}
player->credits += outfit->price * pilot_rmOutfit(player, outfit, q); player->credits += outfit->price * pilot_rmOutfit(player, outfit, q);
outfits_update(NULL); outfits_update(NULL);
@ -567,6 +608,11 @@ static void shipyard_buy(char* str) {
shipname = toolkit_getList(secondary_wid, "lstShipyard"); shipname = toolkit_getList(secondary_wid, "lstShipyard");
ship = ship_get(shipname); 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); credits2str(buf, ship->price, 2);
if(dialogue_YesNo("Are you sure?", if(dialogue_YesNo("Are you sure?",
"Do you really want to spend %s on a new ship?", buf)==0) "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->ship->name,
ship_class(ship->ship), ship_class(ship->ship),
loc, loc,
ship->cargo_free, pilot_cargoFree(ship),
pilot_freeSpace(ship), pilot_freeSpace(ship),
buf2, buf2,
buf3); buf3);
@ -712,8 +758,10 @@ static void shipyard_yoursUpdate(char* str) {
static void shipyard_yoursChange(char* str) { static void shipyard_yoursChange(char* str) {
(void)str; (void)str;
char* shipname, *loc; char* shipname, *loc;
Pilot* newship;
shipname = toolkit_getList(terciary_wid, "lstYourShips"); shipname = toolkit_getList(terciary_wid, "lstYourShips");
newship = player_getShip(shipname);
if(strcmp(shipname, "None")==0) { if(strcmp(shipname, "None")==0) {
// No ships. // No ships.
dialogue_alert("You need another ship to change to!"); dialogue_alert("You need another ship to change to!");
@ -727,6 +775,10 @@ static void shipyard_yoursChange(char* str) {
land_planet->name); land_planet->name);
return; 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); player_swapShip(shipname);

View File

@ -727,7 +727,7 @@ static int player_shipname(lua_State* L) {
} }
static int player_freeSpace(lua_State* L) { static int player_freeSpace(lua_State* L) {
lua_pushnumber(L, pilot_freeCargo(player)); lua_pushnumber(L, pilot_cargoFree(player));
return 1; return 1;
} }

View File

@ -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_update(Pilot* pilot, const double dt);
static void pilot_hyperspace(Pilot* pilot); static void pilot_hyperspace(Pilot* pilot);
void pilot_render(Pilot* pilot); void pilot_render(Pilot* pilot);
static void pilot_calcStats(Pilot* pilot);
static void pilot_calcCargo(Pilot* pilot); static void pilot_calcCargo(Pilot* pilot);
void pilot_free(Pilot* p); void pilot_free(Pilot* p);
static Fleet* fleet_parse(const xmlNodePtr parent); 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. // Remove an outfit from the pilot.
int pilot_rmOutfit(Pilot* pilot, Outfit* outfit, int quantity) { int pilot_rmOutfit(Pilot* pilot, Outfit* outfit, int quantity) {
int i, q; int i, q, c;
char* s; char* s;
c = (outfit_isMod(outfit)) ? outfit->u.mod.cargo : 0;
q = quantity; q = quantity;
for(i = 0; i < pilot->noutfits; i++) 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_setSecondary(pilot, s);
} }
pilot_calcStats(pilot); // Recalculate stats. pilot_calcStats(pilot); // Recalculate stats.
pilot->cargo_free -= c;
return q; return q;
} }
WARN("Failure attempting to remove %d '%s' from pilot '%s'", 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. // Recalculate the pilot's stats based on her outfits.
static void pilot_calcStats(Pilot* pilot) { void pilot_calcStats(Pilot* pilot) {
int i; int i;
double q; double q;
Outfit* o; Outfit* o;
@ -657,7 +658,7 @@ static void pilot_calcStats(Pilot* pilot) {
} }
// Pilot free cargo space. // Pilot free cargo space.
int pilot_freeCargo(Pilot* p) { int pilot_cargoFree(Pilot* p) {
return p->cargo_free; return p->cargo_free;
} }
@ -668,8 +669,8 @@ int pilot_addCargo(Pilot* pilot, Commodity* cargo, int quantity) {
q = quantity; q = quantity;
for(i = 0; i < pilot->ncommodities; i++) for(i = 0; i < pilot->ncommodities; i++)
if(!pilot->commodities[i].id && (pilot->commodities[i].commodity == cargo)) { if(!pilot->commodities[i].id && (pilot->commodities[i].commodity == cargo)) {
if(pilot->cargo_free < quantity) if(pilot_cargoFree(pilot) < quantity)
q = pilot->cargo_free; q = pilot_cargoFree(pilot);
pilot->commodities[i].quantity += q; pilot->commodities[i].quantity += q;
pilot->cargo_free -= q; pilot->cargo_free -= q;
pilot->solid->mass += q; pilot->solid->mass += q;
@ -680,8 +681,8 @@ int pilot_addCargo(Pilot* pilot, Commodity* cargo, int quantity) {
pilot->commodities = realloc(pilot->commodities, pilot->commodities = realloc(pilot->commodities,
sizeof(PilotCommodity) * (pilot->ncommodities+1)); sizeof(PilotCommodity) * (pilot->ncommodities+1));
pilot->commodities[pilot->ncommodities].commodity = cargo; pilot->commodities[pilot->ncommodities].commodity = cargo;
if(pilot->cargo_free < quantity) if(pilot_cargoFree(pilot) < quantity)
q = pilot->cargo_free; q = pilot_cargoFree(pilot);
pilot->commodities[pilot->ncommodities].id = 0; pilot->commodities[pilot->ncommodities].id = 0;
pilot->commodities[pilot->ncommodities].quantity = q; pilot->commodities[pilot->ncommodities].quantity = q;
pilot->cargo_free -= q; pilot->cargo_free -= q;
@ -690,13 +691,24 @@ int pilot_addCargo(Pilot* pilot, Commodity* cargo, int quantity) {
return q; return q;
} }
static void pilot_calcCargo(Pilot* pilot) { // Return the amount of cargo onboard the ship.
int pilot_cargoUsed(Pilot* pilot) {
int i, q; int i, q;
q = 0;
pilot->cargo_free = pilot->ship->cap_cargo; pilot->cargo_free = pilot->ship->cap_cargo;
for(i = 0; i < pilot->ncommodities; i++) for(i = 0; i < pilot->ncommodities; i++)
q += pilot->commodities[i].quantity; 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->cargo_free -= q; // Reduce space left.
pilot->solid->mass = pilot->ship->mass + q; // Cargo affects weight. 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, pilot->commodities = realloc(pilot->commodities,
sizeof(PilotCommodity) * (pilot->ncommodities+1)); sizeof(PilotCommodity) * (pilot->ncommodities+1));
pilot->commodities[pilot->ncommodities].commodity = cargo; pilot->commodities[pilot->ncommodities].commodity = cargo;
if(pilot->cargo_free < quantity) if(pilot_cargoFree(pilot) < quantity)
q = pilot->cargo_free; q = pilot_cargoFree(pilot);
pilot->commodities[pilot->ncommodities].id = ++mission_cargo_id; pilot->commodities[pilot->ncommodities].id = ++mission_cargo_id;
pilot->commodities[pilot->ncommodities].quantity = q; pilot->commodities[pilot->ncommodities].quantity = q;
pilot->cargo_free -= q; pilot->cargo_free -= q;
@ -837,7 +849,7 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, int faction,
pilot->credits = 0; pilot->credits = 0;
pilot->commodities = NULL; pilot->commodities = NULL;
pilot->ncommodities = 0; 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. // Set the pilot stats based on her ship and outfits.
// Hack to have full armour/shield/energy/fuel. // Hack to have full armour/shield/energy/fuel.

View File

@ -154,8 +154,10 @@ int pilot_freeSpace(Pilot* p); // Pilot space.
int pilot_addOutfit(Pilot* pilot, Outfit* outfit, int quantity); int pilot_addOutfit(Pilot* pilot, Outfit* outfit, int quantity);
int pilot_rmOutfit(Pilot* pilot, Outfit* outfit, int quantity); int pilot_rmOutfit(Pilot* pilot, Outfit* outfit, int quantity);
char* pilot_getOutfits(Pilot* pilot); char* pilot_getOutfits(Pilot* pilot);
void pilot_calcStats(Pilot* pilot);
// Normal cargo. // 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_addCargo(Pilot* pilot, Commodity* cargo, int quantity);
int pilot_rmCargo(Pilot* pilot, Commodity* cargo, int quantity); int pilot_rmCargo(Pilot* pilot, Commodity* cargo, int quantity);
// Mission cargo - Not to be confused with normal cargo. // Mission cargo - Not to be confused with normal cargo.

View File

@ -285,6 +285,8 @@ void player_newShip(Ship* ship, double px, double py,
// Change the players ship. // Change the players ship.
static void player_newShipMake(char* name) { static void player_newShipMake(char* name) {
Vec2 vp, vv; Vec2 vp, vv;
// Store the current ship if it exists.
if(player) { if(player) {
player_stack = realloc(player_stack, sizeof(Pilot*)*(player_nstack+1)); player_stack = realloc(player_stack, sizeof(Pilot*)*(player_nstack+1));
player_stack[player_nstack] = pilot_copy(player); player_stack[player_nstack] = pilot_copy(player);
@ -313,14 +315,30 @@ static void player_newShipMake(char* name) {
// Swaps the current ship with shipname. // Swaps the current ship with shipname.
void player_swapShip(char* shipname) { void player_swapShip(char* shipname) {
int i; int i, j;
Pilot* ship; Pilot* ship;
for(i = 0; i < player_nstack; i++) { for(i = 0; i < player_nstack; i++) {
if(strcmp(shipname, player_stack[i]->name)==0) { if(strcmp(shipname, player_stack[i]->name)==0) {
// Swap player and ship. // Swap player and ship.
ship = player_stack[i]; ship = player_stack[i];
// Move credits over.
ship->credits = player->credits; 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; player_stack[i] = player;
pilot_stack[0] = player = ship; pilot_stack[0] = player = ship;
gl_bindCamera(&player->solid->pos); // Let's not forget the camera. 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); i = gl_printWidth(&gl_smallFont, "%d", player->ship->cap_cargo);
gl_print(&gl_smallFont, gl_print(&gl_smallFont,
gui.misc.x + gui.misc.w - 8 - i, j, gui.misc.x + gui.misc.w - 8 - i, j,
NULL, "%d", player->cargo_free); NULL, "%d", pilot_cargoFree(player));
// Messages. // Messages.
x = gui.msg.x; x = gui.msg.x;