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/game.c

287 lines
8.1 KiB

/* game.c - procedures for the game. */
#include <string.h>
#include <SDL.h>
#include "bomberclone.h"
#include "gfx.h"
#include "network.h"
#include "packets.h"
#include "chat.h"
extern int UpdateRects_nr;
void
game_draw_info ()
{
int i,
x,
j,
gfx_oldRects;
char text[255];
char scrtext[255];
SDL_Rect src, dest;
redraw_logo (0, 0, gfx.res.x, 3*16);
gfx_AddUpdateRect (0,0, gfx.res.x, 3*16);
gfx_oldRects = UpdateRects_nr;
bman.players_nr = 0;
/* draw Player names */
if (GT_MP_PTP) {
for (x = 0, j = 0, i = 0; i < MAX_PLAYERS; i++)
if ((bman.players[i].state & PSFM_used) != 0) {
if (bman.players[i].gfx_nr != -1 && PS_IS_used (bman.players[i].state)) {
src.x = 3 * bman.players[i].gfx->smal_size.x;
src.y = 0;
src.w = dest.w = bman.players[i].gfx->smal_size.x;
src.h = dest.h = bman.players[i].gfx->smal_size.y;
dest.x = x;
dest.y = j - 4;
SDL_BlitSurface (bman.players[i].gfx->smal_image, &src, gfx.screen, &dest);
}
sprintf (scrtext, "%10s:%2d", bman.players[i].name, bman.players[i].points);
if ((bman.players[i].state & PSFM_alife) != PSFM_alife) { // Player is dead
draw_text (x, j, scrtext, 0);
if ((bman.players[i].state & PSF_used) != PSF_used)
draw_text (x, j, "-------------", 1);
}
else { // players is alife
draw_text (x, j, scrtext, 1);
bman.players_nr++;
}
x = x + 170;
if (x >= gfx.res.x - (120 + 170)) {
x = 0;
j = j + 14;
}
}
}
x = gfx.res.x - 120;
sprintf (text, "Bombs: %2d", bman.players[bman.p_nr].bombs_n);
draw_text (x, 0, text, 1);
sprintf (text, "Range: %2d", bman.players[bman.p_nr].range);
draw_text (x, 16, text, 1);
sprintf (text, "Speed: %2d", bman.players[bman.p_nr].speed);
draw_text (x, 32, text, 1);
if (bman.state == GS_ready && GT_MP_PTPM)
draw_text (100, 32, "Press F4 to start the game", 1);
else if (bman.state == GS_ready)
draw_text (100, 32, "Waiting for the Server to Start", 1);
gfx_AddUpdateRect (100, 32, gfx.res.x - 100, 16);
redraw_logo (0, gfx.res.y - gfx.font.size.y, gfx.res.x, gfx.res.y);
for (x = 0; x < bman.fieldsize.x; x++)
draw_stone (x, bman.fieldsize.y-1);
sprintf (text, "Net Option: [");
for (i = 0 ; i < MAX_PLAYERS; i++)
sprintf (text, "%s%3d ", text, bman.players[i].net.pkgopt.send_set);
text[strlen(text)+1] = 0;
text[strlen(text)] = ']';
draw_text (0, gfx.res.y - gfx.font.size.y, text, 1);
gfx_AddUpdateRect (0, gfx.res.y - gfx.font.size.y, gfx.res.x, gfx.font.size.y);
if (chat.visible == 0) {
SDL_Flip (gfx.screen);
chat_show (4, 3*16, gfx.res.x - 4, gfx.offset.y);
}
};
void
game_loop ()
{
SDL_Event event;
Uint8 *keys;
int done = 0;
Uint32 timeloop1;
int gameovertimeout = TIME_FACTOR * 5; // gameovertimeout
unsigned char key_bomb = 0; // last state of the bomb key
draw_logo ();
draw_field ();
if (GT_MP_PTP)
net_game_fillsockaddr ();
SDL_Flip (gfx.screen);
timestamp = SDL_GetTicks (); // needed for time sync.
d_gamedetail ("GAME START");
while (!done && (bman.state == GS_running || bman.state == GS_ready)) {
if (SDL_PollEvent (&event) != 0)
switch (event.type) {
case (SDL_QUIT):
done = 1;
bman.state = GS_quit;
}
/* keyboard handling */
keys = SDL_GetKeyState (NULL);
/* only do movements if we're alife and GS_running */
if ((bman.players[bman.p_nr].state & PSFM_alife) == PSFM_alife && bman.state == GS_running) {
if (keys[SDLK_UP]) {
bman.players[bman.p_nr].d = up;
bman.players[bman.p_nr].m = 1;
}
if (keys[SDLK_DOWN]) {
bman.players[bman.p_nr].d = down;
bman.players[bman.p_nr].m = 1;
}
if (keys[SDLK_RIGHT]) {
bman.players[bman.p_nr].d = right;
bman.players[bman.p_nr].m = 1;
}
if (keys[SDLK_LEFT]) {
bman.players[bman.p_nr].d = left;
bman.players[bman.p_nr].m = 1;
}
if (keys[SDLK_LCTRL] || keys[SDLK_RCTRL]) {
if (key_bomb == 0)
player_drop_bomb ();
key_bomb = 1;
}
else
key_bomb = 0;
if (keys[SDLK_LSHIFT] || keys[SDLK_RSHIFT]) {
d_printf ("not in use yet\n");
}
}
else if (GT_MP_PTPM && keys[SDLK_F4] && event.type == SDL_KEYDOWN) {
/* Server is starting the game */
bman.state = GS_running;
net_send_servermode ();
}
if (event.key.keysym.sym == SDLK_ESCAPE && event.type == SDL_KEYDOWN) {
bman.state = GS_startup;
done = 1;
}
chat_loop (&event);
restore_players_screen ();
restore_bomb_screen ();
player_ilness_loop ();
if ((bman.players[bman.p_nr].state & PSFM_alife) == PSFM_alife)
move_player ();
player_calcpos ();
dead_playerani (); /* we need it to draw dead players */
if (bman.gametype != GT_single)
network_loop ();
else
single_loop ();
/* this will even set the variable "bman.player_nr"
to let us know how much Players are still left */
game_draw_info ();
bomb_loop ();
draw_players ();
gfx_UpdateRects ();
/* check if there is only one player left and the game is in multiplayer mode
and if there the last dieing animation is done */
if ((GT_MP_PTPM) && bman.players_nr < 2)
gameovertimeout--;
/* check if we died and we are in single mode and the animation is done */
if (bman.gametype == GT_single && !PS_IS_alife(bman.players[bman.p_nr].state))
gameovertimeout--;
if (gameovertimeout <= 0) {
d_printf ("GAME: Game Over 'Cause only one or noone anymore alife\n");
done = 1;
}
// calculate time sync.
timeloop1 = SDL_GetTicks ();
while (timeloop1 - timestamp >= 0 && timeloop1 - timestamp < 20) {
s_delay (timeloop1 - timestamp - 1);
timeloop1 = SDL_GetTicks ();
}
timestamp = timeloop1;
}
chat_show (-1, -1, -1, -1);
d_gamedetail ("GAME END");
d_printf ("done = %d\n", done);
};
void game_set_playerposition () {
int p, dist, i,j , mx, my, dx, dy;
p = 50;
dist = 8;
while (p == 50) {
p = 0;
dist--;
for (i = 0; (p < 50 && i < MAX_PLAYERS);) {
bman.players[i].pos.x = 2 * (s_random ((bman.fieldsize.x - 1) / 2)) + 1;
bman.players[i].pos.y = 2 * (s_random ((bman.fieldsize.y - 1) / 2)) + 1;
mx = my = 100;
for (j = 0; j <= i; j++) { /* search smalest distance */
dy = bman.players[i].pos.y - bman.players[j].pos.y;
dx = bman.players[i].pos.x - bman.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++;
}
}
};
/* check which player won */
void
game_end ()
{
int i;
/* count the points */
for (i = 0; i < MAX_PLAYERS; i++)
if (PS_IS_used (bman.players[i].state)) {
if (PS_IS_alife (bman.players[i].state)) {
bman.lastwinner = i;
bman.players[i].wins++;
bman.players[i].points += bman.players_nr_s;
}
}
/* check which player is now free ,i.e. disconnected during the game and was playing */
for (i = 0; i < MAX_PLAYERS; i++)
if ((bman.players[i].state & PSF_used ) == 0)
bman.players[i].state = 0;
}