17#include "land_shipyard.h"
29#include "tk/toolkit_priv.h"
32#define SHIP_GFX_SIZE 256
37typedef struct CstShipSlotWidget_ {
66static int shipyard_canAcquire(
const Ship *ship,
const Spob *spob,
68static void shipyard_buy(
unsigned int wid,
const char *str );
70static void shipyard_rmouse(
unsigned int wid,
const char *widget_name );
75static int shipyard_mouseSlots(
unsigned int wid,
const SDL_Event *event,
76 double x,
double y,
double w,
double h,
77 double rx,
double ry,
void *data );
78static void shipyard_renderSlotsOver(
double bx,
double by,
double bw,
79 double bh,
void *data );
82static void preview_free(
void *ptr );
83static void preview_render(
double x,
double y,
double w,
double h,
85static int preview_mouse(
unsigned int wid,
const SDL_Event *event,
double x,
86 double y,
double w,
double h,
double rx,
double ry,
88static void preview_focusLose(
unsigned int wid,
const char *wgtname );
95 ImageArrayCell *cships;
99 int bw, bh, padding, off;
104 land_tabGenerate( LAND_WINDOW_SHIPYARD );
113 iw = 440 + ( w - LAND_WIDTH );
121 padding = 40 + 20 * 4;
124 bw =
MIN( LAND_BUTTON_WIDTH, ( w - iw - padding ) / 4 );
125 bh = LAND_BUTTON_HEIGHT;
129 window_addButtonKey( wid, off, 20, bw, bh,
"btnCloseShipyard",
132 window_addButtonKey( wid, off, 20, bw, bh,
"btnTradeShip", _(
"Trade-In" ),
135 window_addButtonKey( wid, off, 20, bw, bh,
"btnBuyShip", _(
"Buy" ),
138 window_addButtonKey( wid, off, 20, bw, bh,
"btnNaevpediaOutfits",
142 window_addRect( wid, -40 + 4, -40 + 4, sw + 8, sh + 8,
"rctTarget", &cBlack,
147 window_addCust( wid, -40, -40, sw, sh,
"cstPreview", 0, preview_render,
148 preview_mouse, NULL, preview_focusLose, pre );
149 window_custFreeDataFunc( wid,
"cstPreview", preview_free );
150 window_custSetClipping( wid,
"cstPreview", 0 );
154 window_addCust( wid, -20, -sh - 50, sw - 10, 80,
"cstSlots", 0.,
157 window_custSetOverlay( wid,
"cstSlots", shipyard_renderSlotsOver );
158 window_custSetClipping( wid,
"cstSlots", 0 );
160 window_custFreeDataFunc( wid,
"cstSlots", free );
163 window_addText( wid, -4, -sw - 50 - 70 - 20, sw, -sh - 60 - 70 - 20 + h - bh,
167 window_addText( wid, iw + 40, -35, 133, 427, 0,
"txtSDesc", &
gl_defFont,
169 window_addText( wid, iw + 173, -35, w - sw - iw - 208, 427, 0,
"txtDDesc",
171 window_addText( wid, 20 + iw + 20, -462, w - ( iw + 40 ) - ( sw + 40 ),
172 -482 + h - bh, 0,
"txtDescription", &
gl_defFont, NULL,
178 cships = calloc(
MAX( 1, nships ),
sizeof( ImageArrayCell ) );
180 cships[0].image = NULL;
181 cships[0].caption = strdup( _(
"None" ) );
186 for (
int i = 0; i < nships; i++ ) {
189 s->
flags |= SHIP_NEEDSGFX;
197 for (
int i = 0; i < nships; i++ ) {
209 if ( !conf.big_icons ) {
210 if ( toolkit_simImageArrayVisibleElements( iw, ih, iconsize, iconsize ) <
218 window_addImageArray( wid, 20, 20, iw, ih,
"iarShipyard", iconsize, iconsize,
235 int i, tw, th, y, w, h, sw, iw, bh;
237 char lbl[STRMAX], buf[STRMAX], buf_price[ECON_CRED_STRLEN],
238 buf_credits[ECON_CRED_STRLEN];
240 int blackmarket = ( (
land_spob != NULL ) &&
241 spob_hasService(
land_spob, SPOB_SERVICE_BLACKMARKET ) );
243 i = toolkit_getImageArrayPos( wid,
"iarShipyard" );
247 window_disableButton( wid,
"btnBuyShip" );
248 window_disableButton( wid,
"btnTradeShip" );
249 window_modifyText( wid,
"txtStats", NULL );
250 window_modifyText( wid,
"txtDescription", NULL );
251 window_modifyText( wid,
"txtSDesc", NULL );
252 window_modifyText( wid,
"txtDDesc", NULL );
265 window_custSetDynamic( wid,
"cstPreview",
269 window_modifyText( wid,
"txtStats", ship->
desc_stats );
273 k +=
scnprintf( &lbl[k],
sizeof( lbl ) - k,
"%s", _(
"Model:" ) );
274 l +=
scnprintf( &buf[l],
sizeof( buf ) - l,
"%s", _( ship->
name ) );
275 k +=
scnprintf( &lbl[k],
sizeof( lbl ) - k,
"\n%s", _(
"Class:" ) );
276 l +=
scnprintf( &buf[l],
sizeof( buf ) - l,
"\n%s",
278 k +=
scnprintf( &lbl[k],
sizeof( lbl ) - k,
"\n%s", _(
"Fabricator:" ) );
280 k +=
scnprintf( &lbl[k],
sizeof( lbl ) - k,
"\n%s", _(
"Crew:" ) );
281 l +=
scnprintf( &buf[l],
sizeof( buf ) - l,
"\n%d", ship->
crew );
282 if (
player.fleet_capacity > 0 ) {
283 k +=
scnprintf( &lbl[k],
sizeof( lbl ) - k,
"\n%s",
284 _(
"Fleet Capacity:" ) );
289 scnprintf( &lbl[k],
sizeof( lbl ) - k,
"\n\n%s", _(
"Base Properties" ) );
290 l +=
scnprintf( &buf[l],
sizeof( buf ) - l,
"\n\n%s",
"" );
291 if ( ship->
cpu > 0 ) {
292 k +=
scnprintf( &lbl[k],
sizeof( lbl ) - k,
"\n%s", _(
"CPU:" ) );
293 l +=
scnprintf( &buf[l],
sizeof( buf ) - l,
"\n%.0f %s", ship->
cpu,
297 char buf_mass[ECON_MASS_STRLEN];
299 k +=
scnprintf( &lbl[k],
sizeof( lbl ) - k,
"\n%s", _(
"Mass:" ) );
300 l +=
scnprintf( &buf[l],
sizeof( buf ) - l,
"\n%s", buf_mass );
303 k +=
scnprintf( &lbl[k],
sizeof( lbl ) - k,
"\n%s", _(
"Accel:" ) );
304 l +=
scnprintf( &buf[l],
sizeof( buf ) - l,
"\n" );
305 l +=
scnprintf( &buf[l],
sizeof( buf ) - l, _(
"%.0f %s" ), ship->
accel,
309 k +=
scnprintf( &lbl[k],
sizeof( lbl ) - k,
"\n%s", _(
"Speed:" ) );
310 l +=
scnprintf( &buf[l],
sizeof( buf ) - l,
"\n" );
311 l +=
scnprintf( &buf[l],
sizeof( buf ) - l, _(
"%.0f %s" ), ship->
speed,
315 k +=
scnprintf( &lbl[k],
sizeof( lbl ) - k,
"\n%s", _(
"Turn:" ) );
316 l +=
scnprintf( &buf[l],
sizeof( buf ) - l,
"\n" );
317 l +=
scnprintf( &buf[l],
sizeof( buf ) - l, _(
"%.0f %s" ),
318 ship->
turn * 180 / M_PI, UNIT_ROTATION );
322 scnprintf( &lbl[k],
sizeof( lbl ) - k,
"\n%s", _(
"Time Constant:" ) );
323 l +=
scnprintf( &buf[l],
sizeof( buf ) - l,
"\n%.0f%%",
328 k +=
scnprintf( &lbl[k],
sizeof( lbl ) - k,
"\n%s", _(
"Absorption:" ) );
329 l +=
scnprintf( &buf[l],
sizeof( buf ) - l,
"\n" );
330 l +=
scnprintf( &buf[l],
sizeof( buf ) - l, _(
"%.0f%% damage" ),
334 k +=
scnprintf( &lbl[k],
sizeof( lbl ) - k,
"\n%s", _(
"Shield:" ) );
335 l +=
scnprintf( &buf[l],
sizeof( buf ) - l,
"\n" );
337 scnprintf( &buf[l],
sizeof( buf ) - l, _(
"%.0f %s (%.1f %s)" ),
341 k +=
scnprintf( &lbl[k],
sizeof( lbl ) - k,
"\n%s", _(
"Armour:" ) );
342 l +=
scnprintf( &buf[l],
sizeof( buf ) - l,
"\n" );
344 scnprintf( &buf[l],
sizeof( buf ) - l, _(
"%.0f %s (%.1f %s)" ),
348 k +=
scnprintf( &lbl[k],
sizeof( lbl ) - k,
"\n%s", _(
"Energy:" ) );
349 l +=
scnprintf( &buf[l],
sizeof( buf ) - l,
"\n" );
351 scnprintf( &buf[l],
sizeof( buf ) - l, _(
"%.0f %s (%.1f %s)" ),
355 char buf_cargo[ECON_MASS_STRLEN];
357 k +=
scnprintf( &lbl[k],
sizeof( lbl ) - k,
"\n%s", _(
"Cargo Space:" ) );
358 l +=
scnprintf( &buf[l],
sizeof( buf ) - l,
"\n%s", buf_cargo );
361 k +=
scnprintf( &lbl[k],
sizeof( lbl ) - k,
"\n%s", _(
"Fuel:" ) );
362 l +=
scnprintf( &buf[l],
sizeof( buf ) - l,
"\n%d %s", ship->
fuel,
366 k +=
scnprintf( &lbl[k],
sizeof( lbl ) - k,
"\n%s", _(
"Fuel Use:" ) );
367 l +=
scnprintf( &buf[l],
sizeof( buf ) - l,
"\n%d %s",
371 k +=
scnprintf( &lbl[k],
sizeof( lbl ) - k,
"\n\n%s", _(
"Price:" ) );
372 l +=
scnprintf( &buf[l],
sizeof( buf ) - l,
"\n\n%s", buf_price );
373 k +=
scnprintf( &lbl[k],
sizeof( lbl ) - k,
"\n%s", _(
"Money:" ) );
374 l +=
scnprintf( &buf[l],
sizeof( buf ) - l,
"\n%s", buf_credits );
378 k +=
scnprintf( &lbl[k],
sizeof( lbl ) - k,
"\n%s", _(
"License:" ) );
380 l +=
scnprintf( &buf[l],
sizeof( buf ) - l,
"\n%s#0",
381 _(
"Not Necessary (Blackmarket)" ) );
383 l +=
scnprintf( &buf[l],
sizeof( buf ) - l,
"\n%s%s#0",
384 meets_reqs ?
"" :
"#r", _( ship->
license ) );
390 k +=
scnprintf( &lbl[k],
sizeof( lbl ) - k,
"\n%s", _(
"Requires:" ) );
392 l +=
scnprintf( &buf[l],
sizeof( buf ) - l,
"\n%s#0",
393 _(
"Not Necessary (Blackmarket)" ) );
395 l +=
scnprintf( &buf[l],
sizeof( buf ) - l,
"\n%s%s#0",
396 meets_reqs ?
"" :
"#r", _( ship->
condstr ) );
401 iw = 440 + ( w - LAND_WIDTH );
403 bh = LAND_BUTTON_HEIGHT;
407 window_modifyText( wid,
"txtSDesc", lbl );
410 window_modifyText( wid,
"txtDDesc", buf );
418 window_modifyText( wid,
"txtDescription", buf );
420 window_modifyText( wid,
"txtDescription", _( ship->
description ) );
422 w - ( 20 + iw + 20 ) - ( sw + 40 ), y - 20 + h - bh );
426 window_disableButtonSoft( wid,
"btnBuyShip" );
428 window_enableButton( wid,
"btnBuyShip" );
431 window_disableButtonSoft( wid,
"btnTradeShip" );
433 window_enableButton( wid,
"btnTradeShip" );
446static int shipyard_naevpedia_hook(
void *data )
449 naevpedia_open(
"ships" );
483 char buf[STRMAX_SHORT];
487 i = toolkit_getImageArrayPos( wid,
"iarShipyard" );
502 _(
"Do you really want to spend %s on a new ship?" ),
507 snprintf( buf,
sizeof( buf ), _(
"Bought at %s in the %s system." ),
519 hparam[0].
type = HOOK_PARAM_SHIP;
520 hparam[0].
u.
ship = ship;
521 hparam[1].
type = HOOK_PARAM_SENTINEL;
523 land_needsTakeoff( 1 );
526static int shipyard_canAcquire(
const Ship *ship,
const Spob *spob,
531 ( ( spob != NULL ) && spob_hasService( spob, SPOB_SERVICE_BLACKMARKET ) );
549 char buf[ECON_CRED_STRLEN];
565 return shipyard_canAcquire( ship, spob, price );
580 if ( ship_isFlag(
player.p->ship, SHIP_UNIQUE ) ) {
587 _(
"You can not trade in your ship when you have mission cargo!" ) );
590 return shipyard_canAcquire( ship, spob, price );
602 char buf[STRMAX_SHORT], buf2[ECON_CRED_STRLEN], buf3[ECON_CRED_STRLEN],
603 buf4[ECON_CRED_STRLEN];
606 i = toolkit_getImageArrayPos( wid,
"iarShipyard" );
627 if ( targetprice == playerprice ) {
629 _(
"Your %s is worth %s, exactly as much as the new "
630 "ship, so no credits need be exchanged. Are you "
631 "sure you want to trade your ship in?" ),
632 _(
player.p->ship->name ), buf2 ) == 0 )
634 }
else if ( targetprice < playerprice ) {
636 _(
"Your %s is worth %s, more than the new ship. "
637 "For your ship, you will get the new %s and %s. "
638 "Are you sure you want to trade your ship in?" ),
639 _(
player.p->ship->name ), buf2, _( ship->
name ),
642 }
else if ( targetprice > playerprice ) {
644 _(
"Are you sure?" ),
645 _(
"Your %s is worth %s, so the new ship will cost %s. Are you "
646 "sure you want to trade your ship in?" ),
647 _(
player.p->ship->name ), buf2, buf3 ) == 0 )
653 char *sname = strdup(
player.p->name );
656 snprintf( buf,
sizeof( buf ), _(
"Bought at %s in the %s system." ),
664 hparam[0].
type = HOOK_PARAM_SHIP;
665 hparam[0].
u.
ship = ssold;
666 hparam[1].
type = HOOK_PARAM_STRING;
667 hparam[1].
u.
str = sname;
668 hparam[2].
type = HOOK_PARAM_BOOL;
670 hparam[3].
type = HOOK_PARAM_SENTINEL;
672 hparam[0].
type = HOOK_PARAM_SHIP;
673 hparam[0].
u.
ship = ship;
674 hparam[1].
type = HOOK_PARAM_BOOL;
676 hparam[2].
type = HOOK_PARAM_SENTINEL;
755 if ( s[i].locked && !s[i].visible && ( s[i].data == NULL ) )
770 else if ( s[i].exclusive )
773 else if ( s[i].slot.spid != 0 )
780 icon =
sp_icon( s[i].slot.spid );
781 if ( icon != NULL ) {
786 if ( icon->
flags & OPENGL_TEX_SDF )
794static int shipyard_mouseSlots(
unsigned int wid,
const SDL_Event *event,
795 double mx,
double my,
double bw,
double bh,
796 double rx,
double ry,
void *data )
802 int x = floor( ( mx - 30. - 21. ) / 21. );
803 int y = floor( ( bh - my - 15. ) / 20. );
813 if ( event->type != SDL_MOUSEMOTION )
832 if ( ( x < 0 ) || ( x >=
array_size( ps ) ) ) {
840 wgt->alty = 30. + ( 2 - y ) * 20.;
841 wgt->altx = 15. + ( x + 2 ) * 21.;
845static void shipyard_renderSlotsOver(
double bx,
double by,
double bw,
846 double bh,
void *data )
850 char alt[STRMAX_SHORT];
855 if ( wgt->mouseover <= 0 )
861 pos =
scnprintf( alt,
sizeof( alt ),
"#o%s\n",
865 pos +=
scnprintf( &alt[pos],
sizeof( alt ) - pos, _(
"#%c%s #%c%s #0slot" ),
875static void preview_free(
void *ptr )
878 glDeleteFramebuffers( 1, &p->fbo );
879 glDeleteTextures( 1, &p->tex );
883static void preview_render(
double x,
double y,
double w,
double h,
void *data )
894 gl_renderTextureRaw( p->tex, OPENGL_TEX_VFLIP, x, y, w, h, 0., 0., 1., 1.,
898static int preview_mouse(
unsigned int wid,
const SDL_Event *event,
double mx,
899 double my,
double w,
double h,
double rx,
double ry,
908 switch ( event->type ) {
909 case SDL_MOUSEBUTTONUP:
913 case SDL_MOUSEBUTTONDOWN:
914 if ( ( mx < 0. ) || ( mx > w ) || ( my < 0. ) || ( my > h ) )
919 case SDL_MOUSEMOTION:
935static void preview_focusLose(
unsigned int wid,
const char *wgtname )
Provides macros to work with dynamic arrays.
#define array_free(ptr_array)
Frees memory allocated and sets array to NULL.
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
void credits2str(char *str, credits_t credits, int decimals)
Converts credits to a usable string for displaying.
void tonnes2str(char *str, int tonnes)
Converts tonnes to a usable string for displaying.
void price2str(char *str, credits_t price, credits_t credits, int decimals)
Given a price and on-hand credits, outputs a colourized string.
int cond_check(const char *cond)
Checks to see if a condition is true.
int dialogue_YesNo(const char *caption, const char *fmt,...)
Runs a dialogue with both yes and no options.
int gl_printHeightRaw(const glFont *ft_font, const int width, const char *text)
Gets the height of a non-formatted string.
int gl_printWidthRaw(const glFont *ft_font, const char *text)
Gets the width that it would take to print some text.
int gl_printMidRaw(const glFont *ft_font, int width, double x, double y, const glColour *c, double outlineR, const char *text)
Displays text centered in position and width.
void gl_print(const glFont *ft_font, const double x, const double y, const glColour *c, const char *fmt,...)
Prints text on screen like printf.
int hooks_runParam(const char *stack, const HookParam *param)
Runs all the hooks of stack.
unsigned int hook_addFunc(int(*func)(void *), void *data, const char *stack)
Adds a function hook to be run.
unsigned int land_getWid(int window)
Gets the WID of a window by type.
void land_errDialogueBuild(const char *fmt,...)
Generates error dialogues used by several landing tabs.
void land_errClear(void)
Clear error dialogues.
void land_buttonTakeoff(unsigned int wid, const char *unused)
Wrapper for takeoff mission button.
void land_refuel(void)
Refuels the player's current ship, if possible.
int land_errDisplay(void)
Displays an error if applicable.
static void shipyard_naevpedia(unsigned int wid, const char *str)
Starts the map find with ship search selected.
static void shipyard_renderSlotsRow(double bx, double by, double bw, const char *str, ShipOutfitSlot *s)
Renders a row of ship slots.
void shipyard_open(unsigned int wid)
Opens the shipyard window.
static void shipyard_rmouse(unsigned int wid, const char *widget_name)
Player right-clicks on a ship.
void shipyard_cleanup(void)
Cleans up shipyard data.
int shipyard_canBuy(const Ship *ship, const Spob *spob)
Makes sure it's valid to buy a ship.
static Ship ** shipyard_list
static void shipyard_renderSlots(double bx, double by, double bw, double bh, void *data)
Custom widget render function for the slot widget.
static void shipyard_buy(unsigned int wid, const char *str)
Player attempts to buy a ship.
void shipyard_update(unsigned int wid, const char *str)
Updates the ships in the shipyard window.
int shipyard_canTrade(const Ship *ship, const Spob *spob)
Makes sure it's valid to buy a ship, trading the old one in simultaneously.
static void shipyard_trade(unsigned int wid, const char *str)
Player attempts to buy a ship, trading the current ship in.
static Ship * shipyard_selected
Header file with generic functions and naev-specifics.
int scnprintf(char *text, size_t maxlen, const char *fmt,...)
Like snprintf(), but returns the number of characters ACTUALLY "printed" into the buffer....
void gl_renderSDF(const glTexture *texture, double x, double y, double w, double h, const glColour *c, double angle, double outline)
SDF Texture blitting backend.
void gl_renderScaleAspect(const glTexture *texture, double bx, double by, double bw, double bh, const glColour *c)
Blits a texture scaling it to fit a rectangle, but conserves aspect ratio.
void gl_renderTextureRaw(GLuint texture, uint8_t flags, double x, double y, double w, double h, double tx, double ty, double tw, double th, const glColour *c, double angle)
Texture blitting backend.
void gl_renderRectEmpty(double x, double y, double w, double h, const glColour *c)
Renders a rectangle.
int gl_fboCreate(GLuint *fbo, GLuint *tex, GLsizei width, GLsizei height)
Creates a framebuffer and its associated texture.
glTexture ** gl_addTexArray(glTexture **tex, glTexture *t)
Adds an element to a texture array.
glTexture ** gl_copyTexArray(glTexture **tex)
Copy a texture array.
char outfit_slotTypeColourFont(const OutfitSlot *os)
Gets a font colour character that roughly matches an outfit slot type colour.
char outfit_slotSizeColourFont(const OutfitSlot *os)
Gets a font colour character that roughly matches an outfit slot size colour.
const char * slotName(const OutfitSlotType type)
const char * slotSize(const OutfitSlotSize o)
Gets the slot size as a string.
glTexture * rarity_texture(int rarity)
const glColour * outfit_slotSizeColour(const OutfitSlot *os)
Gets the slot size colour for an outfit slot.
int pilot_cargoUsedMission(const Pilot *p)
Gets how much mission cargo ship has on board.
int player_hasLicense(const char *license)
Checks to see if player has license.
credits_t player_shipPrice(const char *shipname, int count_unique)
Calculates the price of one of the player's ships.
PlayerShip_t * player_newShip(const Ship *ship, const char *def_name, int trade, const char *acquired, int noname)
Creates a new ship for player.
credits_t player_modCredits(credits_t amount)
Modifies the amount of credits the player has.
int player_hasCredits(credits_t amount)
Checks to see if the player has enough credits.
const char * ship_classDisplay(const Ship *s)
Gets the ship's display class in human readable form.
credits_t ship_buyPrice(const Ship *s)
The ship buy price, includes default outfits.
int ship_gfxLoadNeeded(void)
Tries to load the graphics for all ships that need it.
int ship_gfxLoaded(const Ship *s)
Checks to see if a ship has loaded graphics.
int ship_gfxAnimated(const Ship *s)
Returns whether or not the ship has animated graphics.
glTexture * ship_gfxStore(const Ship *s, int size, double dir, double updown, double glow)
Get the store gfx.
const glTexture * sp_icon(unsigned int spid)
Gets the icon associated with the slot.
const char * sp_display(unsigned int spid)
Gets the display name of a slot property (in English).
const char * spob_name(const Spob *p)
Gets the translated name of a spob.
The actual hook parameter.
union HookParam::@325330313164266255110350307176363262300250041145 u
ShipOutfitSlot * outfit_utility
ShipOutfitSlot * outfit_weapon
ShipOutfitSlot * outfit_structure
Represents a Space Object (SPOB), including and not limited to planets, stations, wormholes,...
Abstraction for rendering sprite sheets.
Ship ** tech_getShip(const tech_group_t *tech)
Gets all of the ships associated to a tech group.