|
|
|
@ -1,4 +1,4 @@
|
|
|
|
|
/* $Id: map.c,v 1.15 2003/12/28 01:35:35 stpohle Exp $ */
|
|
|
|
|
/* $Id: map.c,v 1.16 2003/12/28 04:51:25 stpohle Exp $ */
|
|
|
|
|
/* map handling, like generate and load maps. */
|
|
|
|
|
|
|
|
|
|
#include "bomberclone.h"
|
|
|
|
@ -162,142 +162,204 @@ map_genrandom ()
|
|
|
|
|
|
|
|
|
|
/* will set the playerposition but in a way that we won't start on a block */
|
|
|
|
|
/* i am just too lazy to write this all again and again */
|
|
|
|
|
#define PLX players[i].pos.x
|
|
|
|
|
#define PLY players[i].pos.y
|
|
|
|
|
void
|
|
|
|
|
map_set_playerposition (int usermap)
|
|
|
|
|
{
|
|
|
|
|
int p,
|
|
|
|
|
dist,
|
|
|
|
|
i,
|
|
|
|
|
j,
|
|
|
|
|
mx,
|
|
|
|
|
my,
|
|
|
|
|
dx = 0,
|
|
|
|
|
dy = 0;
|
|
|
|
|
char txt[255];
|
|
|
|
|
|
|
|
|
|
p = 50;
|
|
|
|
|
dist = 8;
|
|
|
|
|
while (p == 50) {
|
|
|
|
|
p = 0;
|
|
|
|
|
dist--;
|
|
|
|
|
for (i = 0; (p < 50 && i < MAX_PLAYERS);)
|
|
|
|
|
if (PS_IS_playing (players[i].state))
|
|
|
|
|
{
|
|
|
|
|
int maxloop = 0;
|
|
|
|
|
while (maxloop < 200 && (PLX == -1 || PLY == -1)) {
|
|
|
|
|
maxloop++;
|
|
|
|
|
PLX = s_random (map.size.x - 2) + 1;
|
|
|
|
|
PLY = s_random (map.size.y - 2) + 1;
|
|
|
|
|
|
|
|
|
|
for (dx = 10, dy = 10, j = 0; (j < i && j < MAX_PLAYERS && (dx > 1 || dy > 1)); j++) { /* is ther any other player */
|
|
|
|
|
dx = PLX - players[j].pos.x;
|
|
|
|
|
#define PLX(__i) players[__i].pos.x
|
|
|
|
|
#define PLY(__i) players[__i].pos.y
|
|
|
|
|
|
|
|
|
|
/* check if there is another player in the near if so delete player pos for another try */
|
|
|
|
|
void map_playerpos_check (int pl) {
|
|
|
|
|
int i, d = MAX_FIELDSIZE_X, dx, dy;
|
|
|
|
|
for (i = 0; (i < MAX_PLAYERS && d > 1); i++)
|
|
|
|
|
if (i != pl) {
|
|
|
|
|
dx = PLX(i) - PLX(pl);
|
|
|
|
|
if (dx < 0)
|
|
|
|
|
dx = -dx;
|
|
|
|
|
dy = PLY - players[j].pos.y;
|
|
|
|
|
dy = PLY(i) - PLY(pl);
|
|
|
|
|
if (dy < 0)
|
|
|
|
|
dy = -dy;
|
|
|
|
|
if (dx < dy) // save the biggest distance in there
|
|
|
|
|
dx = dy;
|
|
|
|
|
if (dx < d)
|
|
|
|
|
d = dx;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (d < 2) {
|
|
|
|
|
PLX(pl) = -1;
|
|
|
|
|
PLY(pl) = -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
map_set_player_way1 (int pl)
|
|
|
|
|
{
|
|
|
|
|
_point p, t[4];
|
|
|
|
|
int i, j, ok = 0;
|
|
|
|
|
|
|
|
|
|
p.x = s_random (map.size.x - 2) + 1;
|
|
|
|
|
p.y = s_random (map.size.y - 2) + 1;
|
|
|
|
|
|
|
|
|
|
d_printf ("map_set_player_way2 (%d) : %d,%d\n", pl, p.x, p.y);
|
|
|
|
|
|
|
|
|
|
/* check if there is no block */
|
|
|
|
|
if ((dx > 1 || dy > 1)
|
|
|
|
|
&& ((map.field[(int)PLX][(int)PLY].type != FT_block && maxloop > 100)
|
|
|
|
|
|| map.field[(int)PLX][(int)PLY].type == FT_nothing)) {
|
|
|
|
|
/* get (up or down) dx and (left or right) dy */
|
|
|
|
|
dx = s_random (2);
|
|
|
|
|
if (dx == 0)
|
|
|
|
|
dx = -1;
|
|
|
|
|
dy = s_random (2);
|
|
|
|
|
if (dy == 0)
|
|
|
|
|
dy = -1;
|
|
|
|
|
|
|
|
|
|
/* first check if there is a free place for us */
|
|
|
|
|
if (!((map.field[(int)PLX + dx][(int)PLY].type != FT_block && maxloop > 100) ||
|
|
|
|
|
map.field[(int)PLX + dx][(int)PLY].type == FT_nothing))
|
|
|
|
|
dx = -dx;
|
|
|
|
|
if (!((map.field[(int)PLX + dx][(int)PLY].type != FT_block && maxloop > 100) ||
|
|
|
|
|
map.field[(int)PLX + dx][(int)PLY].type == FT_nothing))
|
|
|
|
|
PLX = -1;
|
|
|
|
|
if (map.field[p.x][p.y].type != FT_nothing)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (!((map.field[(int)PLX][(int)PLY + dy].type != FT_block && maxloop > 100) ||
|
|
|
|
|
map.field[(int)PLX][(int)PLY + dy].type == FT_nothing))
|
|
|
|
|
dy = -dy;
|
|
|
|
|
if (!((map.field[(int)PLX][(int)PLY + dy].type != FT_block && maxloop > 100) ||
|
|
|
|
|
map.field[(int)PLX][(int)PLY + dy].type == FT_nothing))
|
|
|
|
|
PLY = -1;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
PLX = -1;
|
|
|
|
|
PLY = -1;
|
|
|
|
|
/* check if we can run away somewhere */
|
|
|
|
|
for (j = 0; j < 4; j++) {
|
|
|
|
|
t[j].x = p.x;
|
|
|
|
|
t[j].y = p.y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* make some space */
|
|
|
|
|
if (PLX >= 0.0f && PLY >= 0.0f) {
|
|
|
|
|
if (map.field[(int)PLX][(int)PLY].type != FT_tunnel)
|
|
|
|
|
map.field[(int)PLX][(int)PLY].type = FT_nothing;
|
|
|
|
|
if (map.field[(int)PLX + dx][(int)PLY].type != FT_tunnel)
|
|
|
|
|
map.field[(int)PLX + dx][(int)PLY].type = FT_nothing;
|
|
|
|
|
if (map.field[(int)PLX][(int)PLY + dy].type != FT_tunnel)
|
|
|
|
|
map.field[(int)PLX][(int)PLY + dy].type = FT_nothing;
|
|
|
|
|
for (i = 0; (i < 10 && ok == 0); i++) {
|
|
|
|
|
t[left].x -= 1;
|
|
|
|
|
t[right].x += 1;
|
|
|
|
|
t[up].y = -1;
|
|
|
|
|
t[down].y += 1;
|
|
|
|
|
for (j = 0; j < 4; j++)
|
|
|
|
|
if (t[j].x > 0 && t[j].x < map.size.x
|
|
|
|
|
&& t[j].y > 0 && t[j].y < map.size.y) {
|
|
|
|
|
if (map.field[t[j].x][t[j].y].type == FT_nothing) {
|
|
|
|
|
if ((j == left || j == right)
|
|
|
|
|
&& map.field[t[j].x][t[j].y - 1].type == FT_nothing
|
|
|
|
|
&& map.field[t[j].x][t[j].y + 1].type == FT_nothing)
|
|
|
|
|
ok = 1;
|
|
|
|
|
if ((j == up || j == down)
|
|
|
|
|
&& map.field[t[j].x - 1][t[j].y].type == FT_nothing
|
|
|
|
|
&& map.field[t[j].x + 1][t[j].y].type == FT_nothing)
|
|
|
|
|
ok = 1;
|
|
|
|
|
}
|
|
|
|
|
else { /* this field is not free anymore */
|
|
|
|
|
t[j].x = -1;
|
|
|
|
|
t[j].y = -1;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
t[j].x = -1;
|
|
|
|
|
t[j].y = -1;
|
|
|
|
|
}
|
|
|
|
|
if (PLX < 0 || PLY < 0) {
|
|
|
|
|
/* we could not set all fields or we don't run on a usermap */
|
|
|
|
|
if (usermap) {
|
|
|
|
|
sprintf (txt, "Not all players could be set (Pl:%d)", i);
|
|
|
|
|
// menu_displaymessage ("MAP - ERROR", txt);
|
|
|
|
|
}
|
|
|
|
|
if (ok) {
|
|
|
|
|
PLX(pl) = p.x;
|
|
|
|
|
PLY(pl) = p.y;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* now there will be some fields deleted */
|
|
|
|
|
PLX = 2 * (s_random ((map.size.x - 1) / 2)) + 1;
|
|
|
|
|
PLY = 2 * (s_random ((map.size.y - 1) / 2)) + 1;
|
|
|
|
|
void
|
|
|
|
|
map_set_player_way2 (int pl)
|
|
|
|
|
{
|
|
|
|
|
_point p, t[4];
|
|
|
|
|
int i, j, ok = 0;
|
|
|
|
|
|
|
|
|
|
if (map.field[(int)PLX][(int)PLY].type != FT_tunnel)
|
|
|
|
|
map.field[(int)PLX][(int)PLY].type = FT_nothing;
|
|
|
|
|
p.x = s_random (map.size.x - 2) + 1;
|
|
|
|
|
p.y = s_random (map.size.y - 2) + 1;
|
|
|
|
|
|
|
|
|
|
dx = s_random (4); // bit 1 = up/down bit 2 = left/right
|
|
|
|
|
/* up and down */
|
|
|
|
|
if (((dx & 1) == 0 && PLX > 1.0f) || PLX >= map.size.x - 2) {
|
|
|
|
|
if (map.field[(int)PLX - 1][(int)PLY].type != FT_tunnel)
|
|
|
|
|
map.field[(int)PLX - 1][(int)PLY].type = FT_nothing;
|
|
|
|
|
d_printf ("map_set_player_way2 (%d) : %d,%d\n", pl, p.x, p.y);
|
|
|
|
|
|
|
|
|
|
/* check if there is no block */
|
|
|
|
|
if (map.field[p.x][p.y].type != FT_nothing)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* check if we can run away somewhere */
|
|
|
|
|
for (j = 0; j < 4; j++) {
|
|
|
|
|
t[j].x = p.x;
|
|
|
|
|
t[j].y = p.y;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (map.field[(int)PLX + 1][(int)PLY].type != FT_tunnel)
|
|
|
|
|
map.field[(int)PLX + 1][(int)PLY].type = FT_nothing;
|
|
|
|
|
|
|
|
|
|
for (i = 0; (i < 10 && ok == 0); i++) {
|
|
|
|
|
t[left].x -= 1;
|
|
|
|
|
t[right].x += 1;
|
|
|
|
|
t[up].y = -1;
|
|
|
|
|
t[down].y += 1;
|
|
|
|
|
for (j = 0; j < 4; j++)
|
|
|
|
|
if (t[j].x > 0 && t[j].x < map.size.x
|
|
|
|
|
&& t[j].y > 0 && t[j].y < map.size.y) {
|
|
|
|
|
if (map.field[t[j].x][t[j].y].type == FT_nothing) {
|
|
|
|
|
if (ok == 0 && (j == left || j == right) && map.field[t[j].x][t[j].y - 1].type == FT_stone) {
|
|
|
|
|
map.field[t[j].x][t[j].y - 1].type = FT_nothing;
|
|
|
|
|
map.field[t[j].x][t[j].y - 1].special = FT_nothing;
|
|
|
|
|
ok = 1;
|
|
|
|
|
}
|
|
|
|
|
/* left and right */
|
|
|
|
|
if (((dx & 2) == 0 && PLY > 1) || PLY >= map.size.y - 2) {
|
|
|
|
|
if (map.field[(int)PLX][(int)PLY - 1].type != FT_tunnel)
|
|
|
|
|
map.field[(int)PLX][(int)PLY - 1].type = FT_nothing;
|
|
|
|
|
if (ok == 0 && (j == left || j == right) && map.field[t[j].x][t[j].y + 1].type == FT_stone) {
|
|
|
|
|
map.field[t[j].x][t[j].y + 1].type = FT_nothing;
|
|
|
|
|
map.field[t[j].x][t[j].y + 1].special = FT_nothing;
|
|
|
|
|
ok = 1;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (map.field[(int)PLX][(int)PLY + 1].type != FT_tunnel)
|
|
|
|
|
map.field[(int)PLX][(int)PLY + 1].type = FT_nothing;
|
|
|
|
|
if (ok == 0 && (j == up || j == down) && map.field[t[j].x + 1][t[j].y].type == FT_stone) {
|
|
|
|
|
map.field[t[j].x + 1][t[j].y].type = FT_nothing;
|
|
|
|
|
map.field[t[j].x + 1][t[j].y].special = FT_nothing;
|
|
|
|
|
ok = 1;
|
|
|
|
|
}
|
|
|
|
|
if (ok == 0 && (j == up || j == down) && map.field[t[j].x - 1][t[j].y].type == FT_stone) {
|
|
|
|
|
map.field[t[j].x - 1][t[j].y].type = FT_nothing;
|
|
|
|
|
map.field[t[j].x - 1][t[j].y].special = FT_nothing;
|
|
|
|
|
ok = 1;
|
|
|
|
|
}
|
|
|
|
|
mx = my = 100;
|
|
|
|
|
for (j = 0; j <= i; j++) { /* search smalest distance */
|
|
|
|
|
dy = PLY - players[j].pos.y;
|
|
|
|
|
dx = PLX - players[j].pos.x;
|
|
|
|
|
if (dy < 0)
|
|
|
|
|
dy = -dy;
|
|
|
|
|
if (dx < 0)
|
|
|
|
|
dx = -dx;
|
|
|
|
|
|
|
|
|
|
if (mx > dx && i != j)
|
|
|
|
|
mx = dx;
|
|
|
|
|
if (my > dy && i != j)
|
|
|
|
|
my = dy;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mx > dist || my > dist)
|
|
|
|
|
i++;
|
|
|
|
|
else
|
|
|
|
|
p++;
|
|
|
|
|
else { /* this field is not free anymore */
|
|
|
|
|
t[j].x = -1;
|
|
|
|
|
t[j].y = -1;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
t[j].x = -1;
|
|
|
|
|
t[j].y = -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (ok) {
|
|
|
|
|
PLX(pl) = p.x;
|
|
|
|
|
PLY(pl) = p.y;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
map_set_playerposition (int usermap)
|
|
|
|
|
{
|
|
|
|
|
int pl,
|
|
|
|
|
ready,
|
|
|
|
|
maxtry;
|
|
|
|
|
|
|
|
|
|
/* try to set every player on a good place */
|
|
|
|
|
maxtry = 300;
|
|
|
|
|
ready = 0;
|
|
|
|
|
while (!ready && maxtry-- > 0) {
|
|
|
|
|
ready = 1;
|
|
|
|
|
for (pl = 0; pl < MAX_PLAYERS; pl++)
|
|
|
|
|
if (PS_IS_used (players[pl].state) && (PLX (pl) < 0 || PLY (pl) < 0)) {
|
|
|
|
|
/* set player */
|
|
|
|
|
ready = 0;
|
|
|
|
|
map_set_player_way1 (pl);
|
|
|
|
|
map_playerpos_check (pl);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* every player which is still not set .. set now and delete some normal stones */
|
|
|
|
|
maxtry = 200;
|
|
|
|
|
ready = 0;
|
|
|
|
|
while (!ready && maxtry-- > 0) {
|
|
|
|
|
ready = 1;
|
|
|
|
|
for (pl = 0; pl < MAX_PLAYERS; pl++)
|
|
|
|
|
if (PS_IS_used (players[pl].state) && (PLX (pl) < 0 || PLY (pl) < 0)) {
|
|
|
|
|
/* set player */
|
|
|
|
|
ready = 0;
|
|
|
|
|
map_set_player_way2 (pl);
|
|
|
|
|
if (maxtry > 50)
|
|
|
|
|
map_playerpos_check (pl);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* every player who is still not set ... let them die before they
|
|
|
|
|
* can play put a warning on the screen */
|
|
|
|
|
maxtry = 0; // mark our warning
|
|
|
|
|
for (pl = 0; pl < MAX_PLAYERS; pl++)
|
|
|
|
|
if (PS_IS_used (players[pl].state) && (PLX (pl) < 0 || PLY (pl) < 0)) {
|
|
|
|
|
PLX (pl) = 0.0;
|
|
|
|
|
PLY (pl) = 0.0;
|
|
|
|
|
maxtry = 1;
|
|
|
|
|
}
|
|
|
|
|
if (maxtry)
|
|
|
|
|
d_fatal ("Not All Player could been set\n");
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#undef PLX
|
|
|
|
|
#undef PLY
|
|
|
|
|
|
|
|
|
|