22#include "gatherable.h"
27#include "threadpool.h"
29#define XML_COMMODITY_ID "commodity"
30#define CRED_TEXT_MAX \
31 ( ECON_CRED_STRLEN - \
45typedef struct CommodityThreadData_ {
55static int commodity_parseThread(
void *ptr );
58static int commodity_cmp(
const void *p1,
const void *p2 );
60static int commodity_cmp(
const void *p1,
const void *p2 )
79 snprintf( str, CRED_TEXT_MAX, _(
"%.*f ¤" ), 0, (
double)credits );
80 }
else if ( credits >= 1000000000000000000LL )
81 snprintf( str, CRED_TEXT_MAX, _(
"%.*f E¤" ), decimals,
82 (
double)credits / 1e18 );
83 else if ( credits >= 1000000000000000LL )
84 snprintf( str, CRED_TEXT_MAX, _(
"%.*f P¤" ), decimals,
85 (
double)credits / 1e15 );
86 else if ( credits >= 1000000000000LL )
87 snprintf( str, CRED_TEXT_MAX, _(
"%.*f T¤" ), decimals,
88 (
double)credits / 1e12 );
89 else if ( credits >= 1000000000L )
90 snprintf( str, CRED_TEXT_MAX, _(
"%.*f G¤" ), decimals,
91 (
double)credits / 1e9 );
92 else if ( credits >= 1000000 )
93 snprintf( str, CRED_TEXT_MAX, _(
"%.*f M¤" ), decimals,
94 (
double)credits / 1e6 );
95 else if ( credits >= 1000 )
96 snprintf( str, CRED_TEXT_MAX, _(
"%.*f k¤" ), decimals,
97 (
double)credits / 1e3 );
99 snprintf( str, CRED_TEXT_MAX, _(
"%.*f ¤" ), decimals, (
double)credits );
111void price2str(
char *str, credits_t price, credits_t credits,
int decimals )
113 char buf[CRED_TEXT_MAX];
115 if ( price <= credits ) {
121 snprintf( str, ECON_CRED_STRLEN,
"#r%s#0", (
char *)buf );
133 snprintf( str, ECON_MASS_STRLEN, n_(
"%d tonne",
"%d tonnes", tonnes ),
156 WARN( _(
"Commodity '%s' not found in stack" ), name );
168 const Commodity q = { .name = (
char *)name };
198 WARN( _(
"Commodity with index %d not found" ), indx );
219 while ( next != NULL ) {
227 while ( next != NULL ) {
260 return strcmp( c1->
name, c2->
name );
271 for (
int i = 0; i < n; i++ ) {
273 if ( commodity_isFlag(
c, COMMODITY_FLAG_STANDARD ) )
288 xmlNodePtr node, parent;
295 parent = doc->xmlChildrenNode;
297 WARN( _(
"Malformed %s file: missing root element '%s'" ), filename,
308 node = parent->xmlChildrenNode;
310 xml_onlyNodes( node );
312 xmlr_strd( node,
"name", temp->
name );
313 xmlr_strd( node,
"description", temp->
description );
314 xmlr_int( node,
"price", temp->
price );
315 xmlr_float( node,
"price_mod", temp->
price_mod );
316 xmlr_strd( node,
"price_ref", temp->
price_ref );
318 if ( xml_isNode( node,
"gfx_space" ) ) {
320 node, COMMODITY_GFX_PATH
"space/%s", 1, 1, OPENGL_TEX_MIPMAPS );
323 if ( xml_isNode( node,
"gfx_store" ) ) {
325 1, OPENGL_TEX_MIPMAPS );
328 if ( xml_isNode( node,
"standard" ) ) {
329 commodity_setFlag( temp, COMMODITY_FLAG_STANDARD );
332 if ( xml_isNode( node,
"always_can_sell" ) ) {
333 commodity_setFlag( temp, COMMODITY_FLAG_ALWAYS_CAN_SELL );
336 if ( xml_isNode( node,
"price_constant" ) ) {
337 commodity_setFlag( temp, COMMODITY_FLAG_PRICE_CONSTANT );
340 if ( xml_isNode( node,
"illegalto" ) ) {
341 xmlNodePtr cur = node->xmlChildrenNode;
344 xml_onlyNodes( cur );
345 if ( xml_isNode( cur,
"faction" ) ) {
349 }
while ( xml_nextNode( node ) );
353 xmlr_float( node,
"period", temp->
period );
354 if ( xml_isNode( node,
"spob_modifier" ) ) {
357 xmlr_attr_strd( node,
"type", newdict->name );
358 newdict->value = xml_getFloat( node );
362 if ( xml_isNode( node,
"faction_modifier" ) ) {
365 xmlr_attr_strd( node,
"type", newdict->name );
366 newdict->value = xml_getFloat( node );
371 WARN( _(
"Commodity '%s' has unknown node '%s'" ), temp->
name,
373 }
while ( xml_nextNode( node ) );
375 if ( temp->
name == NULL )
376 WARN( _(
"Commodity from %s has invalid or no name" ),
377 COMMODITY_DATA_PATH );
381 WARN( _(
"No <gfx_store> node found, using default texture for "
382 "commodity \"%s\"" ),
389 gl_newImage( COMMODITY_GFX_PATH
"space/_default.webp", 0 );
392 if ( temp->
price > 0. )
393 WARN( _(
"Commodity '%s' is setting both 'price' and 'price_ref'." ),
398#define MELEMENT( o, s ) \
400 WARN( _( "Commodity '%s' missing '"s \
404 MELEMENT(temp->high==0,
"high");
405 MELEMENT(temp->medium==0,
"medium");
406 MELEMENT(temp->low==0,
"low");
446 WARN( _(
"Commodity '%s' not found in stack" ), name );
466 ( *c )->name = strdup( name );
467 ( *c )->description = strdup( desc );
477 WARN( _(
"Trying to modify temporary commodity '%s'!" ), com->
name );
495static int commodity_parseThread(
void *ptr )
516 Uint32 time = SDL_GetTicks();
518 ThreadQueue *tq = vpool_create();
528 for (
int i = 0; i <
array_size( commodities ); i++ ) {
531 cd->filename = commodities[i];
533 free( commodities[i] );
538 SDL_GL_MakeCurrent(
gl_screen.window, NULL );
539 for (
int i = 0; i <
array_size( cdata ); i++ )
540 vpool_enqueue( tq, commodity_parseThread, &cdata[i] );
547 for (
int i = 0; i <
array_size( cdata ); i++ ) {
551 free( cd->filename );
563 if ( com->
price > 0. )
568 if ( conf.devmode ) {
569 time = SDL_GetTicks() - time;
570 DEBUG( n_(
"Loaded %d Commodity in %.3f s",
571 "Loaded %d Commodities in %.3f s",
575 DEBUG( n_(
"Loaded %d Commodity",
"Loaded %d Commodities",
Provides macros to work with dynamic arrays.
#define array_free(ptr_array)
Frees memory allocated and sets array to NULL.
#define array_create_size(basic_type, capacity)
Creates a new dynamic array of ‘basic_type’ with an initial capacity.
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
#define array_grow(ptr_array)
Increases the number of elements by one and returns the last element.
#define array_push_back(ptr_array, element)
Adds a new element at the end of the array.
#define array_create(basic_type)
Creates a new dynamic array of ‘basic_type’.
Commodity * commodity_getAll(void)
Gets all the commodities.
Commodity * commodity_get(const char *name)
Gets a commodity by name.
Commodity * commodity_newTemp(const char *name, const char *desc)
Creates a new temporary commodity.
static void commodity_freeOne(Commodity *com)
Frees a commodity.
static Commodity ** commodity_temp
void commodity_free(void)
Frees all the loaded commodities.
Commodity * commodity_getByIndex(const int indx)
Gets a commodity by index.
static int commodity_parse(Commodity *temp, const char *filename)
Loads a commodity.
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.
int commodity_getN(void)
Return the number of commodities globally.
int commodity_compareTech(const void *commodity1, const void *commodity2)
Function meant for use with C89, C99 algorithm qsort().
void price2str(char *str, credits_t price, credits_t credits, int decimals)
Given a price and on-hand credits, outputs a colourized string.
int commodity_load(void)
Loads all the commodity data.
Commodity ** standard_commodities(void)
Return an array (array.h) of standard commodities. Free with array_free. (Don't free contents....
int commodity_checkIllegal(const Commodity *com, int faction)
Checks to see if a commodity is illegal to a faction.
Commodity * commodity_getW(const char *name)
Gets a commodity by name without warning.
Commodity * commodity_stack
int commodity_tempIllegalto(Commodity *com, int faction)
Makes a temporary commodity illegal to something.
int commodity_isTemp(const char *name)
Checks to see if a commodity is temporary.
int faction_get(const char *name)
Gets a faction ID by name.
int gatherable_load(void)
Loads the gatherable system.
void gatherable_cleanup(void)
Cleans up after the gatherable system.
void naev_renderLoadscreen(void)
Renders the loadscreen if necessary.
int naev_shouldRenderLoadscreen(void)
Whether or not we want to render the loadscreen.
Header file with generic functions and naev-specifics.
int ndata_matchExt(const char *path, const char *ext)
Sees if a file matches an extension.
char ** ndata_listRecursive(const char *path)
Lists all the visible files in a directory, at any depth.
glTexture * xml_parseTexture(xmlNodePtr node, const char *path, int defsx, int defsy, const unsigned int flags)
Parses a texture handling the sx and sy elements.
xmlDocPtr xml_parsePhysFS(const char *filename)
Analogous to xmlParseMemory/xmlParseFile.
glTexture * gl_newImage(const char *path, const unsigned int flags)
Loads an image as a texture.
void gl_freeTexture(glTexture *texture)
Frees a texture.
Represents a dictionary of values used to modify a commodity.
For threaded loading of commodities.
CommodityModifier * spob_modifier
double population_modifier
CommodityModifier * faction_modifier