[Add] Initial work on implementing a dynamic economy.
This commit is contained in:
parent
da58e41da9
commit
6285fb0629
327
src/economy.c
327
src/economy.c
@ -2,6 +2,8 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "cs.h"
|
||||||
|
|
||||||
#include "lephisto.h"
|
#include "lephisto.h"
|
||||||
#include "xml.h"
|
#include "xml.h"
|
||||||
#include "pack.h"
|
#include "pack.h"
|
||||||
@ -9,18 +11,41 @@
|
|||||||
#include "spfx.h"
|
#include "spfx.h"
|
||||||
#include "pilot.h"
|
#include "pilot.h"
|
||||||
#include "rng.h"
|
#include "rng.h"
|
||||||
|
#include "space.h"
|
||||||
#include "economy.h"
|
#include "economy.h"
|
||||||
|
|
||||||
#define XML_COMMODITY_ID "Commodities" /* XML section identifier. */
|
#define XML_COMMODITY_ID "Commodities" /* XML section identifier. */
|
||||||
#define XML_COMMODITY_TAG "commodity"
|
#define XML_COMMODITY_TAG "commodity"
|
||||||
#define COMMODITY_DATA "../dat/commodity.xml"
|
#define COMMODITY_DATA "../dat/commodity.xml"
|
||||||
|
|
||||||
|
/* Economy Nodal Analysis parameters. */
|
||||||
|
#define ECON_BASE_RES 30. /**< Base resistance value for any system. */
|
||||||
|
#define ECON_SELF_RES 30. /**< Additional resistance for the self node. */
|
||||||
|
#define ECON_FACTION_MOD 0.1 /**< Modifier on Base for faction standings. */
|
||||||
|
#define ECON_PROD_MODIFIER 500000. /**< Production modifier, divide production by this amount. */
|
||||||
|
|
||||||
/* Commodity stack. */
|
/* Commodity stack. */
|
||||||
static Commodity* commodity_stack = NULL;
|
static Commodity* commodity_stack = NULL;
|
||||||
static int commodity_nstack = 0;
|
static int commodity_nstack = 0;
|
||||||
|
|
||||||
|
/* Systems stack. */
|
||||||
|
extern StarSystem* systems_stack; /**< Star system stack. */
|
||||||
|
extern int systems_nstack; /**< Number of star systems. */
|
||||||
|
|
||||||
|
/* Nodal analysis simulation for dynamic economies. */
|
||||||
|
static int econ_initialized = 0; /**< Is economy system initialized? */
|
||||||
|
static int* econ_comm = NULL; /**< Commodities to calculate. */
|
||||||
|
static int econ_nprices = 0; /**< Number of prices to calculate. */
|
||||||
|
static cs* econ_G = NULL; /**< Admittance matrix. */
|
||||||
|
|
||||||
|
/* Commodity. */
|
||||||
static void commodity_freeOne(Commodity* com);
|
static void commodity_freeOne(Commodity* com);
|
||||||
static Commodity* commodity_parse(xmlNodePtr parent);
|
static int commodity_parse(Commodity* tmp, xmlNodePtr parent);
|
||||||
|
/* Economy. */
|
||||||
|
static double econ_calcJumpR(StarSystem* A, StarSystem* B);
|
||||||
|
static int econ_createGMatrix(void);
|
||||||
|
unsigned int economy_getPrice(const Commodity* com,
|
||||||
|
const StarSystem* sys, const Planet* p); /* Externed in land.c. */
|
||||||
|
|
||||||
/* Convert credits to a usable string for displaying. */
|
/* Convert credits to a usable string for displaying. */
|
||||||
/* str must have 10 characters allocated. */
|
/* str must have 10 characters allocated. */
|
||||||
@ -51,11 +76,16 @@ Commodity* commodity_get(const char* name) {
|
|||||||
static void commodity_freeOne(Commodity* com) {
|
static void commodity_freeOne(Commodity* com) {
|
||||||
if(com->name) free(com->name);
|
if(com->name) free(com->name);
|
||||||
if(com->description) free(com->description);
|
if(com->description) free(com->description);
|
||||||
|
|
||||||
|
/* Clear the memory. */
|
||||||
|
memset(com, 0, sizeof(Commodity));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Commodity* commodity_parse(xmlNodePtr parent) {
|
static int commodity_parse(Commodity* tmp, xmlNodePtr parent) {
|
||||||
xmlNodePtr node;
|
xmlNodePtr node;
|
||||||
Commodity* tmp = CALLOC_L(Commodity);
|
|
||||||
|
/* Clear memory. */
|
||||||
|
memset(tmp, 0, sizeof(Commodity));
|
||||||
|
|
||||||
tmp->name = (char*)xmlGetProp(parent, (xmlChar*)"name");
|
tmp->name = (char*)xmlGetProp(parent, (xmlChar*)"name");
|
||||||
if(tmp->name == NULL)
|
if(tmp->name == NULL)
|
||||||
@ -65,9 +95,7 @@ static Commodity* commodity_parse(xmlNodePtr parent) {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
xmlr_strd(node, "description", tmp->description);
|
xmlr_strd(node, "description", tmp->description);
|
||||||
xmlr_strd(node, "high", tmp->high);
|
xmlr_int( node, "price", tmp->price);
|
||||||
xmlr_strd(node, "medium", tmp->medium);
|
|
||||||
xmlr_strd(node, "low", tmp->low);
|
|
||||||
} while((node = node->next));
|
} while((node = node->next));
|
||||||
#if 0 /* Let's kill this for now. */
|
#if 0 /* Let's kill this for now. */
|
||||||
#define MELEMENT(o,s)if(o)WARN("Commodity '%s' missing '"s"' element",tmp->name)
|
#define MELEMENT(o,s)if(o)WARN("Commodity '%s' missing '"s"' element",tmp->name)
|
||||||
@ -78,7 +106,7 @@ static Commodity* commodity_parse(xmlNodePtr parent) {
|
|||||||
#undef MELEMENT
|
#undef MELEMENT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return tmp;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Throw cargo out into space (graphically). */
|
/* Throw cargo out into space (graphically). */
|
||||||
@ -119,8 +147,6 @@ int commodity_load(void) {
|
|||||||
xmlNodePtr node;
|
xmlNodePtr node;
|
||||||
xmlDocPtr doc = xmlParseMemory(buf, bufsize);
|
xmlDocPtr doc = xmlParseMemory(buf, bufsize);
|
||||||
|
|
||||||
Commodity* tmp = NULL;
|
|
||||||
|
|
||||||
node = doc->xmlChildrenNode; /* Commoditys node. */
|
node = doc->xmlChildrenNode; /* Commoditys node. */
|
||||||
if(strcmp((char*)node->name, XML_COMMODITY_ID)) {
|
if(strcmp((char*)node->name, XML_COMMODITY_ID)) {
|
||||||
ERR("Malformed "COMMODITY_DATA
|
ERR("Malformed "COMMODITY_DATA
|
||||||
@ -135,13 +161,19 @@ int commodity_load(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if(node->type == XML_NODE_START) {
|
if(xml_isNode(node, XML_COMMODITY_TAG)) {
|
||||||
if(strcmp((char*)node->name, XML_COMMODITY_TAG)==0) {
|
/* Make room for commodity. */
|
||||||
tmp = commodity_parse(node);
|
|
||||||
commodity_stack = realloc(commodity_stack,
|
commodity_stack = realloc(commodity_stack,
|
||||||
sizeof(Commodity)*(++commodity_nstack));
|
sizeof(Commodity)*(++commodity_nstack));
|
||||||
memcpy(commodity_stack+commodity_nstack-1, tmp, sizeof(Commodity));
|
|
||||||
free(tmp);
|
/* Load commodity. */
|
||||||
|
commodity_parse(&commodity_stack[commodity_nstack-1], node);
|
||||||
|
|
||||||
|
/* See if it should get added to commodity list. */
|
||||||
|
if(commodity_stack[commodity_nstack-1].price > 0.) {
|
||||||
|
econ_nprices++;
|
||||||
|
econ_comm = realloc(econ_comm, econ_nprices * sizeof(int));
|
||||||
|
econ_comm[econ_nprices-1] = commodity_nstack-1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while((node = node->next));
|
} while((node = node->next));
|
||||||
@ -164,3 +196,270 @@ void commodity_free(void) {
|
|||||||
commodity_nstack = 0;
|
commodity_nstack = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the price of a good on a planet in a system.
|
||||||
|
* @param com Commodity to get price of.
|
||||||
|
* @param sys System to get price of commodity.
|
||||||
|
* @param p Planet to get price of commodity.
|
||||||
|
* @return The price of the commodity.
|
||||||
|
*/
|
||||||
|
unsigned int economy_getPrice(const Commodity* com,
|
||||||
|
const StarSystem* sys, const Planet* p) {
|
||||||
|
(void)p;
|
||||||
|
int i, k;
|
||||||
|
double price;
|
||||||
|
|
||||||
|
/* Get position in stack. */
|
||||||
|
k = com - commodity_stack;
|
||||||
|
|
||||||
|
/* Find what commodity that is. */
|
||||||
|
for(i = 0; i < econ_nprices; i++)
|
||||||
|
if(econ_comm[i] == k)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Check if found. */
|
||||||
|
if(i >= econ_nprices) {
|
||||||
|
WARN("Price for commodity '%s' not known.", com->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calculate price. */
|
||||||
|
price = (double)com->price;
|
||||||
|
price *= sys->prices[i];
|
||||||
|
return (unsigned int) price;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Calculates the resistance between two star systems.
|
||||||
|
* @param A Star system to calculate the resistance between.
|
||||||
|
* @param B Star system to calculate the resistance between.
|
||||||
|
* @return Resistance between A and B.
|
||||||
|
*/
|
||||||
|
static double econ_calcJumpR(StarSystem* A, StarSystem* B) {
|
||||||
|
double R;
|
||||||
|
|
||||||
|
/* Set to base to ensure price change. */
|
||||||
|
R = ECON_BASE_RES;
|
||||||
|
|
||||||
|
/* Modify based on system conditions. */
|
||||||
|
R += (A->nebu_density + B->nebu_density) / 1000.; /* Density shouldn't affect much. */
|
||||||
|
R += (A->nebu_volatility + B->nebu_volatility) / 100.; /* Volatility should. */
|
||||||
|
|
||||||
|
/* Modify based on global faction. */
|
||||||
|
if((A->faction != -1) && (B->faction != -1)) {
|
||||||
|
if(areEnemies(A->faction, B->faction))
|
||||||
|
R += ECON_FACTION_MOD * ECON_BASE_RES;
|
||||||
|
else if(areAllies(A->faction, B->faction))
|
||||||
|
R -= ECON_FACTION_MOD * ECON_BASE_RES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* @todo Modify based on fleets. */
|
||||||
|
return R;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Calculates the intensity in a system node.
|
||||||
|
*
|
||||||
|
* @todo Make it time/item dependent.
|
||||||
|
*/
|
||||||
|
static double econ_calcSysI(unsigned int dt, StarSystem* sys, int price) {
|
||||||
|
(void)dt;
|
||||||
|
(void)price;
|
||||||
|
int i;
|
||||||
|
double I;
|
||||||
|
double p;
|
||||||
|
Planet* planet;
|
||||||
|
|
||||||
|
/* Calculate production level. */
|
||||||
|
p = 0.;
|
||||||
|
for(i = 0; i < sys->nplanets; i++) {
|
||||||
|
planet = sys->planets[i];
|
||||||
|
if(planet_hasService(planet, PLANET_SERVICE_BASIC))
|
||||||
|
p += planet->prodfactor * sqrt(planet->population);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Intensity is the production minus the consumption. */
|
||||||
|
I = p / ECON_PROD_MODIFIER;
|
||||||
|
|
||||||
|
return I;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create the admitance matrix.
|
||||||
|
* @return 0 on suceess.
|
||||||
|
*/
|
||||||
|
static int econ_createGMatrix(void) {
|
||||||
|
int ret;
|
||||||
|
int i, j;
|
||||||
|
double R, Rsum;
|
||||||
|
cs* M;
|
||||||
|
StarSystem* sys;
|
||||||
|
|
||||||
|
/* Create the matrix. */
|
||||||
|
M = cs_spalloc(systems_nstack, systems_nstack, 1, 1, 1);
|
||||||
|
if(M == NULL)
|
||||||
|
ERR("Unable to create CSparse Matrix.");
|
||||||
|
|
||||||
|
/* Fill the matrix. */
|
||||||
|
for(i = 0; i < systems_nstack; i++) {
|
||||||
|
sys = &systems_stack[i];
|
||||||
|
Rsum = 0.;
|
||||||
|
|
||||||
|
/* Set some values. */
|
||||||
|
for(j = 0; j < sys->njumps; j++) {
|
||||||
|
/* Get the resistance. */
|
||||||
|
R = econ_calcJumpR(sys, &systems_stack[sys->jumps[j]]);
|
||||||
|
R = 1./R; /* Must be inverted. */
|
||||||
|
Rsum += R;
|
||||||
|
|
||||||
|
/* Matrix is symetrical. */
|
||||||
|
ret = cs_entry(M, i, sys->jumps[j], -R);
|
||||||
|
if(ret != 1)
|
||||||
|
WARN("Unable to enter CSparse Matrix Cell.");
|
||||||
|
ret = cs_entry(M, sys->jumps[j], i, -R);
|
||||||
|
if(ret != 1)
|
||||||
|
WARN("Unable to enter CSparse Matrix Cell.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the diagonal. */
|
||||||
|
cs_entry(M, i, i, Rsum + 1./ECON_SELF_RES);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compress M matrix and put into G. */
|
||||||
|
if(econ_G != NULL)
|
||||||
|
cs_spfree(econ_G);
|
||||||
|
econ_G = cs_compress(M);
|
||||||
|
if(econ_G == NULL)
|
||||||
|
ERR("Unable to create economy G Matrix.");
|
||||||
|
|
||||||
|
/* Clean up. */
|
||||||
|
cs_spfree(M);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initializes the economy.
|
||||||
|
*/
|
||||||
|
int economy_init(void) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Allocate price space. */
|
||||||
|
for(i = 0; i < systems_nstack; i++) {
|
||||||
|
if(systems_stack[i].prices != NULL)
|
||||||
|
free(systems_stack[i].prices);
|
||||||
|
systems_stack[i].prices = calloc(econ_nprices, sizeof(double));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the resistance matrix. */
|
||||||
|
if(econ_createGMatrix())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Initialize the prices. */
|
||||||
|
economy_update(0);
|
||||||
|
|
||||||
|
/* Mark economy as initialized. */
|
||||||
|
econ_initialized = 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Regenerates the economy matrix. Should be used if the universe
|
||||||
|
* changes in any permanent way.
|
||||||
|
*/
|
||||||
|
int economy_refresh(void) {
|
||||||
|
/* Economy must be initialized. */
|
||||||
|
if(econ_initialized == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Create the resistance matrix. */
|
||||||
|
if(econ_createGMatrix())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Initialize the prices. */
|
||||||
|
economy_update(0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Updates the economy.
|
||||||
|
* @param dt Deltatick in LTIME.
|
||||||
|
*/
|
||||||
|
int economy_update(unsigned int dt) {
|
||||||
|
int ret;
|
||||||
|
int i, j;
|
||||||
|
double *X;
|
||||||
|
double scale, offset;
|
||||||
|
double min, max;
|
||||||
|
|
||||||
|
/* Create the vector to solve the system. */
|
||||||
|
X = malloc(sizeof(double)*systems_nstack);
|
||||||
|
if(X == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Calculate the results for each price set. */
|
||||||
|
for(j = 0; j < econ_nprices; j++) {
|
||||||
|
/* First we must load the vector with intensities. */
|
||||||
|
for(i = 0; i < systems_nstack; i++)
|
||||||
|
X[i] = econ_calcSysI(dt, &systems_stack[i], j);
|
||||||
|
|
||||||
|
/* Solve the system. */
|
||||||
|
ret = cs_lsolve(econ_G, X);
|
||||||
|
if(ret != 1)
|
||||||
|
WARN("Failed to solve the Economy System.");
|
||||||
|
|
||||||
|
/* Get the minimum and maximum to scale. */
|
||||||
|
min = +HUGE_VALF;
|
||||||
|
max = -HUGE_VALF;
|
||||||
|
for(i = 0; i < systems_nstack; i++) {
|
||||||
|
if(X[i] < min)
|
||||||
|
min = X[i];
|
||||||
|
if(X[i] > max)
|
||||||
|
max = X[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* I'm not sure I like the filtering of the results, but it would take
|
||||||
|
* much more work to get a sane system working without the need of post
|
||||||
|
* filtering.
|
||||||
|
*/
|
||||||
|
/*scale = 1. / (max - min);
|
||||||
|
offset = 0.5 - min * scale;*/
|
||||||
|
scale = 1.;
|
||||||
|
offset = 1.;
|
||||||
|
for(i = 0; i < systems_nstack; i++) {
|
||||||
|
systems_stack[i].prices[j] = X[i] * scale + offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clean up. */
|
||||||
|
free(X);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destroys the economy.
|
||||||
|
*/
|
||||||
|
void economy_destroy(void) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Clean up the prices in the systems stack. */
|
||||||
|
for(i = 0; i < systems_nstack; i++) {
|
||||||
|
if(systems_stack[i].prices != NULL) {
|
||||||
|
free(systems_stack[i].prices);
|
||||||
|
systems_stack[i].prices = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Destroy the economy matrix. */
|
||||||
|
if(econ_G != NULL) {
|
||||||
|
cs_spfree(econ_G);
|
||||||
|
econ_G = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Economy is now deinitialized. */
|
||||||
|
econ_initialized = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
typedef struct Commodity_ {
|
typedef struct Commodity_ {
|
||||||
char* name;
|
char* name; /**< Name of the commodity. */
|
||||||
char* description;
|
char* description; /**< Description of the commodity. */
|
||||||
unsigned int low, medium, high; /* Prices. */
|
double price; /**< Base price of the commodity. */
|
||||||
} Commodity;
|
} Commodity;
|
||||||
|
|
||||||
/* Commidity stuff. */
|
/* Commidity stuff. */
|
||||||
@ -11,6 +11,12 @@ Commodity* commodity_get(const char* name);
|
|||||||
int commodity_load(void);
|
int commodity_load(void);
|
||||||
void commodity_free(void);
|
void commodity_free(void);
|
||||||
|
|
||||||
|
/* Economy stuff. */
|
||||||
|
int economy_init(void);
|
||||||
|
int economy_update(unsigned int dt);
|
||||||
|
int economy_refresh(void);
|
||||||
|
void economy_destroy(void);
|
||||||
|
|
||||||
/* Misc. */
|
/* Misc. */
|
||||||
void credits2str(char* str, unsigned int credits, int decimals);
|
void credits2str(char* str, unsigned int credits, int decimals);
|
||||||
void commodity_Jettison(int pilot, Commodity* com, int quantity);
|
void commodity_Jettison(int pilot, Commodity* com, int quantity);
|
||||||
|
17
src/land.c
17
src/land.c
@ -112,6 +112,9 @@ static void misn_update(unsigned int wid, char* str);
|
|||||||
static void land_checkAddRefuel(void);
|
static void land_checkAddRefuel(void);
|
||||||
static unsigned int refuel_price(void);
|
static unsigned int refuel_price(void);
|
||||||
static void spaceport_refuel(unsigned int wid, char* str);
|
static void spaceport_refuel(unsigned int wid, char* str);
|
||||||
|
/* External. */
|
||||||
|
static unsigned int economy_getPrice(const Commodity* com,
|
||||||
|
const StarSystem* sys, const Planet* p);
|
||||||
|
|
||||||
/* The local market. */
|
/* The local market. */
|
||||||
static void commodity_exchange_open(void) {
|
static void commodity_exchange_open(void) {
|
||||||
@ -182,7 +185,7 @@ static void commodity_update(unsigned int wid, char* str) {
|
|||||||
"\n"
|
"\n"
|
||||||
"%d tons\n",
|
"%d tons\n",
|
||||||
player_cargoOwned(comname),
|
player_cargoOwned(comname),
|
||||||
com->medium,
|
economy_getPrice(com, cur_system, land_planet),
|
||||||
pilot_cargoFree(player));
|
pilot_cargoFree(player));
|
||||||
|
|
||||||
window_modifyText(wid, "txtDInfo", buf);
|
window_modifyText(wid, "txtDInfo", buf);
|
||||||
@ -193,13 +196,14 @@ static void commodity_buy(unsigned int wid, char* str) {
|
|||||||
(void)str;
|
(void)str;
|
||||||
char* comname;
|
char* comname;
|
||||||
Commodity* com;
|
Commodity* com;
|
||||||
int q;
|
unsigned int q, price;
|
||||||
|
|
||||||
q = 10;
|
q = 10;
|
||||||
comname = toolkit_getList(wid, "lstGoods");
|
comname = toolkit_getList(wid, "lstGoods");
|
||||||
com = commodity_get(comname);
|
com = commodity_get(comname);
|
||||||
|
price = economy_getPrice(com, cur_system, land_planet);
|
||||||
|
|
||||||
if(player->credits < q * com->medium) {
|
if(player->credits < q * price) {
|
||||||
dialogue_alert("Not enough Scred!");
|
dialogue_alert("Not enough Scred!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -209,7 +213,7 @@ static void commodity_buy(unsigned int wid, char* str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
q = pilot_addCargo(player, com, q);
|
q = pilot_addCargo(player, com, q);
|
||||||
player->credits -= q * com->medium;
|
player->credits -= q * price;
|
||||||
land_checkAddRefuel();
|
land_checkAddRefuel();
|
||||||
commodity_update(wid, NULL);
|
commodity_update(wid, NULL);
|
||||||
}
|
}
|
||||||
@ -218,14 +222,15 @@ static void commodity_sell(unsigned int wid, char* str) {
|
|||||||
(void)str;
|
(void)str;
|
||||||
char* comname;
|
char* comname;
|
||||||
Commodity* com;
|
Commodity* com;
|
||||||
int q;
|
unsigned int q, price;
|
||||||
|
|
||||||
q = 10;
|
q = 10;
|
||||||
comname = toolkit_getList(wid, "lstGoods");
|
comname = toolkit_getList(wid, "lstGoods");
|
||||||
com = commodity_get(comname);
|
com = commodity_get(comname);
|
||||||
|
price = economy_getPrice(com, cur_system, land_planet);
|
||||||
|
|
||||||
q = pilot_rmCargo(player, com, q);
|
q = pilot_rmCargo(player, com, q);
|
||||||
player->credits += q * com->medium;
|
player->credits += q * price;
|
||||||
land_checkAddRefuel();
|
land_checkAddRefuel();
|
||||||
commodity_update(wid, NULL);
|
commodity_update(wid, NULL);
|
||||||
}
|
}
|
||||||
|
@ -255,7 +255,6 @@ int main(int argc, char** argv) {
|
|||||||
gui_free(); /* Free up the gui. */
|
gui_free(); /* Free up the gui. */
|
||||||
weapon_exit(); /* Destroy all active weapons. */
|
weapon_exit(); /* Destroy all active weapons. */
|
||||||
pilots_free(); /* Free the pilots, they where locked up D: */
|
pilots_free(); /* Free the pilots, they where locked up D: */
|
||||||
space_exit(); /* Cleans up the universe itself. */
|
|
||||||
|
|
||||||
/* Unload data. */
|
/* Unload data. */
|
||||||
unload_all();
|
unload_all();
|
||||||
@ -413,7 +412,9 @@ void load_all(void) {
|
|||||||
* @brief Unloads all data, simplifies main().
|
* @brief Unloads all data, simplifies main().
|
||||||
*/
|
*/
|
||||||
void unload_all(void) {
|
void unload_all(void) {
|
||||||
/* Data unloading - order should not matter, but inverse load_all is good. */
|
/* Data unloading - Inverse load_all is a good order. */
|
||||||
|
economy_destroy(); /* Must be called before space_exit. */
|
||||||
|
space_exit(); /* Cleans up the universe. */
|
||||||
fleet_free();
|
fleet_free();
|
||||||
ships_free();
|
ships_free();
|
||||||
outfit_free();
|
outfit_free();
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "lephisto.h"
|
#include "lephisto.h"
|
||||||
#include "hook.h"
|
#include "hook.h"
|
||||||
|
#include "economy.h"
|
||||||
#include "ltime.h"
|
#include "ltime.h"
|
||||||
|
|
||||||
static unsigned int lephisto_time = 0;
|
static unsigned int lephisto_time = 0;
|
||||||
@ -43,6 +44,8 @@ void ltime_inc(unsigned int t) {
|
|||||||
lephisto_time += t;
|
lephisto_time += t;
|
||||||
|
|
||||||
hooks_run("time");
|
hooks_run("time");
|
||||||
|
|
||||||
|
economy_update(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
15
src/map.c
15
src/map.c
@ -11,15 +11,15 @@
|
|||||||
#include "colour.h"
|
#include "colour.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
|
||||||
#define MAP_WDWNAME "Star Map"
|
#define MAP_WDWNAME "Star Map" /**< Map window name. */
|
||||||
#define WINDOW_WIDTH 650
|
#define WINDOW_WIDTH 650 /**< Map window width. */
|
||||||
#define WINDOW_HEIGHT 540
|
#define WINDOW_HEIGHT 540 /**< Map window height. */
|
||||||
|
|
||||||
#define MAP_WIDTH (WINDOW_WIDTH-150)
|
#define MAP_WIDTH (WINDOW_WIDTH-150) /**< Map window width. */
|
||||||
#define MAP_HEIGHT (WINDOW_HEIGHT-100)
|
#define MAP_HEIGHT (WINDOW_HEIGHT-100) /**< Map height. */
|
||||||
|
|
||||||
#define BUTTON_WIDTH 60
|
#define BUTTON_WIDTH 60 /**< Map button width. */
|
||||||
#define BUTTON_HEIGHT 30
|
#define BUTTON_HEIGHT 30 /**< Map button height. */
|
||||||
|
|
||||||
static double map_zoom = 1.; /**< Zoom of the map. */
|
static double map_zoom = 1.; /**< Zoom of the map. */
|
||||||
static double map_xpos = 0.; /**< Map X position. */
|
static double map_xpos = 0.; /**< Map X position. */
|
||||||
@ -252,6 +252,7 @@ static void map_update(unsigned int wid) {
|
|||||||
for(i = 0; i < sys->nplanets; i++)
|
for(i = 0; i < sys->nplanets; i++)
|
||||||
services |= sys->planets[i]->services;
|
services |= sys->planets[i]->services;
|
||||||
buf[0] = '\0';
|
buf[0] = '\0';
|
||||||
|
/*snprintf(buf, sizeof(buf), "%f\n", sys->prices[0]); */
|
||||||
if(services & PLANET_SERVICE_COMMODITY)
|
if(services & PLANET_SERVICE_COMMODITY)
|
||||||
strcat(buf, "Commodity\n");
|
strcat(buf, "Commodity\n");
|
||||||
if(services & PLANET_SERVICE_OUTFITS)
|
if(services & PLANET_SERVICE_OUTFITS)
|
||||||
|
@ -411,6 +411,9 @@ static int player_newMake(void) {
|
|||||||
/* Clear the map. */
|
/* Clear the map. */
|
||||||
map_clear();
|
map_clear();
|
||||||
|
|
||||||
|
/* Start the economy. */
|
||||||
|
economy_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,6 +221,9 @@ static int load_game(char* file) {
|
|||||||
hook_load(node);
|
hook_load(node);
|
||||||
space_sysLoad(node);
|
space_sysLoad(node);
|
||||||
|
|
||||||
|
/* Initialize the economy. */
|
||||||
|
economy_init();
|
||||||
|
|
||||||
/* Need to run takeoff hooks since player just "took off". */
|
/* Need to run takeoff hooks since player just "took off". */
|
||||||
hooks_run("takeoff");
|
hooks_run("takeoff");
|
||||||
hooks_run("enter");
|
hooks_run("enter");
|
||||||
|
@ -415,6 +415,7 @@ void ships_free(void) {
|
|||||||
if(ship_stack[i].description) free(ship_stack[i].description);
|
if(ship_stack[i].description) free(ship_stack[i].description);
|
||||||
if(ship_stack[i].gui) free(ship_stack[i].gui);
|
if(ship_stack[i].gui) free(ship_stack[i].gui);
|
||||||
if(ship_stack[i].fabricator) free(ship_stack[i].fabricator);
|
if(ship_stack[i].fabricator) free(ship_stack[i].fabricator);
|
||||||
|
if(ship_stack[i].license != NULL) free(ship_stack[i].license);
|
||||||
|
|
||||||
so = ship_stack[i].outfit;
|
so = ship_stack[i].outfit;
|
||||||
while(so) { /* free the ship outfit. */
|
while(so) { /* free the ship outfit. */
|
||||||
|
20
src/space.c
20
src/space.c
@ -712,16 +712,18 @@ static int planet_parse(Planet* planet, const xmlNodePtr parent) {
|
|||||||
else if(xml_isNode(node, "general")) {
|
else if(xml_isNode(node, "general")) {
|
||||||
cur = node->children;
|
cur = node->children;
|
||||||
do {
|
do {
|
||||||
|
/* Direct reads. */
|
||||||
|
xmlr_strd( cur, "bar", planet->bar_description);
|
||||||
|
xmlr_strd( cur, "description", planet->description);
|
||||||
|
xmlr_long( cur, "population", planet->population);
|
||||||
|
xmlr_float( cur, "prodfactor", planet->prodfactor);
|
||||||
|
|
||||||
if(xml_isNode(cur, "class"))
|
if(xml_isNode(cur, "class"))
|
||||||
planet->class = planetclass_get(cur->children->content[0]);
|
planet->class = planetclass_get(cur->children->content[0]);
|
||||||
else if(xml_isNode(cur, "faction")) {
|
else if(xml_isNode(cur, "faction")) {
|
||||||
flags |= FLAG_FACTIONSET;
|
flags |= FLAG_FACTIONSET;
|
||||||
planet->faction = faction_get(xml_get(cur));
|
planet->faction = faction_get(xml_get(cur));
|
||||||
}
|
}
|
||||||
else if(xml_isNode(cur, "description"))
|
|
||||||
planet->description = xml_getStrd(cur);
|
|
||||||
else if(xml_isNode(cur, "bar"))
|
|
||||||
planet->bar_description = xml_getStrd(cur);
|
|
||||||
else if(xml_isNode(cur, "services")) {
|
else if(xml_isNode(cur, "services")) {
|
||||||
flags |= FLAG_SERVICESET;
|
flags |= FLAG_SERVICESET;
|
||||||
planet->services = xml_getInt(cur); /* Flags gotten by data. */
|
planet->services = xml_getInt(cur); /* Flags gotten by data. */
|
||||||
@ -765,6 +767,10 @@ static int planet_parse(Planet* planet, const xmlNodePtr parent) {
|
|||||||
MELEMENT(planet->gfx_space==NULL, "GFX space");
|
MELEMENT(planet->gfx_space==NULL, "GFX space");
|
||||||
MELEMENT(planet_hasService(planet, PLANET_SERVICE_LAND) &&
|
MELEMENT(planet_hasService(planet, PLANET_SERVICE_LAND) &&
|
||||||
planet->gfx_exterior==NULL, "GFX exterior");
|
planet->gfx_exterior==NULL, "GFX exterior");
|
||||||
|
MELEMENT(planet_hasService(planet, PLANET_SERVICE_BASIC) &&
|
||||||
|
(planet->population==0), "population");
|
||||||
|
MELEMENT(planet_hasService(planet, PLANET_SERVICE_BASIC) &&
|
||||||
|
(planet->prodfactor==0.), "prodfactor");
|
||||||
MELEMENT((flags&FLAG_XSET)==0, "x");
|
MELEMENT((flags&FLAG_XSET)==0, "x");
|
||||||
MELEMENT((flags&FLAG_YSET)==0, "y");
|
MELEMENT((flags&FLAG_YSET)==0, "y");
|
||||||
MELEMENT(planet->class==PLANET_CLASS_NULL, "class");
|
MELEMENT(planet->class==PLANET_CLASS_NULL, "class");
|
||||||
@ -824,6 +830,9 @@ int system_addPlanet(StarSystem* sys, char* planetname) {
|
|||||||
|
|
||||||
system_setFaction(sys);
|
system_setFaction(sys);
|
||||||
|
|
||||||
|
/* Regenerate the economy stuff. */
|
||||||
|
economy_refresh();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -878,6 +887,9 @@ int system_rmPlanet(StarSystem* sys, char* planetname) {
|
|||||||
|
|
||||||
system_setFaction(sys);
|
system_setFaction(sys);
|
||||||
|
|
||||||
|
/* Regenerate economy stuff. */
|
||||||
|
economy_refresh();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,9 +61,14 @@ typedef struct Planet_ {
|
|||||||
char* name; /**< Planet name */
|
char* name; /**< Planet name */
|
||||||
Vec2 pos; /**< Position in star system. */
|
Vec2 pos; /**< Position in star system. */
|
||||||
|
|
||||||
|
/* Planet details. */
|
||||||
PlanetClass class; /**< Planet type. */
|
PlanetClass class; /**< Planet type. */
|
||||||
int faction; /**< Planet faction. */
|
int faction; /**< Planet faction. */
|
||||||
|
|
||||||
|
int population; /**< Population of the planet. */
|
||||||
|
double prodfactor; /**< Production factor of the planet. */
|
||||||
|
|
||||||
|
/* Landing details. */
|
||||||
char* description; /**< Planet description. */
|
char* description; /**< Planet description. */
|
||||||
char* bar_description; /**< Spaceport bar description. */
|
char* bar_description; /**< Spaceport bar description. */
|
||||||
unsigned int services; /**< Offered services. */
|
unsigned int services; /**< Offered services. */
|
||||||
@ -75,6 +80,7 @@ typedef struct Planet_ {
|
|||||||
tech[1-PLANET_TECH_MAX] store the
|
tech[1-PLANET_TECH_MAX] store the
|
||||||
"unique" tech levels (only matches) */
|
"unique" tech levels (only matches) */
|
||||||
|
|
||||||
|
/* Graphics. */
|
||||||
glTexture* gfx_space; /**< Graphics in space. */
|
glTexture* gfx_space; /**< Graphics in space. */
|
||||||
char* gfx_exterior; /**< Don't actually load the texture. */
|
char* gfx_exterior; /**< Don't actually load the texture. */
|
||||||
} Planet;
|
} Planet;
|
||||||
@ -127,6 +133,8 @@ typedef struct StarSystem_ {
|
|||||||
double nebu_density; /**< Nebulae density (0. - 1000.).*/
|
double nebu_density; /**< Nebulae density (0. - 1000.).*/
|
||||||
double nebu_volatility; /**< Nebulae volatility (0. - 1000.). */
|
double nebu_volatility; /**< Nebulae volatility (0. - 1000.). */
|
||||||
|
|
||||||
|
double* prices; /**< Handles the prices in the system. */
|
||||||
|
|
||||||
unsigned int flags; /**< Flags for system properties. */
|
unsigned int flags; /**< Flags for system properties. */
|
||||||
} StarSystem;
|
} StarSystem;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user