|
|
|
@ -1,4 +1,4 @@
|
|
|
|
|
/* $Id: bomb.c,v 1.54 2004/01/25 19:36:46 stpohle Exp $ */
|
|
|
|
|
/* $Id: bomb.c,v 1.55 2004/02/05 21:32:18 stpohle Exp $ */
|
|
|
|
|
/* everything what have to do with the bombs */
|
|
|
|
|
|
|
|
|
|
#include "bomberclone.h"
|
|
|
|
@ -88,17 +88,16 @@ draw_bomb (_bomb * bomb)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
bomb_explode (int p, int b, int net)
|
|
|
|
|
bomb_explode (_bomb *bomb, int net)
|
|
|
|
|
{
|
|
|
|
|
int d;
|
|
|
|
|
_bomb *bomb = &players[p].bombs[b];
|
|
|
|
|
|
|
|
|
|
d_printf ("Bomb Explode p:%d, b:%d [%f,%f]\n", p, b, bomb->pos.x, bomb->pos.y);
|
|
|
|
|
d_printf ("Bomb Explode p:%d, b:%d [%f,%f]\n", bomb->id.p, bomb->id.b, bomb->pos.x, bomb->pos.y);
|
|
|
|
|
|
|
|
|
|
if (bomb->ex_nr == -1)
|
|
|
|
|
bomb->ex_nr = bman.last_ex_nr++; // set bomb explosion id
|
|
|
|
|
|
|
|
|
|
players[p].bomb_lastex = b;
|
|
|
|
|
players[bomb->id.p].bomb_lastex = bomb->id.b;
|
|
|
|
|
|
|
|
|
|
bomb->to = EXPLOSIONTIMEOUT; /* set the timeout for the fireexplosion */
|
|
|
|
|
bomb->state = BS_exploding;
|
|
|
|
@ -108,7 +107,7 @@ bomb_explode (int p, int b, int net)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (GT_MP_PTPM && net) /* from now on only the server let the bomb explode */
|
|
|
|
|
net_game_send_bomb (p, b);
|
|
|
|
|
net_game_send_bomb (bomb->id.p, bomb->id.b);
|
|
|
|
|
|
|
|
|
|
snd_play (SND_explode);
|
|
|
|
|
};
|
|
|
|
@ -242,7 +241,7 @@ bomb_loop ()
|
|
|
|
|
if (GT_MP_PTPM || GT_SP) {
|
|
|
|
|
bomb->to -= timediff;
|
|
|
|
|
if (bomb->to <= 0.0f) // bomb will have to explode in the next loop
|
|
|
|
|
bomb_explode (p, i, 1);
|
|
|
|
|
bomb_explode (bomb, 1);
|
|
|
|
|
else
|
|
|
|
|
draw_bomb (bomb);
|
|
|
|
|
}
|
|
|
|
@ -267,7 +266,7 @@ bomb_loop ()
|
|
|
|
|
|
|
|
|
|
case BS_exploding:
|
|
|
|
|
if (bomb->to > 0.0f) {
|
|
|
|
|
do_explosion (p, i);
|
|
|
|
|
do_explosion (bomb);
|
|
|
|
|
}
|
|
|
|
|
if (bomb->to <= 0.0f) { // explosion done
|
|
|
|
|
restore_explosion (bomb);
|
|
|
|
@ -313,35 +312,11 @@ get_bomb_on (float x, float y, _point bombs[])
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* if frame == -1 we will draw the framenumber in
|
|
|
|
|
the field.ex data */
|
|
|
|
|
void
|
|
|
|
|
draw_fire (int x, int y, int d, int frame)
|
|
|
|
|
{
|
|
|
|
|
SDL_Rect src,
|
|
|
|
|
dest;
|
|
|
|
|
|
|
|
|
|
if (frame == -1) // no giving frame
|
|
|
|
|
frame = map.field[x][y].ex[d].frame;
|
|
|
|
|
|
|
|
|
|
dest.w = src.w = gfx.block.x;
|
|
|
|
|
dest.h = src.h = gfx.block.y;
|
|
|
|
|
|
|
|
|
|
dest.x = gfx.offset.x + x * gfx.block.x;
|
|
|
|
|
dest.y = gfx.offset.y + y * gfx.block.y;
|
|
|
|
|
|
|
|
|
|
src.y = frame * src.w;
|
|
|
|
|
src.x = d * src.w;
|
|
|
|
|
|
|
|
|
|
gfx_blit (gfx.fire.image, &src, gfx.screen, &dest, (y * 100));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
restore_explosion (_bomb * bomb)
|
|
|
|
|
{
|
|
|
|
|
int i,
|
|
|
|
|
j,
|
|
|
|
|
d,
|
|
|
|
|
dx = 0,
|
|
|
|
|
dy = 0,
|
|
|
|
@ -370,22 +345,21 @@ restore_explosion (_bomb * bomb)
|
|
|
|
|
|
|
|
|
|
_x = bomb->pos.x;
|
|
|
|
|
_y = bomb->pos.y;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* with every field where was an fire on it decrease the ex[].count value
|
|
|
|
|
* and force an drawing of this field */
|
|
|
|
|
for (i = 0; i < bomb->firer[d]; i++) {
|
|
|
|
|
if (--map.field[_x][_y].ex[d].count == 0) // there was only one explosion so
|
|
|
|
|
map.field[_x][_y].ex[d].frame = 0; // reset the framenumber
|
|
|
|
|
|
|
|
|
|
for (j = 0; j >= 0 && j < 4; j++)
|
|
|
|
|
if (map.field[_x][_y].ex[j].count > 0 && j != d)
|
|
|
|
|
j = -4;
|
|
|
|
|
if (j > 0)
|
|
|
|
|
stonelist_add (_x, _y);
|
|
|
|
|
stonelist_add (_x, _y);
|
|
|
|
|
|
|
|
|
|
_x = _x + dx;
|
|
|
|
|
_y = _y + dy;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// delete the stone completly if there was any in the way
|
|
|
|
|
/* delete the stone completly if there was any in the way
|
|
|
|
|
* push the values field->type = fiels->special */
|
|
|
|
|
if (bomb->firer[d] <= bomb->r && map.field[_x][_y].type != FT_block
|
|
|
|
|
&& map.field[_x][_y].type != FT_tunnel && bomb->ex_nr != map.field[_x][_y].ex_nr) {
|
|
|
|
|
|
|
|
|
@ -416,13 +390,12 @@ restore_explosion (_bomb * bomb)
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
check the field on which the explosion is
|
|
|
|
|
*/
|
|
|
|
|
int
|
|
|
|
|
explosion_check_field (int x, int y, int p, int b)
|
|
|
|
|
/* check the field if there is another bomb stone or wathever
|
|
|
|
|
* if a bomb is found let this one explode, on a player well this player
|
|
|
|
|
* will die and if a stone was found, start with the stone explosion
|
|
|
|
|
* RETURN: value of the stonetype (FT_*) */
|
|
|
|
|
int explosion_check_field (int x, int y, _bomb *bomb)
|
|
|
|
|
{
|
|
|
|
|
_bomb *bomb = &players[p].bombs[b];
|
|
|
|
|
int pl[MAX_PLAYERS];
|
|
|
|
|
int i;
|
|
|
|
|
_point bo[MAX_PLAYERS * MAX_BOMBS];
|
|
|
|
@ -435,12 +408,12 @@ explosion_check_field (int x, int y, int p, int b)
|
|
|
|
|
get_player_on (x, y, pl);
|
|
|
|
|
get_bomb_on (x, y, bo);
|
|
|
|
|
|
|
|
|
|
// check if any bomb have to explode..
|
|
|
|
|
/* check if any bomb have to explode.. */
|
|
|
|
|
for (i = 0; bo[i].x != -1; i++) {
|
|
|
|
|
tmpbomb = &players[bo[i].x].bombs[bo[i].y];
|
|
|
|
|
if (tmpbomb != bomb && tmpbomb->state != BS_exploding) {
|
|
|
|
|
tmpbomb->ex_nr = bomb->ex_nr; // set the ex_nr to identify explosions
|
|
|
|
|
bomb_explode (bo[i].x, bo[i].y, 1);
|
|
|
|
|
bomb_explode (&players[bo[i].x].bombs[bo[i].y], 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -450,7 +423,7 @@ explosion_check_field (int x, int y, int p, int b)
|
|
|
|
|
if (((tmpplayer->state & PSF_alife) != 0)
|
|
|
|
|
&& (GT_SP || (GT_MP && (&players[bman.p_nr] == tmpplayer))
|
|
|
|
|
|| (GT_MP_PTPM && PS_IS_aiplayer (tmpplayer->state))))
|
|
|
|
|
player_died (tmpplayer, p);
|
|
|
|
|
player_died (tmpplayer, bomb->id.p);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// let the stones right beside explode
|
|
|
|
@ -499,22 +472,23 @@ draw_explosion (_bomb * bomb)
|
|
|
|
|
p.y = bomb->pos.y;
|
|
|
|
|
|
|
|
|
|
for (r = 0; r < bomb->firer[d]; r++) {
|
|
|
|
|
map.field[p.x][p.y].ex[d].bomb_p = bomb->id.p;
|
|
|
|
|
map.field[p.x][p.y].ex[d].bomb_b = bomb->id.b;
|
|
|
|
|
map.field[p.x][p.y].ex[d].frame += timefactor;
|
|
|
|
|
if (map.field[p.x][p.y].ex[d].frame >= gfx.fire.frames)
|
|
|
|
|
map.field[p.x][p.y].ex[d].frame = 0.0f;
|
|
|
|
|
stonelist_add (p.x, p.y);
|
|
|
|
|
draw_fire (p.x, p.y, d, -1);
|
|
|
|
|
p.x += dx;
|
|
|
|
|
p.y += dy;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* do the bombexplosion itself */
|
|
|
|
|
/* do the bombexplosion itself, with every loop for one explosion
|
|
|
|
|
* add one more distance from the bomb if no stones are in the way */
|
|
|
|
|
void
|
|
|
|
|
do_explosion (int p, int b)
|
|
|
|
|
do_explosion (_bomb *bomb)
|
|
|
|
|
{
|
|
|
|
|
_bomb *bomb = &players[p].bombs[b];
|
|
|
|
|
int dx = 0,
|
|
|
|
|
dy = 0,
|
|
|
|
|
d;
|
|
|
|
@ -545,15 +519,13 @@ do_explosion (int p, int b)
|
|
|
|
|
dx = bomb->firer[d] * dx;
|
|
|
|
|
dy = bomb->firer[d] * dy;
|
|
|
|
|
|
|
|
|
|
checkfield = explosion_check_field (bomb->pos.x + dx, bomb->pos.y + dy, p, b);
|
|
|
|
|
checkfield = explosion_check_field (bomb->pos.x + dx, bomb->pos.y + dy, bomb);
|
|
|
|
|
if ((checkfield == FT_nothing || checkfield == FT_tunnel)
|
|
|
|
|
&& bomb->firerst[d] == -1) {
|
|
|
|
|
bomb->firer[d]++;
|
|
|
|
|
map.field[(int) bomb->pos.x + dx][(int) bomb->pos.y + dy].ex[d].count++;
|
|
|
|
|
map.field[(int) bomb->pos.x + dx][(int) bomb->pos.y + dy].ex[d].frame =
|
|
|
|
|
bomb->firer[d];
|
|
|
|
|
/* if we have a slow pc we can enable this and disable the drawing animation */
|
|
|
|
|
// draw_fire (bomb->pos.x + dx, bomb->pos.y + dy, d, gfx.fire.frames>>1);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
bomb->firerst[d] = bomb->firer[d];
|
|
|
|
|