You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
bomberclone/src/special.c

197 lines
4.2 KiB

/* 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;
}}