/* 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 (bman.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 (bman.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 bman.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; 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; if (!bman.bfield[x][y]) return; x1 = x + dx; y1 = y + dy; if (bman.bfield[x1][y1] || bman.field[x1][y1].type != FT_nothing) return; get_bomb_on (x, y, bombs); for (i = 0; bombs[i].x != -1; i++) { b = &bman.players[bombs[i].x].bombs[bombs[i].y]; if (b->state != BS_exploding) { b->pos.x = x1<<8; b->pos.y = y1<<8; bman.bfield[x][y]=0; bman.bfield[x1][y1]=1; draw_stone(x,y); field_update(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; } } void special_clear (int p_nr) { bman.players[p_nr].special.type=0; bman.updatestatusbar=1; } void special_loop (int p_nr) { _special *s = &bman.players[p_nr].special; if (!s->type) return; bman.updatestatusbar=1; if (s->to) { s->to--; if (!s->to) special_clear (p_nr); } } void special_use (int p_nr) { switch (bman.players[p_nr].special.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; }}