void game_showresultnormal (int pos_x, int pos_y, int pos_w, int pos_h) { char text[255]; int i, p, x, y, pl_cnt = 0, pl_x, pl_y, // player in a row/col dx, dy, // distance sx, sy, px; // start view and position SDL_Rect dest, src; _player *pl[MAX_PLAYERS]; /* Sort the playerlist */ for (p = 0, pl_cnt = 0; p < MAX_PLAYERS; p++) if (PS_IS_used (players[p].state)) { // Set isplayer statistics for futur display players[p].gamestats.isaplayer = 1; // Sort player pl[pl_cnt] = &players[p]; i = pl_cnt; while (i > 0 && (pl[i - 1]->points < players[p].points || (pl[i - 1]->points == players[p].points && pl[i - 1]->wins < players[p].wins))) { pl[i] = pl[i - 1]; i--; pl[i] = &players[p]; } pl_cnt++; } if (pl_cnt == 0) { /* we still haven't joined the game */ } /* calc the best view and start point */ pl_x = 0; do { pl_x++; pl_y = ceil ((float) (((float) pl_cnt) / ((float) pl_x))); if (pl_y == 0) pl_y++; dy = pos_h / pl_y; } while (dy < SHOWRESULT_HEIGHT); dx = pos_w / pl_x; x = sx = (dx - SHOWRESULT_WIDTH) / 2; y = sy = (dy - SHOWRESULT_HEIGHT) / 2; px = 0; d_printf ("game_showresultnormal: pl_x:%d, pl_y:%d, dx:%d, dy:%d\n", pl_x, pl_y, dx, dy); /* draw the playerlist */ for (i = 1, p = 0; p < pl_cnt; p++) { if (PS_IS_used (pl[p]->state)) { if (PS_IS_alife (pl[p]->state)) { font_gfxdrawbold (10 + pos_x + x + GFX_MENUPLAYERIMGSIZE_X + 8, pos_y + y - 10, pl[p]->name, 0, COLOR_brown, 1, 1); font_gfxdraw (10 + pos_x + x + GFX_MENUPLAYERIMGSIZE_X + 8, pos_y + y - 10, pl[p]->name, 0, COLOR_yellow, 1); } else font_gfxdraw (10 + pos_x + x + GFX_MENUPLAYERIMGSIZE_X, pos_y + y - 10, pl[p]->name, 0, COLOR_gray, 1); sprintf (text, "%3d (%2d)", pl[p]->points, pl[p]->wins); font_gfxdraw (10 + pos_x + x + GFX_MENUPLAYERIMGSIZE_X, pos_y + y + 6, text, 0, 0, 1); if (pl[p]->gfx != NULL) { dest.x = pos_x + x; dest.y = pos_y + y - 16; src.w = dest.w = pl[p]->gfx->menu_image->w; src.h = dest.h = pl[p]->gfx->menu_image->h; src.x = 0; src.y = 0; gfx_blit (pl[p]->gfx->menu_image, &src, gfx.screen, &dest, 1); } else { dest.x = pos_x + x; dest.y = pos_y + y - 16; src.w = dest.w = gfx.ghost->w; src.h = dest.h = gfx.ghost->h; src.x = 0; src.y = 0; gfx_blit (gfx.ghost, &src, gfx.screen, &dest, 1); } /* setup the new position */ y += (dy / pl_x); x += dx; px++; if (px >= pl_x) { px = 0; x = sx; } } } }
/* check which player won and free all unnneded data */ void game_end () { int i; int cnt_left = 0; gfx_free_players (); tileset_free (); fire_clear (); snd_music_stop (); snd_free (); /* count the wins for the player, and if only one player * left count the points too */ cnt_left = 0; for (i = 0; i < MAX_PLAYERS; i++) { // Update player statistics players[i].gamestats.killed += players[i].nbrKilled; if (PS_IS_used (players[i].state)) { if (PS_IS_alife (players[i].state)) { bman.lastwinner = i; cnt_left++; if ( GT_MP_PTPM ) players[i].wins++; } } } if (cnt_left == 1 && GT_MP_PTPM ) { players[bman.lastwinner].points += 1; // Bonus for victory players[bman.lastwinner].points += players[bman.lastwinner].nbrKilled; } else bman.lastwinner = -1; /* check which team was alife */ if (bman.gametype == GT_team) { int t_nr; bman.lastwinner = -1; cnt_left = 0; for (t_nr = 0; t_nr < MAX_TEAMS; t_nr++) for (i = 0; i < MAX_PLAYERS; i++) { if (teams[t_nr].players[i] != NULL) if (PS_IS_alife (teams[t_nr].players[i]->state)) { if (bman.lastwinner != t_nr) { teams[t_nr].wins++; cnt_left++; bman.lastwinner = t_nr; } } } if (cnt_left == 1) { /* set the points */ cnt_left = 0; for (t_nr = 0; t_nr < MAX_TEAMS; t_nr++) { for (i = 0; (i < MAX_PLAYERS && teams[t_nr].players[i] != NULL); i++); if (i < MAX_PLAYERS && teams[t_nr].players[i] != NULL) cnt_left++; } teams[bman.lastwinner].points += cnt_left; } else bman.lastwinner = -1; } if (GT_SP) game_showresult (); /* check which player is now free,i.e. disconnected during the game and was playing */ for (i = 0; i < MAX_PLAYERS; i++) if ((players[i].state & PSF_used) == 0) players[i].state = 0; }
void game_draw_info () { int i, x, j, col; char text[255]; char scrtext[255]; SDL_Rect src, dest; if (GT_MP && (chat.oldscreen == NULL || chat.window.x != 4 || chat.window.y != 4.5 * 16)) { chat_show (4, 4.5 * 16, gfx.res.x - 8, gfx.offset.y - 4.5 * 16); chat_setactive (0, 0); } if (bman.updatestatusbar) { redraw_logo (0, 0, gfx.res.x, (4.5 * 16)); dest.x = dest.y = 0; dest.h = 4.5 * 16; dest.w = gfx.res.x; gfx_blitupdaterectadd (&dest); /* In Multiplayer mode draw Player names and count the players who are still alife. */ for (x = 0, j = 0, i = 0; i < MAX_PLAYERS; i++) if ((players[i].state & PSFM_used) != 0) { if (players[i].gfx_nr != -1 && PS_IS_used (players[i].state)) { src.x = 0; src.y = 0; src.w = dest.w = players[i].gfx->small_image->w; src.h = dest.h = players[i].gfx->small_image->h; dest.x = x; dest.y = j - 4; SDL_BlitSurface (players[i].gfx->small_image, &src, gfx.screen, &dest); } sprintf (scrtext, "%10s:%d %1d %1d", players[i].name, players[i].wins, players[i].points, players[i].nbrKilled); if (!PS_IS_alife (players[i].state)) { // Player is dead if ((players[i].state & PSF_used) != PSF_used) col = 4; else col = 3; } else { // player is alife if (bman.gametype == GT_team) col = teams[players[i].team_nr].col; else col = 0; } font_draw (x, j, scrtext, 0, col); x = x + 180; if (x >= gfx.res.x - (120 + 170)) { x = 0; j = j + 1.5 * font[0].size.x; } } x = gfx.res.x - 120; sprintf (text, "Bombs: %2d", players[bman.p_nr].bombs_n); font_draw (x, 0, text, 0, 0); sprintf (text, "Range: %2d", players[bman.p_nr].range); font_draw (x, 16, text, 0, 0); sprintf (text, "Speed: %1.1f", players[bman.p_nr].speed * 10); font_draw (x, 32, text, 0, 0); if (players[bman.p_nr].special.type != 0) { col = players[bman.p_nr].special.type + FT_sp_trigger - 1; dest.x = x - 32; dest.y = 16; dest.w = gfx.menu_field[col]->w; dest.h = gfx.menu_field[col]->h; SDL_BlitSurface (gfx.menu_field[col], NULL, gfx.screen, &dest); } if (bman.state == GS_ready && GT_MP_PTPM) font_gfxdraw (100, 32, "Press F4 to start the game", 0, COLOR_yellow, 0xFFFF); else if (bman.state == GS_ready) font_gfxdraw (100, 32, "Waiting for the Server to Start", 0, COLOR_yellow, 0xFFFF); } /* draw the warning part */ if (map.state != MS_normal) { hurrywarn_to -= timediff; if (bman.updatestatusbar || hurrywarn_to <= 0.0 || hurrywarn_to > HURRYWARN_TO_BLINKING) { hurrywarn_to = HURRYWARN_TO_BLINKING; hurrywarn_state = !hurrywarn_state; if (hurrywarn_state) { font_drawbold ((gfx.res.x - strlen ("HURRY HURRY") * font[1].size.x) / 2, 40, "HURRY HURRY", 1, 0, 2); font_draw ((gfx.res.x - strlen ("HURRY HURRY") * font[1].size.x) / 2, 40, "HURRY HURRY", 1, 1); } else { font_drawbold ((gfx.res.x - strlen ("HURRY HURRY") * font[1].size.x) / 2, 40, "HURRY HURRY", 1, 1, 2); font_draw ((gfx.res.x - strlen ("HURRY HURRY") * font[1].size.x) / 2, 40, "HURRY HURRY", 1, 0); } dest.x = dest.y = 0; dest.h = 4.5 * 16; dest.w = gfx.res.x; gfx_blitupdaterectadd (&dest); } } if (debug) debug_ingameinfo (); bman.updatestatusbar = 0; };
int game_check_endgame () { int res = 0; static float loop; loop -= timediff; if (loop > 0.0f && loop < ENDGAME_CHECK_AGAIN) return 0; loop = ENDGAME_CHECK_AGAIN; if (bman.gametype == GT_team) { /* * Team Mode Calculation */ int t_nr; // teamnumber int p_nr; // playernumber int h_team = 0; // how many human teams are alife int ateam = 0; // teams which are alife int h_team_last = -1; // last human team which was alife int team_last = -1; // last teams which was alift _player *p; for (t_nr = 0; t_nr < MAX_TEAMS; t_nr++) for (p_nr = 0; p_nr < MAX_PLAYERS; p_nr++) if (teams[t_nr].players[p_nr] != NULL) { p = teams[t_nr].players[p_nr]; if (PS_IS_used (p->state) && PS_IS_alife (p->state)) { if (team_last != t_nr) { team_last = t_nr; ateam++; } if ((!PS_IS_aiplayer (p->state)) && h_team_last != t_nr) { h_team++; h_team_last = t_nr; } } } if (h_team < 1 || ateam < 2) res = 1; } else if ((bman.gametype == GT_bomberman) || (map.state != MS_normal && bman.gametype == GT_deathmatch)) { int p_nr; // playernumber int h_alife = 0; // human players who are alife int alife = 0; // ai players who are alife _player *p; for (p = &players[0], p_nr = 0; p_nr < MAX_PLAYERS; p_nr++, p++) { if (PS_IS_used (p->state) && PS_IS_alife (p->state)) { alife++; if (!PS_IS_aiplayer (p->state)) h_alife++; } } if ((h_alife < 1) || (alife < 2)) res = 1; } return res; };
/* single player loop for calculating the ai players */ void single_loop () { int p; _player *pl; _point plpos; int nearbomb = 0, bestbdir, i; _airunaway rawdir; if (GT_MP_PTPS) // we are not the master so no need for this. return; for (p = 0; p < MAX_PLAYERS; p++) if (p != bman.p_nr && PS_IS_aiplayer (players[p].state)) { if (PS_IS_alife (players[p].state)) { pl = &players[p]; i = ai_checkpos (pl, &plpos); if (!i) /* we're still moving */ pl->m = 1; else { nearbomb = ai_findnearbombs (plpos); if (nearbomb == 0) { // no bombs found bestbdir = ai_findbestbombdir (plpos, pl->d, pl->range); if (bestbdir & DIRM_under) { if (ai_easyrunaway (plpos, pl->range) != 0) player_drop_bomb (p); } else if (bestbdir == 0) { pl->d = s_random (4); pl->m = 1; } else { pl->d = ai_choosedir (bestbdir, 0, pl->d); pl->m = 1; } if (!ai_checknewpos (plpos, pl->d)) pl->m = 0; } else { // bombs in the near found rawdir = ai_runawayfrom (plpos, nearbomb, pl->range, 0); if (rawdir.dir != 0 && rawdir.bestdir == -1) { pl->d = ai_choosedir (rawdir.dir, nearbomb, pl->d); // we have to make a choice.. do it pl->m = 1; } else if (rawdir.bestdir != -1) { pl->d = rawdir.bestdir; pl->m = 1; } else if (rawdir.bestdir == -1 && rawdir.dir == 0) { /* no good ways found, just run in the opposite direction of the bomb */ if (map.field[(int) pl->pos.x][(int) pl->pos.y].type == FT_nothing || map.field[(int) pl->pos.x][(int) pl->pos.y].type >= FT_tunnel) pl->m = 1; } } if (pl->m == 0 && map.field[(int) pl->pos.x][(int) pl->pos.y].type == FT_tunnel) pl->m = 1; } player_ilness_loop (p); player_move (p); } else player_checkdeath (p); } };