naev 0.10.4
land_outfits.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
10#include <math.h>
11#include <stdio.h>
12#include <stdlib.h>
13
14#include "naev.h"
17#include "land_outfits.h"
18
19#include "array.h"
20#include "cond.h"
21#include "dialogue.h"
22#include "equipment.h"
23#include "hook.h"
24#include "log.h"
25#include "map.h"
26#include "map_find.h"
27#include "nstring.h"
28#include "nlua.h"
29#include "outfit.h"
30#include "player.h"
31#include "player_gui.h"
32#include "slots.h"
33#include "space.h"
34#include "toolkit.h"
35#include "utf8.h"
36
37#define OUTFITS_IAR "iarOutfits"
38#define OUTFITS_TAB "tabOutfits"
39#define OUTFITS_FILTER "inpFilterOutfits"
40#define OUTFITS_NTABS 6
41
42typedef struct LandOutfitData_ {
43 const Outfit **outfits;
45
46static iar_data_t *iar_data = NULL;
47static Outfit ***iar_outfits = NULL;
48static int outfit_Mode = 0;
50/* Modifier for buying and selling quantity. */
51static int outfits_mod = 1;
52
53/*
54 * Helper functions.
55 */
56static void outfits_getSize( unsigned int wid, int *w, int *h,
57 int *iw, int *ih, int *bw, int *bh );
58static void outfits_buy( unsigned int wid, const char *str );
59static void outfits_sell( unsigned int wid, const char *str );
60static int outfits_getMod (void);
61static void outfits_renderMod( double bx, double by, double w, double h, void *data );
62static void outfits_rmouse( unsigned int wid, const char* widget_name );
63static void outfits_find( unsigned int wid, const char *str );
64static const char *outfit_getPrice( const Outfit *outfit, credits_t *price, int *canbuy, int *cansell );
65static void outfit_Popdown( unsigned int wid, const char* str );
66static void outfits_genList( unsigned int wid );
67static void outfits_changeTab( unsigned int wid, const char *wgt, int old, int tab );
68static void outfits_onClose( unsigned int wid, const char *str );
69
73static void outfits_getSize( unsigned int wid, int *w, int *h,
74 int *iw, int *ih, int *bw, int *bh )
75{
76 int padding;
77
78 /* Get window dimensions. */
79 window_dimWindow( wid, w, h );
80
81 /* Calculate image array dimensions. */
82 if (iw != NULL)
83 *iw = 680 + (*w - LAND_WIDTH);
84 if (ih != NULL)
85 *ih = *h - 60;
86
87 /* Left padding + per-button padding * nbuttons */
88 padding = 40 + 20 * 4;
89
90 /* Calculate button dimensions. */
91 if (bw != NULL)
92 *bw = (*w - (iw!=NULL?*iw:0) - padding) / 4;
93 if (bh != NULL)
94 *bh = LAND_BUTTON_HEIGHT;
95}
96
100static void outfits_onClose( unsigned int wid, const char *str )
101{
102 (void) str;
103 LandOutfitData *data = window_getData( wid );
104 if (data==NULL)
105 return;
106 array_free( data->outfits );
107 free( data );
108}
109
117void outfits_open( unsigned int wid, const Outfit **outfits )
118{
119 int w, h, iw, ih, bw, bh, off;
120 LandOutfitData *data = NULL;
121
122 /* initialize the outfit mode. */
123 outfit_Mode = 0;
124
125 /* Set up window data. */
126 if (outfits!=NULL) {
127 data = malloc( sizeof( LandOutfitData ) );
128 data->outfits = outfits;
129 window_setData( wid, data );
131 }
132
133 /* Mark as generated. */
134 if (outfits==NULL)
135 land_tabGenerate(LAND_WINDOW_OUTFITS);
136
137 /* Get dimensions. */
138 outfits_getSize( wid, &w, &h, &iw, &ih, &bw, &bh );
139
140 /* Initialize stored positions. */
141 if (iar_data == NULL)
142 iar_data = calloc( OUTFITS_NTABS, sizeof(iar_data_t) );
143 else
144 memset( iar_data, 0, sizeof(iar_data_t) * OUTFITS_NTABS );
145 if (iar_outfits == NULL)
146 iar_outfits = calloc( OUTFITS_NTABS, sizeof(Outfit**) );
147 else {
148 for (int i=0; i<OUTFITS_NTABS; i++)
150 memset( iar_outfits, 0, sizeof(Outfit**) * OUTFITS_NTABS );
151 }
152
153 /* will allow buying from keyboard */
155
156 /* buttons */
157 off = -20;
158 if (data==NULL) {
159 window_addButtonKey( wid, off, 20,
160 bw, bh, "btnCloseOutfits",
161 _("Take Off"), land_buttonTakeoff, SDLK_t );
162 }
163 else {
164 window_addButtonKey( wid, off, 20,
165 bw, bh, "btnCloseOutfits",
166 _("Close"), window_close, SDLK_t );
167 }
168 off -= 20+bw;
169 window_addButtonKey( wid, off, 20,
170 bw, bh, "btnSellOutfit",
171 _("Sell"), outfits_sell, SDLK_s );
172 off -= 20+bw;
173 window_addButtonKey( wid, off, 20,
174 bw, bh, "btnBuyOutfit",
175 _("Buy"), outfits_buy, SDLK_b );
176 off -= 20+bw;
177 window_addButtonKey( wid, off, 20,
178 bw, bh, "btnFindOutfits",
179 _("Find Outfits"), outfits_find, SDLK_f );
180
181 /* fancy 256x256 image */
182 window_addRect( wid, -40+4, -40+4, 264, 264, "rctImage", &cBlack, 1 );
183 window_addImage( wid, -40, -40, 256, 256, "imgOutfit", NULL, 0 );
184
185 /* cust draws the modifier */
186 window_addCust( wid, -40-bw, 60+2*bh,
187 bw, bh, "cstMod", 0, outfits_renderMod, NULL, NULL, NULL, NULL );
188 window_canFocusWidget( wid, "cstMod", 0 );
189
190 /* the descriptive text */
191 window_addText( wid, 20 + iw + 20, -40,
192 w - (20 + iw + 20) - 264 - 40, 160, 0, "txtOutfitName", &gl_defFont, NULL, NULL );
193 window_addText( wid, 20 + iw + 20, -40 - gl_defFont.h*2. - 30,
194 w - (20 + iw + 20) - 264 - 40, 400, 0, "txtDescShort", &gl_defFont, NULL, NULL );
195
196 window_addText( wid, 20 + iw + 20, 0,
197 90, 160, 0, "txtSDesc", &gl_defFont, &cFontGrey, NULL );
198 window_addText( wid, 20 + iw + 20 + 90, 0,
199 w - (20 + iw + 20 + 90), 160, 0, "txtDDesc", &gl_defFont, NULL, NULL );
200 window_addText( wid, 20 + iw + 20, 0,
201 w-(iw+80), h, /* TODO: Size exactly and resize instead of moving? */
202 0, "txtDescription", &gl_defFont, NULL, NULL );
203
204 /* Create the image array. */
205 outfits_genList( wid );
206
207 /* Set default keyboard focus to the list */
208 window_setFocus( wid , OUTFITS_IAR );
209}
210
217void outfits_regenList( unsigned int wid, const char *str )
218{
219 (void) str;
220 int tab;
221 char *focused;
222 LandOutfitData *data;
223
224 /* If local or not. */
225 data = window_getData( wid );
226
227 /* Must exist. */
228 if ((data==NULL) && (land_getWid( LAND_WINDOW_OUTFITS ) == 0))
229 return;
230
231 /* Save focus. */
232 focused = window_getFocus( wid );
233
234 /* Save positions. */
235 tab = window_tabWinGetActive( wid, OUTFITS_TAB );
236 toolkit_saveImageArrayData( wid, OUTFITS_IAR, &iar_data[tab] );
237 window_destroyWidget( wid, OUTFITS_IAR );
238
239 outfits_genList( wid );
240
241 /* Restore positions. */
242 toolkit_setImageArrayPos( wid, OUTFITS_IAR, iar_data[tab].pos );
243 toolkit_setImageArrayOffset( wid, OUTFITS_IAR, iar_data[tab].offset );
244 outfits_update( wid, NULL );
245
246 /* Restore focus. */
247 window_setFocus( wid, focused );
248 free(focused);
249}
250
255static int outfitLand_filter( const Outfit *o ) {
256 Pilot *p;
257 const PlayerShip_t *ps;
258
259 switch (outfit_Mode) {
260 case 0:
261 return 1;
262
263 case 1: /* Fits any ship of the player. */
264 ps = player_getShipStack();
265 for (int j=0; j < array_size(ps); j++) {
266 p = ps[j].p;
267 for (int i=0; i < array_size(p->outfits); i++) {
268 if (outfit_fitsSlot( o, &p->outfits[i]->sslot->slot ))
269 return 1;
270 }
271 }
272 return 0;
273
274 case 2: /* Fits currently selected ship. */
275 p = player.p;
276 if (p==NULL)
277 return 1;
278 for (int i=0; i < array_size(p->outfits); i++) {
279 if (outfit_fitsSlot( o, &p->outfits[i]->sslot->slot ))
280 return 1;
281 }
282 return 0;
283
284 case 3:
285 return (o->slot.size==OUTFIT_SLOT_SIZE_LIGHT);
286 case 4:
287 return (o->slot.size==OUTFIT_SLOT_SIZE_MEDIUM);
288 case 5:
289 return (o->slot.size==OUTFIT_SLOT_SIZE_HEAVY);
290 }
291 return 1;
292}
293static int outfitLand_filterWeapon( const Outfit *o ) {
294 return outfitLand_filter(o) && outfit_filterWeapon(o);
295}
296static int outfitLand_filterUtility( const Outfit *o ) {
297 return outfitLand_filter(o) && outfit_filterUtility(o);
298}
299static int outfitLand_filterStructure( const Outfit *o ) {
300 return outfitLand_filter(o) && outfit_filterStructure(o);
301}
302static int outfitLand_filterCore( const Outfit *o ) {
303 return outfitLand_filter(o) && outfit_filterCore(o);
304}
305
311static void outfits_genList( unsigned int wid )
312{
313 int (*tabfilters[])( const Outfit *o ) = {
315 outfitLand_filterWeapon,
316 outfitLand_filterUtility,
317 outfitLand_filterStructure,
318 outfitLand_filterCore,
319 outfit_filterOther
320 };
321 const char *tabnames[] = {
322 _("All"), _(OUTFIT_LABEL_WEAPON), _(OUTFIT_LABEL_UTILITY), _(OUTFIT_LABEL_STRUCTURE), _(OUTFIT_LABEL_CORE), _("Other")
323 };
324
325 int active;
326 int fx, fy, fw, fh, barw; /* Input filter. */
327 ImageArrayCell *coutfits;
328 int noutfits;
329 int w, h, iw, ih;
330 const char *filtertext;
331 LandOutfitData *data;
332 int iconsize;
333
334 /* Get dimensions. */
335 outfits_getSize( wid, &w, &h, &iw, &ih, NULL, NULL );
336
337 /* Create tabbed window. */
338 if (!widget_exists( wid, OUTFITS_TAB )) {
339 window_addTabbedWindow( wid, 20, 20 + ih - 30, iw, 30,
340 OUTFITS_TAB, OUTFITS_NTABS, tabnames, 1 );
341
342 barw = window_tabWinGetBarWidth( wid, OUTFITS_TAB );
343 fw = CLAMP(0, 150, iw - barw - 30);
344 fh = 30;
345
346 fx = iw - fw + 15;
347 fy = ih - 25 -1 + 20;
348
349 /* Only create the filter widgets if it will be a reasonable size. */
350 if (iw >= 65) {
351 /* Add popdown menu stuff. */
352 window_addButton( wid, fx+fw-30, fy, 30, 30, "btnOutfitFilter", NULL, outfit_Popdown );
353 window_buttonCustomRender( wid, "btnOutfitFilter", window_buttonCustomRenderGear );
354 fw -= 35;
355
356 /* Set text filter. */
357 window_addInput( wid, fx, fy, fw, fh, OUTFITS_FILTER, 32, 1, &gl_defFont );
358 inp_setEmptyText( wid, OUTFITS_FILTER, _("Filter…") );
359 window_setInputCallback( wid, OUTFITS_FILTER, outfits_regenList );
360 }
361 }
362
363 window_tabWinOnChange( wid, OUTFITS_TAB, outfits_changeTab );
364 active = window_tabWinGetActive( wid, OUTFITS_TAB );
365
366 /* Widget must not already exist. */
367 if (widget_exists( wid, OUTFITS_IAR ))
368 return;
369
370 filtertext = NULL;
371 if (widget_exists( wid, OUTFITS_FILTER )) {
372 filtertext = window_getInput( wid, OUTFITS_FILTER );
373 if (strlen(filtertext) == 0)
374 filtertext = NULL;
375 }
376
377 /* Set up the outfits to buy/sell */
378 data = window_getData( wid );
379 array_free( iar_outfits[active] );
380 /* Use custom list; default to landed outfits. */
381 iar_outfits[active] = data!=NULL ? array_copy( Outfit*, data->outfits ) : tech_getOutfit( land_spob->tech );
382 noutfits = outfits_filter( (const Outfit**)iar_outfits[active], array_size(iar_outfits[active]), tabfilters[active], filtertext );
383 coutfits = outfits_imageArrayCells( (const Outfit**)iar_outfits[active], &noutfits, player.p );
384
385 iconsize = 128;
386 if (!conf.big_icons) {
387 if (toolkit_simImageArrayVisibleElements(iw,ih-34,iconsize,iconsize) < noutfits)
388 iconsize = 96;
389 if (toolkit_simImageArrayVisibleElements(iw,ih-34,iconsize,iconsize) < noutfits)
390 iconsize = 64;
391 }
392 window_addImageArray( wid, 20, 20,
393 iw, ih - 34, OUTFITS_IAR, iconsize, iconsize,
394 coutfits, noutfits, outfits_update, outfits_rmouse, NULL );
395
396 /* write the outfits stuff */
397 outfits_update( wid, NULL );
398}
399
405void outfits_update( unsigned int wid, const char *str )
406{
407 (void) str;
408 int i, active;
409 Outfit* outfit;
410 char buf[STRMAX], lbl[STRMAX], buf_credits[ECON_CRED_STRLEN], buf_mass[ECON_MASS_STRLEN];
411 const char *buf_price;
412 credits_t price;
413 size_t l = 0, k = 0;
414 int iw, ih, w, h, blackmarket, canbuy, cansell, sw, th;
415 double mass;
416 const char *summary;
417
418 /* Get dimensions. */
419 outfits_getSize( wid, &w, &h, &iw, &ih, NULL, NULL );
420
421 blackmarket = ((land_spob!=NULL) && spob_hasService( land_spob, SPOB_SERVICE_BLACKMARKET ));
422
423 /* Set up keys. */
424 k += scnprintf( &lbl[k], sizeof(lbl)-k, "%s", _("Owned:") );
425 k += scnprintf( &lbl[k], sizeof(lbl)-k, "\n%s", _("Mass:") );
426 k += scnprintf( &lbl[k], sizeof(lbl)-k, "\n%s", _("Price:") );
427 k += scnprintf( &lbl[k], sizeof(lbl)-k, "\n%s", _("Money:") );
428
429 /* Get and set parameters. */
430 active = window_tabWinGetActive( wid, OUTFITS_TAB );
431 i = toolkit_getImageArrayPos( wid, OUTFITS_IAR );
432 if (i < 0 || array_size(iar_outfits[active]) == 0) { /* No outfits */
433 window_modifyImage( wid, "imgOutfit", NULL, 256, 256 );
434 window_disableButton( wid, "btnBuyOutfit" );
435 window_disableButton( wid, "btnSellOutfit" );
436 l += scnprintf( &buf[l], sizeof(buf)-l, "%s", _("N/A") );
437 l += scnprintf( &buf[l], sizeof(buf)-l, "\n%s", _("N/A") );
438 l += scnprintf( &buf[l], sizeof(buf)-l, "\n%s", _("N/A") );
439 l += scnprintf( &buf[l], sizeof(buf)-l, "\n%s", _("N/A") );
440 window_modifyText( wid, "txtSDesc", buf );
441 window_modifyText( wid, "txtDDesc", buf );
442 window_modifyText( wid, "txtOutfitName", _("None") );
443 window_modifyText( wid, "txtDescShort", NULL );
444 window_modifyText( wid, "txtDescription", NULL );
445 /* Reposition. */
446 th = 260;
447 window_moveWidget( wid, "txtSDesc", 20+iw+20, -40-th-30-32 );
448 window_moveWidget( wid, "txtDDesc", 20+iw+20+90, -40-th-30-32 );
449 window_moveWidget( wid, "txtDescription", 20+iw+20, -240-32);
450 return;
451 }
452
453 outfit = iar_outfits[active][i];
454
455 /* new image */
456 window_modifyImage( wid, "imgOutfit", outfit->gfx_store, 256, 256 );
457
458 /* new text */
459 window_modifyText( wid, "txtDescription", pilot_outfitDescription( player.p, outfit ) );
460 buf_price = outfit_getPrice( outfit, &price, &canbuy, &cansell );
461 credits2str( buf_credits, player.p->credits, 2 );
462
463 /* gray out sell button */
464 if ((outfit_canSell(outfit->name) > 0) && cansell)
465 window_enableButton( wid, "btnSellOutfit" );
466 else
467 window_disableButtonSoft( wid, "btnSellOutfit" );
468
469 if ((outfit_canBuy(outfit->name, land_spob) > 0) && canbuy)
470 window_enableButton( wid, "btnBuyOutfit" );
471 else
472 window_disableButtonSoft( wid, "btnBuyOutfit" );
473
474 mass = outfit->mass;
475 if (outfit_isLauncher(outfit))
476 mass += outfit_amount(outfit) * outfit->u.lau.ammo_mass;
477 else if (outfit_isFighterBay(outfit))
478 mass += outfit_amount(outfit) * outfit->u.bay.ship_mass;
479 tonnes2str( buf_mass, (int)round( mass ) );
480
481 outfit_getNameWithClass( outfit, buf, sizeof(buf) );
482 window_modifyText( wid, "txtOutfitName", buf );
483 window_dimWidget( wid, "txtOutfitName", &sw, NULL );
484 th = gl_printHeightRaw( &gl_defFont, sw, buf )+gl_defFont.h/2;
485 l = 0;
486 l += scnprintf( &buf[l], sizeof(buf)-l, "%d", player_outfitOwned(outfit) );
487 l += scnprintf( &buf[l], sizeof(buf)-l, "\n%s", buf_mass );
488 l += scnprintf( &buf[l], sizeof(buf)-l, "\n%s", buf_price );
489 l += scnprintf( &buf[l], sizeof(buf)-l, "\n%s", buf_credits );
490 if (outfit->license) {
491 k += scnprintf( &lbl[k], sizeof(lbl)-k, "\n%s", _("License:") );
492 if (blackmarket || player_hasLicense( outfit->license ))
493 l += scnprintf( &buf[l], sizeof(buf)-l, "\n%s", _(outfit->license) );
494 else
495 l += scnprintf( &buf[l], sizeof(buf)-l, "\n#r%s#0", _(outfit->license) );
496 }
497 if (outfit->cond) {
498 k += scnprintf( &lbl[k], sizeof(lbl)-k, "\n%s", _("Requires:") );
499 if (cond_check(outfit->cond))
500 l += scnprintf( &buf[l], sizeof(buf)-l, "\n%s", _(outfit->condstr) );
501 else
502 l += scnprintf( &buf[l], sizeof(buf)-l, "\n#r%s#0", _(outfit->condstr) );
503 }
504 window_modifyText( wid, "txtSDesc", lbl );
505 window_modifyText( wid, "txtDDesc", buf );
506 summary = pilot_outfitSummary( player.p, outfit, 0 );
507 window_modifyText( wid, "txtDescShort", summary );
508 window_moveWidget( wid, "txtDescShort", 20+iw+20, -40-th );
509 window_dimWidget( wid, "txtDescShort", &sw, NULL );
510 th += gl_printHeightRaw( &gl_defFont, sw, summary );
511 th = MAX( th+gl_defFont.h/2, 210 );
512 window_moveWidget( wid, "txtSDesc", 20+iw+20, -40-th );
513 window_moveWidget( wid, "txtDDesc", 20+iw+20+90, -40-th );
514 window_dimWidget( wid, "txtDDesc", &sw, NULL );
515 th += gl_printHeightRaw( &gl_defFont, sw, buf );
516 th = MAX( th+gl_defFont.h/2, 256+10 );
517 window_moveWidget( wid, "txtDescription", 20+iw+20, -40-th );
518}
519
524{
525 if (landed && land_doneLoading()) {
526 if (spob_hasService(land_spob, SPOB_SERVICE_OUTFITS)) {
527 int ow = land_getWid( LAND_WINDOW_OUTFITS );
528 outfits_regenList( ow, NULL );
529 }
530 else if (!spob_hasService(land_spob, SPOB_SERVICE_SHIPYARD))
531 return;
532
533 int ew = land_getWid( LAND_WINDOW_EQUIPMENT );
535 equipment_regenLists( ew, 1, 0 );
536 }
537}
538
547static void outfits_changeTab( unsigned int wid, const char *wgt, int old, int tab )
548{
549 (void) wid;
550 (void) wgt;
551 int pos;
552 double offset;
553
554 toolkit_saveImageArrayData( wid, OUTFITS_IAR, &iar_data[old] );
555
556 /* Store the currently-saved positions for the new tab. */
557 pos = iar_data[tab].pos;
558 offset = iar_data[tab].offset;
559
560 /* Resetting the input will cause the outfit list to be regenerated. */
561 if (widget_exists(wid, OUTFITS_FILTER))
562 window_setInput(wid, OUTFITS_FILTER, NULL);
563 else
564 outfits_regenList( wid, NULL );
565
566 /* Set positions for the new tab. This is necessary because the stored
567 * position for the new tab may have exceeded the size of the old tab,
568 * resulting in it being clipped. */
569 toolkit_setImageArrayPos( wid, OUTFITS_IAR, pos );
570 toolkit_setImageArrayOffset( wid, OUTFITS_IAR, offset );
571
572 /* Focus the outfit image array. */
573 window_setFocus( wid, OUTFITS_IAR );
574}
575
585int outfits_filter( const Outfit **outfits, int n,
586 int(*filter)( const Outfit *o ), const char *name )
587{
588 int j = 0;
589 for (int i=0; i<n; i++) {
590 if ((filter != NULL) && !filter(outfits[i]))
591 continue;
592
593 if ((name != NULL) && (strcasestr( outfits[i]->name, name ) == NULL))
594 continue;
595
596 /* Shift matches downward. */
597 outfits[j] = outfits[i];
598 j++;
599 }
600
601 return j;
602}
603
609static void outfits_find( unsigned int wid, const char *str )
610{
611 (void) str;
612 map_inputFindType(wid, "outfit");
613}
614
618static const char *outfit_getPrice( const Outfit *outfit, credits_t *price, int *canbuy, int *cansell )
619{
620 static char pricestr[STRMAX_SHORT];
621 unsigned int q = outfits_getMod();
622 if (outfit->lua_price == LUA_NOREF) {
623 price2str( pricestr, outfit->price * q, player.p->credits, 2 );
624 *price = outfit->price * q;
625 *canbuy = 1;
626 *cansell = 1;
627 return pricestr;
628 }
629 const char *str;
630
631 lua_rawgeti(naevL, LUA_REGISTRYINDEX, outfit->lua_price);
632 lua_pushinteger(naevL, q);
633 if (nlua_pcall( outfit->lua_env, 1, 3 )) { /* */
634 WARN(_("Outfit '%s' failed to run '%s':\n%s"),outfit->name,"price",lua_tostring(naevL,-1));
635 *price = 0;
636 *canbuy = 0;
637 *cansell = 0;
638 lua_pop(naevL, 1);
639 return pricestr;
640 }
641
642 str = luaL_checkstring( naevL, -3 );
643 strncpy( pricestr, str, sizeof(pricestr)-1 );
644 *price = 0;
645 *canbuy = lua_toboolean( naevL, -2 );
646 *cansell = lua_toboolean( naevL, -1 );
647 lua_pop(naevL, 3);
648
649 return pricestr;
650}
651
655int outfit_altText( char *buf, int n, const Outfit *o, const Pilot *plt )
656{
657 int p;
658 double mass;
659
660 /* Compute total mass of launcher and ammo if necessary. */
661 mass = o->mass;
662 if (outfit_isLauncher(o))
663 mass += outfit_amount(o) * o->u.lau.ammo_mass;
664 else if (outfit_isFighterBay(o))
665 mass += outfit_amount(o) * o->u.bay.ship_mass;
666
667 p = outfit_getNameWithClass( o, buf, n );
668 if (outfit_isProp(o, OUTFIT_PROP_UNIQUE))
669 p += scnprintf( &buf[p], n-p, "#o%s#0\n", _("Unique") );
670 if (o->limit != NULL)
671 p += scnprintf( &buf[p], n-p, "#r%s#0\n", _("Only 1 of type per ship") );
672 if (o->slot.spid != 0)
673 p += scnprintf( &buf[p], n-p, "#o%s#0\n",
674 _(sp_display( o->slot.spid) ) );
675 p += scnprintf( &buf[p], n-p, "%s", pilot_outfitSummary( plt, o, 1 ) );
676 if ((o->mass > 0.) && (p < n)) {
677 char buf_mass[ECON_MASS_STRLEN];
678 tonnes2str( buf_mass, (int)round( mass ) );
679 scnprintf( &buf[p], n-p, "\n%s", buf_mass );
680 }
681 return 0;
682}
683
687ImageArrayCell *outfits_imageArrayCells( const Outfit **outfits, int *noutfits, const Pilot *p )
688{
689 ImageArrayCell *coutfits = calloc( MAX(1,*noutfits), sizeof(ImageArrayCell) );
690
691 if (*noutfits == 0) {
692 *noutfits = 1;
693 coutfits[0].image = NULL;
694 coutfits[0].caption = strdup( _("None") );
695 }
696 else {
697 /* Set alt text. */
698 for (int i=0; i<*noutfits; i++) {
699 const glColour *c;
700 const char *typename;
701 glTexture *t;
702 const Outfit *o = outfits[i];
703
704 coutfits[i].image = gl_dupTexture( o->gfx_store );
705 coutfits[i].caption = strdup( _(o->name) );
706 coutfits[i].quantity = player_outfitOwned(o);
707
708 /* Background colour. */
710 if (c == NULL)
711 c = &cBlack;
712 col_blend( &coutfits[i].bg, c, &cGrey70, 1 );
713
714 /* Short description. */
715 coutfits[i].alt = strdup( pilot_outfitSummary( p, o, 1 ) );
716
717 /* Slot type. */
718 if ( (strcmp(outfit_slotName(o), "N/A") != 0)
719 && (strcmp(outfit_slotName(o), "NULL") != 0) ) {
720 size_t sz = 0;
721 typename = _(outfit_slotName(o));
722 u8_inc( typename, &sz );
723 coutfits[i].slottype = malloc( sz+1 );
724 memcpy( coutfits[i].slottype, typename, sz );
725 coutfits[i].slottype[sz] = '\0';
726 }
727
728 /* Layers. */
729 coutfits[i].layers = gl_copyTexArray( o->gfx_overlays, &coutfits[i].nlayers );
730 if (o->rarity > 0) {
731 t = rarity_texture( o->rarity );
732 coutfits[i].layers = gl_addTexArray( coutfits[i].layers, &coutfits[i].nlayers, t );
733 }
734 }
735 }
736 return coutfits;
737}
738
743static void outfit_PopdownSelect( unsigned int wid, const char *str )
744{
745 int m = toolkit_getListPos( wid, str );
746 if (m == outfit_Mode)
747 return;
748
749 outfit_Mode = m;
750 outfits_regenList( wid, NULL );
751}
752
753static void outfit_PopdownActivate( unsigned int wid, const char *str )
754{
755 outfit_PopdownSelect( wid, str );
756 window_destroyWidget( wid, str );
757}
758
759static void outfit_Popdown( unsigned int wid, const char* str )
760{
761 const char *name = "lstOutfitPopdown";
762 const char *modes[] = {
763 N_("Show all outfits"),
764 N_("Show only outfits equipable on any of your ships"),
765 N_("Show only outfits equipable on current ship"),
766 N_("Show only light outfits"),
767 N_("Show only medium outfits"),
768 N_("Show only heavy outfits"),
769 };
770 char **modelist;
771 const size_t n = sizeof(modes) / sizeof(const char*);
772 int x, y, w, h;
773
774 if (widget_exists( wid, name )) {
775 window_destroyWidget( wid, name );
776 return;
777 }
778
779 modelist = malloc(sizeof(modes));
780 for (size_t i=0; i<n; i++)
781 modelist[i] = strdup( _(modes[i]) );
782
783 window_dimWidget( wid, str, &w, &h );
784 window_posWidget( wid, str, &x, &y );
785 window_addList( wid, x+w, y-120+h, 350, 120, name, modelist, n, outfit_Mode, outfit_PopdownSelect, outfit_PopdownActivate );
786 window_setFocus( wid, name );
787}
788
794int outfit_canBuy( const char *name, const Spob *spob )
795{
796 int failure, blackmarket, canbuy, cansell;
797 credits_t price;
798 const Outfit *outfit;
799 char buf[ECON_CRED_STRLEN];
800
801 failure = 0;
802 outfit = outfit_get(name);
803 outfit_getPrice( outfit, &price, &canbuy, &cansell );
804 blackmarket = ((spob!=NULL) && spob_hasService(spob, SPOB_SERVICE_BLACKMARKET));
805
806 /* Unique. */
807 if (outfit_isProp(outfit, OUTFIT_PROP_UNIQUE) && (player_outfitOwnedTotal(outfit)>0)) {
808 land_errDialogueBuild( _("You can only own one of this outfit.") );
809 return 0;
810 }
811
812 /* Map already mapped */
813 if ((outfit_isMap(outfit) && map_isUseless(outfit)) ||
814 (outfit_isLocalMap(outfit) && localmap_isUseless(outfit))) {
815 land_errDialogueBuild( _("You already know of everything this map contains.") );
816 return 0;
817 }
818 /* GUI already owned */
819 if (outfit_isGUI(outfit) && player_guiCheck(outfit->u.gui.gui)) {
820 land_errDialogueBuild( _("You already own this GUI.") );
821 return 0;
822 }
823 /* Already has license. */
824 if (outfit_isLicense(outfit) && player_hasLicense(outfit->u.lic.provides)) {
825 land_errDialogueBuild( _("You already have this license.") );
826 return 0;
827 }
828 /* not enough $$ */
829 if (!player_hasCredits(price)) {
830 credits2str( buf, price - player.p->credits, 2 );
831 land_errDialogueBuild( _("You need %s more."), buf);
832 failure = 1;
833 }
834 /* Needs license. */
835 if (!blackmarket && !player_hasLicense(outfit->license)) {
836 land_errDialogueBuild( _("You need the '%s' license to buy this outfit."),
837 _(outfit->license) );
838 failure = 1;
839 }
840 /* Needs requirements. */
841 if (!blackmarket && (outfit->cond!=NULL) && !cond_check(outfit->cond)) {
842 land_errDialogueBuild( "%s", _(outfit->condstr) );
843 failure = 1;
844 }
845 /* Custom condition failed. */
846 if (!canbuy) {
847 land_errDialogueBuild( _("You lack the resources to buy this outfit.") );
848 failure = 1;
849 }
850
851 return !failure;
852}
853
859static void outfits_rmouse( unsigned int wid, const char* widget_name )
860{
861 outfits_buy( wid, widget_name );
862}
863
869static void outfits_buy( unsigned int wid, const char *str )
870{
871 (void) str;
872 int i, active;
873 Outfit* outfit;
874 int q;
875 HookParam hparam[3];
876
877 active = window_tabWinGetActive( wid, OUTFITS_TAB );
878 i = toolkit_getImageArrayPos( wid, OUTFITS_IAR );
879 if (i < 0 || array_size(iar_outfits[active]) == 0)
880 return;
881
882 outfit = iar_outfits[active][i];
883 q = outfits_getMod();
884 /* Can only get one unique item. */
885 if (outfit_isProp(outfit, OUTFIT_PROP_UNIQUE) ||
886 outfit_isMap(outfit) || outfit_isLocalMap(outfit) ||
887 outfit_isGUI(outfit) || outfit_isLicense(outfit))
888 q = MIN(q,1);
889
890 /* Can buy the outfit? */
891 if (land_errDialogue( outfit->name, "buyOutfit" ))
892 return;
893
894 /* Try Lua. */
895 if (outfit->lua_buy != LUA_NOREF) {
896 lua_rawgeti(naevL, LUA_REGISTRYINDEX, outfit->lua_buy);
897 lua_pushinteger(naevL, q);
898 if (nlua_pcall( outfit->lua_env, 1, 2 )) { /* */
899 WARN(_("Outfit '%s' failed to run '%s':\n%s"),outfit->name,"price",lua_tostring(naevL,-1));
900 lua_pop(naevL, 1);
901 }
902
903 int bought = lua_toboolean(naevL,-2);
904
905 if (!bought) {
906 dialogue_alert( "%s", lua_tostring(naevL,-1) );
907 lua_pop(naevL, 2);
908 return;
909 }
910 q = luaL_checkinteger(naevL,-1);
911 player_addOutfit( outfit, q );
912
913 lua_pop(naevL, 2);
914 }
915 else
916 player_modCredits( -outfit->price * player_addOutfit( outfit, q ) );
917
918 /* Actually buy the outfit. */
920 hparam[0].type = HOOK_PARAM_STRING;
921 hparam[0].u.str = outfit->name;
922 hparam[1].type = HOOK_PARAM_NUMBER;
923 hparam[1].u.num = q;
924 hparam[2].type = HOOK_PARAM_SENTINEL;
925 hooks_runParam( "outfit_buy", hparam );
926 land_needsTakeoff( 1 );
927
928 /* Regenerate list. */
929 outfits_regenList( wid, NULL );
930}
935int outfit_canSell( const char *name )
936{
937 int failure = 0;
938 int canbuy, cansell;
939 credits_t price;
940 const Outfit *outfit = outfit_get(name);
941
942 outfit_getPrice( outfit, &price, &canbuy, &cansell );
943
944 /* Unique item. */
945 if (outfit_isProp(outfit, OUTFIT_PROP_UNIQUE)) {
946 land_errDialogueBuild(_("You can't sell a unique outfit."));
947 failure = 1;
948 }
949 /* Map check. */
950 if (outfit_isMap(outfit) || outfit_isLocalMap(outfit)) {
951 land_errDialogueBuild(_("You can't sell a map."));
952 failure = 1;
953 }
954 /* GUI check. */
955 if (outfit_isGUI(outfit)) {
956 land_errDialogueBuild(_("You can't sell a GUI."));
957 failure = 1;
958 }
959 /* License check. */
960 if (outfit_isLicense(outfit)) {
961 land_errDialogueBuild(_("You can't sell a license."));
962 failure = 1;
963 }
964 /* has no outfits to sell */
965 if (player_outfitOwned(outfit) <= 0) {
966 land_errDialogueBuild( _("You can't sell something you don't have!") );
967 failure = 1;
968 }
969 /* Custom condition failed. */
970 if (!cansell) {
971 land_errDialogueBuild(_("You are unable to sell this outfit!"));
972 failure = 1;
973 }
974
975 return !failure;
976}
982static void outfits_sell( unsigned int wid, const char *str )
983{
984 (void)str;
985 int i, active;
986 Outfit* outfit;
987 int q;
988 HookParam hparam[3];
989
990 active = window_tabWinGetActive( wid, OUTFITS_TAB );
991 i = toolkit_getImageArrayPos( wid, OUTFITS_IAR );
992 if (i < 0 || array_size(iar_outfits[active]) == 0)
993 return;
994
995 outfit = iar_outfits[active][i];
996
997 q = outfits_getMod();
998
999 /* Check various failure conditions. */
1000 if (land_errDialogue( outfit->name, "sellOutfit" ))
1001 return;
1002
1003 /* Try Lua. */
1004 if (outfit->lua_sell != LUA_NOREF) {
1005 lua_rawgeti(naevL, LUA_REGISTRYINDEX, outfit->lua_sell);
1006 lua_pushinteger(naevL, q);
1007 if (nlua_pcall( outfit->lua_env, 1, 2 )) { /* */
1008 WARN(_("Outfit '%s' failed to run '%s':\n%s"),outfit->name,"price",lua_tostring(naevL,-1));
1009 lua_pop(naevL, 1);
1010 }
1011
1012 int bought = lua_toboolean(naevL,-2);
1013
1014 if (!bought) {
1015 dialogue_alert( "%s", lua_tostring(naevL,-1) );
1016 lua_pop(naevL, 2);
1017 return;
1018 }
1019 q = luaL_checkinteger(naevL,-1);
1020
1021 lua_pop(naevL, 2);
1022 }
1023 else
1024 player_modCredits( outfit->price * player_rmOutfit( outfit, q ) );
1025
1027 hparam[0].type = HOOK_PARAM_STRING;
1028 hparam[0].u.str = outfit->name;
1029 hparam[1].type = HOOK_PARAM_NUMBER;
1030 hparam[1].u.num = q;
1031 hparam[2].type = HOOK_PARAM_SENTINEL;
1032 hooks_runParam( "outfit_sell", hparam );
1033 land_needsTakeoff( 1 );
1034
1035 /* Regenerate list. */
1036 outfits_regenList( wid, NULL );
1037}
1042static int outfits_getMod (void)
1043{
1044 SDL_Keymod mods = SDL_GetModState();
1045 int q = 1;
1046 if (mods & (KMOD_LCTRL | KMOD_RCTRL))
1047 q *= 5;
1048 if (mods & (KMOD_LSHIFT | KMOD_RSHIFT))
1049 q *= 10;
1050
1051 return q;
1052}
1061static void outfits_renderMod( double bx, double by, double w, double h, void *data )
1062{
1063 (void) data;
1064 (void) h;
1065 int q;
1066 char buf[8];
1067
1068 q = outfits_getMod();
1069 if (q != outfits_mod) {
1071 outfits_mod = q;
1072 }
1073 if (q==1) return; /* Ignore no modifier. */
1074
1075 snprintf( buf, 8, "%dx", q );
1076 gl_printMidRaw( &gl_smallFont, w, bx, by, &cFontWhite, -1, buf );
1077}
1078
1083{
1084 /* Free stored positions. */
1085 free(iar_data);
1086 iar_data = NULL;
1087 if (iar_outfits != NULL) {
1088 for (int i=0; i<OUTFITS_NTABS; i++)
1089 array_free( iar_outfits[i] );
1090 free(iar_outfits);
1091 iar_outfits = NULL;
1092 }
1093}
Provides macros to work with dynamic arrays.
#define array_free(ptr_array)
Frees memory allocated and sets array to NULL.
Definition: array.h:158
#define array_copy(basic_type, ptr_array)
Returns a shallow copy of the input array.
Definition: array.h:218
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
Definition: array.h:168
void col_blend(glColour *blend, const glColour *fg, const glColour *bg, float alpha)
Blends two colours.
Definition: colour.c:192
int cond_check(const char *cond)
Checks to see if a condition is true.
Definition: cond.c:53
void dialogue_alert(const char *fmt,...)
Displays an alert popup with only an ok button and a message.
Definition: dialogue.c:132
void equipment_regenLists(unsigned int wid, int outfits, int ships)
Regenerates the equipment window lists.
Definition: equipment.c:1235
void equipment_addAmmo(void)
Adds all the ammo it can to the player.
Definition: equipment.c:1301
int gl_printHeightRaw(const glFont *ft_font, const int width, const char *text)
Gets the height of a non-formatted string.
Definition: font.c:1026
glFont gl_smallFont
Definition: font.c:154
glFont gl_defFont
Definition: font.c:153
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.
Definition: font.c:787
int hooks_runParam(const char *stack, const HookParam *param)
Runs all the hooks of stack.
Definition: hook.c:967
unsigned int land_getWid(int window)
Gets the WID of a window by type.
Definition: land.c:963
int landed
Definition: land.c:74
int land_doneLoading(void)
Check to see if finished loading.
Definition: land.c:189
void land_errDialogueBuild(const char *fmt,...)
Generates error dialogues used by several landing tabs.
Definition: land.c:288
int land_errDialogue(const char *name, const char *type)
Generates error dialogues used by several landing tabs.
Definition: land.c:256
Spob * land_spob
Definition: land.c:82
void land_buttonTakeoff(unsigned int wid, const char *unused)
Wrapper for takeoff mission button.
Definition: land.c:925
static void outfits_sell(unsigned int wid, const char *str)
Attempts to sell the selected outfit the player has.
Definition: land_outfits.c:982
static int outfits_getMod(void)
Gets the current modifier status.
int outfit_altText(char *buf, int n, const Outfit *o, const Pilot *plt)
Computes the alt text for an outfit.
Definition: land_outfits.c:655
static void outfits_onClose(unsigned int wid, const char *str)
For when the widget closes.
Definition: land_outfits.c:100
static void outfits_genList(unsigned int wid)
Generates the outfit list.
Definition: land_outfits.c:311
static Outfit *** iar_outfits
Definition: land_outfits.c:47
static int outfitLand_filter(const Outfit *o)
Definition: land_outfits.c:255
void outfits_regenList(unsigned int wid, const char *str)
Regenerates the outfit list.
Definition: land_outfits.c:217
static void outfits_find(unsigned int wid, const char *str)
Starts the map find with outfit search selected.
Definition: land_outfits.c:609
static void outfits_getSize(unsigned int wid, int *w, int *h, int *iw, int *ih, int *bw, int *bh)
Gets the size of the outfits window.
Definition: land_outfits.c:73
void outfits_cleanup(void)
Cleans up outfit globals.
int outfits_filter(const Outfit **outfits, int n, int(*filter)(const Outfit *o), const char *name)
Applies a filter function and string to a list of outfits.
Definition: land_outfits.c:585
void outfits_open(unsigned int wid, const Outfit **outfits)
Opens the outfit exchange center window.
Definition: land_outfits.c:117
ImageArrayCell * outfits_imageArrayCells(const Outfit **outfits, int *noutfits, const Pilot *p)
Generates image array cells corresponding to outfits.
Definition: land_outfits.c:687
void outfits_updateEquipmentOutfits(void)
Updates the outfitter and equipment outfit image arrays.
Definition: land_outfits.c:523
static void outfits_buy(unsigned int wid, const char *str)
Attempts to buy the outfit that is selected.
Definition: land_outfits.c:869
static iar_data_t * iar_data
Definition: land_outfits.c:46
void outfits_update(unsigned int wid, const char *str)
Updates the outfits in the outfit window.
Definition: land_outfits.c:405
static void outfits_renderMod(double bx, double by, double w, double h, void *data)
Renders the outfit buying modifier.
static int outfit_Mode
Definition: land_outfits.c:48
static void outfit_PopdownSelect(unsigned int wid, const char *str)
Definition: land_outfits.c:743
static const char * outfit_getPrice(const Outfit *outfit, credits_t *price, int *canbuy, int *cansell)
Returns the price of an outfit (subject to quantity modifier)
Definition: land_outfits.c:618
static void outfits_rmouse(unsigned int wid, const char *widget_name)
Player right-clicks on an outfit.
Definition: land_outfits.c:859
int outfit_canSell(const char *name)
Checks to see if the player can sell the selected outfit.
Definition: land_outfits.c:935
int outfit_canBuy(const char *name, const Spob *spob)
Checks to see if the player can buy the outfit.
Definition: land_outfits.c:794
static void outfits_changeTab(unsigned int wid, const char *wgt, int old, int tab)
Ensures the tab's selected item is reflected in the ship slot list.
Definition: land_outfits.c:547
Header file with generic functions and naev-specifics.
#define MIN(x, y)
Definition: naev.h:40
#define CLAMP(a, b, x)
Definition: naev.h:41
#define MAX(x, y)
Definition: naev.h:39
char * strcasestr(const char *haystack, const char *needle)
Finds a string inside another string case insensitively.
Definition: nstring.c:68
int scnprintf(char *text, size_t maxlen, const char *fmt,...)
Like snprintf(), but returns the number of characters ACTUALLY "printed" into the buffer....
Definition: nstring.c:178
glTexture * gl_dupTexture(const glTexture *texture)
Duplicates a texture.
Definition: opengl_tex.c:809
glTexture ** gl_copyTexArray(glTexture **tex, int *n)
Copy a texture array.
Definition: opengl_tex.c:892
glTexture ** gl_addTexArray(glTexture **tex, int *n, glTexture *t)
Adds an element to a texture array.
Definition: opengl_tex.c:934
const Outfit * outfit_get(const char *name)
Gets an outfit by name.
Definition: outfit.c:118
int outfit_isLauncher(const Outfit *o)
Checks if outfit is a weapon launcher.
Definition: outfit.c:498
int outfit_isLocalMap(const Outfit *o)
Checks if outfit is a local space map.
Definition: outfit.c:568
size_t outfit_getNameWithClass(const Outfit *outfit, char *buf, size_t size)
Gets a brief name/class description suitable for the title section of an outfitter screen.
Definition: outfit.c:394
int outfit_fitsSlot(const Outfit *o, const OutfitSlot *s)
Checks to see if an outfit fits a slot.
Definition: outfit.c:981
int outfit_isFighterBay(const Outfit *o)
Checks if outfit is a fighter bay.
Definition: outfit.c:550
int outfit_isMap(const Outfit *o)
Checks if outfit is a space map.
Definition: outfit.c:559
int outfit_isLicense(const Outfit *o)
Checks if outfit is a license.
Definition: outfit.c:577
int outfit_amount(const Outfit *o)
Gets the amount an outfit can hold.
Definition: outfit.c:670
int outfit_isGUI(const Outfit *o)
Checks if outfit is a GUI.
Definition: outfit.c:586
const char * outfit_slotName(const Outfit *o)
Gets the name of the slot type of an outfit.
Definition: outfit.c:279
glTexture * rarity_texture(int rarity)
Definition: outfit.c:2726
const glColour * outfit_slotSizeColour(const OutfitSlot *os)
Gets the slot size colour for an outfit slot.
Definition: outfit.c:341
const char * pilot_outfitDescription(const Pilot *p, const Outfit *o)
Gets the description of an outfit for a given pilot.
const char * pilot_outfitSummary(const Pilot *p, const Outfit *o, int withname)
Gets the summary of an outfit for a give pilot.
int player_rmOutfit(const Outfit *o, int quantity)
Remove an outfit from the player's outfit stack.
Definition: player.c:2859
int player_hasLicense(const char *license)
Checks to see if player has license.
Definition: player.c:2996
int player_addOutfit(const Outfit *o, int quantity)
Adds an outfit to the player outfit stack.
Definition: player.c:2803
const PlayerShip_t * player_getShipStack(void)
Gets the array (array.h) of the player's ships.
Definition: player.c:2623
int player_outfitOwnedTotal(const Outfit *o)
Definition: player.c:2729
credits_t player_modCredits(credits_t amount)
Modifies the amount of credits the player has.
Definition: player.c:947
Player_t player
Definition: player.c:73
int player_hasCredits(credits_t amount)
Checks to see if the player has enough credits.
Definition: player.c:936
int player_outfitOwned(const Outfit *o)
Gets how many of the outfit the player owns.
Definition: player.c:2701
int player_guiCheck(char *name)
Check if player has a GUI.
Definition: player_gui.c:98
static const double c[]
Definition: rng.c:264
const char * sp_display(unsigned int spid)
Gets the display name of a slot property (in English).
Definition: slots.c:150
The actual hook parameter.
Definition: hook.h:35
const char * str
Definition: hook.h:39
union HookParam::@4 u
HookParamType type
Definition: hook.h:36
double num
Definition: hook.h:38
char * gui
Definition: outfit.h:291
double ammo_mass
Definition: outfit.h:204
char * provides
Definition: outfit.h:298
OutfitSlotSize size
Definition: outfit.h:105
unsigned int spid
Definition: outfit.h:102
A ship outfit, depends radically on the type.
Definition: outfit.h:304
credits_t price
Definition: outfit.h:322
char * limit
Definition: outfit.h:317
char * cond
Definition: outfit.h:313
OutfitLauncherData lau
Definition: outfit.h:373
int lua_buy
Definition: outfit.h:365
glTexture * gfx_store
Definition: outfit.h:328
int rarity
Definition: outfit.h:307
int lua_price
Definition: outfit.h:364
OutfitGUIData gui
Definition: outfit.h:379
char * condstr
Definition: outfit.h:314
OutfitSlot slot
Definition: outfit.h:311
OutfitFighterBayData bay
Definition: outfit.h:376
int lua_sell
Definition: outfit.h:366
nlua_env lua_env
Definition: outfit.h:342
char * license
Definition: outfit.h:312
glTexture ** gfx_overlays
Definition: outfit.h:329
double mass
Definition: outfit.h:315
union Outfit::@22 u
char * name
Definition: outfit.h:305
OutfitLicenseData lic
Definition: outfit.h:380
The representation of an in-game pilot.
Definition: pilot.h:210
credits_t credits
Definition: pilot.h:317
int big_icons
Definition: conf.h:126
Player ship.
Definition: player.h:73
Pilot * p
Definition: player.h:74
Pilot * p
Definition: player.h:101
Represents a Space Object (SPOB), including and not limited to planets, stations, wormholes,...
Definition: space.h:88
tech_group_t * tech
Definition: space.h:116
int h
Definition: font.h:18
Abstraction for rendering sprite sheets.
Definition: opengl_tex.h:34
Outfit ** tech_getOutfit(const tech_group_t *tech)
Gets all of the outfits associated to a tech group.
Definition: tech.c:725
void window_dimWidget(unsigned int wid, const char *name, int *w, int *h)
Gets the dimensions of a widget.
Definition: toolkit.c:416
void window_setFocus(unsigned int wid, const char *wgtname)
Sets the focused widget in a window.
Definition: toolkit.c:2460
void window_setAccept(unsigned int wid, void(*accept)(unsigned int, const char *))
Sets the default accept function of the window.
Definition: toolkit.c:879
void window_dimWindow(unsigned int wid, int *w, int *h)
Gets the dimensions of a window.
Definition: toolkit.c:371
void window_onClose(unsigned int wid, void(*fptr)(unsigned int, const char *))
Sets the default close function of the window.
Definition: toolkit.c:840
void window_canFocusWidget(unsigned int wid, const char *name, int canfocus)
Allows or disallows focusing a widget.
Definition: toolkit.c:523
void window_moveWidget(unsigned int wid, const char *name, int x, int y)
Moves a widget.
Definition: toolkit.c:467
void window_posWidget(unsigned int wid, const char *name, int *x, int *y)
Gets a widget's position.
Definition: toolkit.c:442
void window_destroyWidget(unsigned int wid, const char *wgtname)
Destroys a widget in a window.
Definition: toolkit.c:1162
void * window_getData(unsigned int wid)
Gets the custom data of a window.
Definition: toolkit.c:934
void window_setData(unsigned int wid, void *data)
Sets custom data for a window.
Definition: toolkit.c:917
int widget_exists(unsigned int wid, const char *wgtname)
Checks to see if a widget exists.
Definition: toolkit.c:1139
void window_close(unsigned int wid, const char *str)
Helper function to automatically close the window calling it.
Definition: toolkit.c:1031
char * window_getFocus(unsigned int wid)
Gets the focused widget in a window (does strdup!!).
Definition: toolkit.c:2486