/* $Id: special.c,v 1.24 2003/07/22 18:29:08 stpohle Exp $ */ /* special.c - procedues to control the specials */ #include "bomberclone.h" #include "basic.h" void special_trigger (int p_nr) { int i, z = 0, ex_nr = bman.last_ex_nr; _player *p = &bman.players[p_nr]; // all triggered bombs will explode for (i = 0; i < MAX_BOMBS; i++) if (p->bombs[i].state == BS_trigger) { p->bombs[i].ex_nr = ex_nr + 5; // we take the next 5 number to be shure bomb_explode (p_nr, i, 0); // no other explosion interfear with it. z++; // count the bombs which will explode } if (p_nr == bman.p_nr && GT_MP_PTP && z) net_game_send_special (p_nr, ex_nr); if (z) { bman.last_ex_nr = ex_nr + 6; p->special.numuse--; if (!p->special.numuse) special_clear (p_nr); } } void special_row (int p_nr) { _bomb *b = NULL; _player *p = &bman.players[p_nr]; int x = p->pos.x >> 8, y = p->pos.y >> 8, dx = 0, dy = 0, t = 0, i; switch (p->d) { case left: dx = -1; break; case right: dx = 1; break; case up: dy = -1; break; case down: dy = +1; break; } x += dx; y += dy; while (map.bfield[x][y]) { x += dx; y += dy; /* add one time tick to each bomb found to ensure that the explosion is infacted by the previous bomb otherwise powerups will disappear due to explosion of previous bomb */ t++; } if (map.field[x][y].type == FT_nothing) { for (i = 0; ((i < p->bombs_n) && (p->bombs[i].state != BS_off)); i++); if (i < p->bombs_n) { b = &p->bombs[i]; b->state = BS_ticking; b->r = p->range; b->ex_nr = -1; b->pos.x = x << 8; b->pos.y = y << 8; b->to = BOMB_TIMEOUT * TIME_FACTOR + t; // 5 Secs * 200 map.bfield[x][y] = 1; if (bman.gametype != GT_single) { net_game_send_bomb (p_nr, i); if (GT_MP_PTPS) b->to = b->to + ((2 * RESENDCACHE_RETRY) / TIME_FACTOR); } } } } void special_push (int p_nr) { _bomb *b = NULL; _player *p = &bman.players[p_nr]; _point bombs[MAX_PLAYERS * MAX_BOMBS]; int x = p->pos.x >> 8, y = p->pos.y >> 8, dx = 0, dy = 0, x1, y1, i; if ((p->pos.x & 0xff) || (p->pos.y & 0xff)) { return; } switch (p->d) { case left: dx = -1; break; case right: dx = 1; break; case up: dy = -1; break; case down: dy = +1; break; } x += dx; y += dy; // check that player is beside a bomb if (!map.bfield[x][y]) return; x1 = x + dx; y1 = y + dy; // check the field behind the bomb if (map.bfield[x1][y1] || map.field[x1][y1].type != FT_nothing) return; get_bomb_on (x << 8, y << 8, bombs); // move all bombs on that field (there should be only 1) for (i = 0; bombs[i].x != -1; i++) { b = &bman.players[bombs[i].x].bombs[bombs[i].y]; if (b->state != BS_exploding) { b->moveto.x = x1 << 8; b->moveto.y = y1 << 8; b->moves = p->speed; map.bfield[x][y] = 0; map.bfield[x1][y1] = 1; stonelist_add (x, y); if (bman.gametype != GT_single) { net_game_send_bomb (bombs[i].x, bombs[i].y); } } } } void special_pickup (int p_nr, int s_nr) { _special *s = &bman.players[p_nr].special; s->to = 0; s->numuse = 0; s->type = s_nr; switch (s_nr) { case SP_trigger: s->numuse = SPECIAL_TRIGGER_NUMUSE; s->to = SPECIAL_TRIGGER_TIME * TIME_FACTOR; break; case SP_row: s->to = SPECIAL_ROW_TIME * TIME_FACTOR; break; case SP_push: s->to = SPECIAL_PUSH_TIME * TIME_FACTOR; break; } bman.updatestatusbar = 1; } void special_clear (int p_nr) { if (bman.players[p_nr].special.type == SP_trigger) { _bomb *bomb; int i; /* put all bombs to normal and if the timeout is higher as usual set it to normal */ for (i = 0; i < MAX_BOMBS; i++) { bomb = &bman.players[p_nr].bombs[i]; if (bomb->state == BS_trigger) { bomb->state = BS_ticking; if (bomb->to > BOMB_TIMEOUT * TIME_FACTOR) bomb->to = BOMB_TIMEOUT * TIME_FACTOR; // 5 Secs * 200 } } } bman.players[p_nr].special.type = 0; bman.updatestatusbar = 1; } void special_loop () { _special *s; int p_nr; for (p_nr = 0; p_nr < MAX_PLAYERS; p_nr++) { s = &bman.players[p_nr].special; if (s->use) { switch (s->type) { case SP_trigger: special_trigger (p_nr); break; case SP_row: if (bman.players[p_nr].m) special_row (p_nr); break; case SP_push: if (bman.players[p_nr].m) special_push (p_nr); break; case SP_kick: break; } s->use = 0; } if (s->type && s->to) { s->to--; if (!s->to) special_clear (p_nr); } } } void special_use (int p_nr) { bman.players[p_nr].special.use = 1; }