diff --git a/gfx/spfx/cargo.png b/gfx/spfx/cargo.png new file mode 100644 index 0000000..c9db109 Binary files /dev/null and b/gfx/spfx/cargo.png differ diff --git a/src/economy.c b/src/economy.c index 8e17f4f..6a90cea 100644 --- a/src/economy.c +++ b/src/economy.c @@ -6,6 +6,9 @@ #include "xml.h" #include "pack.h" #include "log.h" +#include "spfx.h" +#include "pilot.h" +#include "rng.h" #include "economy.h" #define XML_COMMODITY_ID "Commodities" /* XML section identifier. */ @@ -82,6 +85,35 @@ static Commodity* commodity_parse(xmlNodePtr parent) { return tmp; } +/* Throw cargo out into space (graphically). */ +void commodity_Jettison(int pilot, Commodity* com, int quantity) { + (void)com; + int i; + Pilot* p; + int n, effect; + double px, py, r, a, vx, vy; + + p = pilot_get(pilot); + + n = MAX(1, RNG(quantity/10, quantity/5)); + px = p->solid->pos.x; + py = p->solid->pos.y; + + for(i = 0; i < n; i++) { + effect = spfx_get("cargo"); + + /* Radial distribution gives much nicer results. */ + r = RNGF()*25 - 12.5; + a = (double)RNG(0,259); + vx = r*cos(a); + vy = r*sin(a); + + /* Add the cargo effect. */ + spfx_add(effect, px, py, vx, vy, SPFX_LAYER_BACK); + } +} + +/* Init/exit */ int commodity_load(void) { uint32_t bufsize; char* buf = pack_readfile(DATA, COMMODITY_DATA, &bufsize); diff --git a/src/economy.h b/src/economy.h index 76619dc..4d54fe8 100644 --- a/src/economy.h +++ b/src/economy.h @@ -13,4 +13,5 @@ void commodity_free(void); /* Misc. */ void credits2str(char* str, unsigned int credits, int decimals); +void commodity_Jettison(int pilot, Commodity* com, int quantity); diff --git a/src/menu.c b/src/menu.c index 9c8f940..a0f9d8e 100644 --- a/src/menu.c +++ b/src/menu.c @@ -370,6 +370,8 @@ static void cargo_jettison(char* str) { pos = toolkit_getListPos(wid, "lstCargo"); /* Remove the cargo. */ + commodity_Jettison(player->id, player->commodities[pos].commodity, + player->commodities[pos].quantity); pilot_rmCargo(player, player->commodities[pos].commodity, player->commodities[pos].quantity); diff --git a/src/spfx.c b/src/spfx.c index 5cc3be9..8b7ee5e 100644 --- a/src/spfx.c +++ b/src/spfx.c @@ -24,7 +24,9 @@ static int shake_off = 1; typedef struct SPFX_Base_ { char* name; + double ttl; /* Time to live. */ double anim; /* Total duration in ms. */ + glTexture* gfx; /* Will use each sprite as a frame. */ } SPFX_Base; @@ -48,13 +50,13 @@ static SPFX* spfx_stack_back = NULL; static int spfx_nstack_back = 0; static int spfx_mstack_back = 0; -static int spfx_base_load(char* name, int anim, char* gfx, int sx, int sy); +static int spfx_base_load(char* name, int ttl, int anim, char* gfx, int sx, int sy); static void spfx_base_free(SPFX_Base* effect); static void spfx_destroy(SPFX* layer, int* nlayer, int spfx); static void spfx_update_layer(SPFX* layer, int* nlayer, const double dt); /* Load the SPFX_Base. */ -static int spfx_base_load(char* name, int anim, char* gfx, int sx, int sy) { +static int spfx_base_load(char* name, int ttl, int anim, char* gfx, int sx, int sy) { SPFX_Base* cur; char buf[PATH_MAX]; @@ -65,6 +67,7 @@ static int spfx_base_load(char* name, int anim, char* gfx, int sx, int sy) { /* Fill it with the data. */ cur->name = strdup(name); cur->anim = (double)anim / 1000.; + cur->ttl = (double)ttl / 1000.; sprintf(buf, SPFX_GFX"%s", gfx); cur->gfx = gl_newSprite(buf, sx, sy); @@ -90,9 +93,10 @@ int spfx_get(char* name) { */ int spfx_load(void) { /* Standard explosion effects. */ - spfx_base_load("ExpS", 400, "exps.png", 6, 5); - spfx_base_load("ExpM", 450, "expm.png", 6, 5); - spfx_base_load("ExpL", 500, "expl.png", 6, 5); + spfx_base_load("ExpS", 400, 400, "exps.png", 6, 5); + spfx_base_load("ExpM", 450, 450, "expm.png", 6, 5); + spfx_base_load("ExpL", 500, 500, "expl.png", 6, 5); + spfx_base_load("cargo", 15000, 5000, "cargo.png", 6, 6); return 0; } @@ -119,8 +123,11 @@ void spfx_add(int effect, const double px, const double py, const double vx, const double vy, const int layer) { - SPFX* cur_spfx; + SPFX* cur_spfx; + double ttl, anim; + + /* Select the layer. */ if(layer == SPFX_LAYER_FRONT) { /* Front layer. */ if(spfx_mstack_front < spfx_nstack_front+1) { @@ -142,10 +149,17 @@ void spfx_add(int effect, spfx_nstack_back++; } + /* The actualy adding of the spfx. */ cur_spfx->effect = effect; vect_csetmin(&cur_spfx->pos, px, py); vect_csetmin(&cur_spfx->vel, vx, vy); - cur_spfx->timer = (double)spfx_effects[effect].anim; + /* timer magic if ttl != anim. */ + ttl = spfx_effects[effect].ttl; + anim = spfx_effects[effect].anim; + if(ttl != anim) + cur_spfx->timer = ttl + RNGF()*anim; + else + cur_spfx->timer = ttl; } void spfx_clear(void) { @@ -264,6 +278,7 @@ void spfx_render(const int layer) { int i, spfx_nstack; SPFX_Base* effect; int sx, sy; + double time; /* Get the appropriate layer. */ switch(layer) { @@ -285,9 +300,10 @@ void spfx_render(const int layer) { sx = (int)effect->gfx->sx; sy = (int)effect->gfx->sy; - if(!paused) /* Don't calculate frame if paused. */ - spfx_stack[i].lastframe = sx * sy - * MIN(((double)(spfx_stack[i].timer)/(double)effect->anim), 1.); + if(!paused) { /* Don't calculate frame if paused. */ + time = fmod(spfx_stack[i].timer, effect->anim) / effect->anim; + spfx_stack[i].lastframe = sx * sy * MIN(time, 1.); + } /* Render. */ gl_blitSprite(effect->gfx,