/* send an update about the game to all clients */ void send_ogc_update () { int i, j; char status[10]; if (!bman.notifygamemaster || GT_MP_PTPS) return; for (j = 0, i = 0; i < bman.maxplayer; i++) if (PS_IS_used (players[i].state)) j++; switch (bman.state) { case (GS_running): sprintf (status, "running"); break; case (GS_ready): sprintf (status, "ready"); break; case (GS_wait): sprintf (status, "wait"); break; case (GS_update): sprintf (status, "update"); break; default: sprintf (status, "error"); break; } ogc_sendgamestatus (bman.sock, "BomberClone", VERSION, bman.gamename, j, bman.maxplayer, status); };
/* start a single player game and prepare everything for the game */ void single_game_new () { int p; bman.players_nr_s = 1; bman.players_nr = 1; // set players variables, only the variables which depend on single games for (p = 0; p < MAX_PLAYERS; p++) { if (PS_IS_used (players[p].state)) { bman.players_nr_s++; bman.players_nr++; players[p].state |= PSF_used + PSF_alife + PSF_playing; } else players[p].state = 0; } players[bman.p_nr].state = PSFM_alife; player_set_gfx (&players[bman.p_nr], players[bman.p_nr].gfx_nr); bman.last_ex_nr = 1; bman.sock = -1; bman.state = GS_ready; };
/* * the ai player will choose diffrent gfx for every * team another gfx, but not one which is selected by * human player. */ void ai_team_choosegfx () { struct _team_tmpdata_ { int ai_gfx; } teamdat[MAX_TEAMS]; int tm_nr; int pl_nr; int i, used; _player *pl; /* find a ai player gfx for every team */ for (i = 0, tm_nr = 0; (i < gfx.player_gfx_count && tm_nr < MAX_TEAMS); i++) { used = 0; for (pl_nr = 0; pl_nr < MAX_PLAYERS; pl_nr++) { if ((!PS_IS_aiplayer(players[pl_nr].state)) && (PS_IS_used (players[pl_nr].state)) && i == players[pl_nr].gfx_nr) used = 1; } if (!used && tm_nr < MAX_TEAMS) { teamdat[tm_nr].ai_gfx = i; tm_nr++; } } /* * give all ai players in the teams the right gfx */ for (tm_nr = 0; tm_nr < MAX_TEAMS; tm_nr++) for (pl_nr = 0; pl_nr < MAX_PLAYERS; pl_nr++) { pl = teams[tm_nr].players[pl_nr]; if (pl) { if (PS_IS_used(pl->state) && PS_IS_aiplayer(pl->state)) player_set_gfx (pl, teamdat[tm_nr].ai_gfx); } } };
/* i am just too lazy to write this all again and again */ void map_set_playerposition (int usermap) { int pl; d_printf ("map_set_playerposition\n"); /* This is the new code that will set every player in a starting point * It should never fail, but if it does, it will fall through to the old method */ for (pl = 0; pl < MAX_PLAYERS; pl++) { if (PS_IS_used(players[pl].state)) { map_place_player(pl); } } }
/* this routine will set up some things for the network game after this the data should be transfered to the other clients. */ void net_new_game () { int p; /* set all multiplayer depending datas */ bman.players_nr = 0; bman.players_nr_s = 0; for (p = 0; p < MAX_PLAYERS; p++) { if (PS_IS_used (players[p].state)) bman.players_nr_s++; else players[p].state = 0; } if (bman.p_nr != -1) players[bman.p_nr].state &= (0xFF - PSF_net); // we are the local player bman.last_ex_nr = 1; };
/* create a giving number of ai players */ int single_create_ai (int num_players) { int p, count, try, gfx_sel, i = 0; _player *pl = NULL; for (count = 0; count < num_players; count++) { /* find free players */ for (pl = NULL, p = 0; (pl == NULL && p < MAX_PLAYERS);p++) if (p < MAX_PLAYERS && !(PS_IS_used (players[p].state))) { pl = &players[p]; sprintf (pl->name, "AI %d", p + 1); pl->state |= PSF_used + PSF_alife + PSF_playing + PSF_ai; pl->net.flags = NETF_firewall; sprintf (pl->net.addr.host, "localhost"); sprintf (pl->net.addr.port, "11000"); try = 0; do { gfx_sel = s_random (gfx.player_gfx_count); MW_IS_GFX_SELECT (gfx_sel, i); try++; } while (try < 100 && i != -1); pl->wins = 0; pl->points = 0; pl->team_nr = -1; player_set_gfx (pl, gfx_sel); team_choose (pl); } if (pl == NULL) { d_printf ("single_create_ai: No free Player found.\n"); return -1; } else d_printf ("single_create_ai: Player %d Created Name:%s\n", pl - players, pl->name); } if (pl != NULL) return pl - players; return -1; };
/* shutdown the network part */ void network_shutdown () { int i; int new_server = bman.p_servnr; d_printf ("network_shutdown\n"); if (GT_MP_PTPM) { d_printf ("Server Quit Send information\n"); /* find new server */ for (i = 0; i < MAX_PLAYERS; i++) { if (PS_IS_used (players[i].state) && PS_IS_netplayer (players[i].state) && i != bman.p_servnr && players[i].net.flags == 0) new_server = i; } d_printf ("netword_shutdown: new server set to: %d\n", new_server); for (i = 0; i < MAX_PLAYERS; i++) if (i != bman.p_servnr && PS_IS_netplayer (players[i].state) && !PS_IS_aiplayer (players[i].state)) send_quit (&players[i].net.addr, bman.p_servnr, new_server); } else if (players[bman.p_servnr].net.addr.host[0] != 0) { send_quit (&players[bman.p_servnr].net.addr, bman.p_nr, bman.p_servnr); if (IS_LPLAYER2) send_quit (&players[bman.p_servnr].net.addr, bman.p2_nr, bman.p_servnr); } if (bman.notifygamemaster) { ogc_sendgamequit (bman.sock); ogc_shutdown (); } udp_close (bman.sock); bman.p_nr = -1; bman.sock = -1; #ifdef _WIN32 WSACleanup (); #endif };
/* * send the information about the deleted player to all clients */ void net_game_send_delplayer (int pl_nr) { int i; int new_server = bman.p_servnr; d_printf ("net_game_send_delplayer (%d)\n", pl_nr); if (GT_MP_PTPM && (GS_WAITRUNNING || bman.state == GS_update)) { /* find new server, if needed */ if (pl_nr == bman.p_servnr) { for (i = 0; i < MAX_PLAYERS; i++) { if (PS_IS_used (players[i].state) && PS_IS_netplayer (players[i].state) && i != bman.p_servnr && players[i].net.flags == 0) new_server = i; } d_printf ("new_game_send_delplayer: new server set to: %d\n", new_server); } for (i = 0; i < MAX_PLAYERS; i++) if (NET_CANSEND (i) && i != bman.p_nr) send_quit (&players[i].net.addr, pl_nr, new_server); bman.updatestatusbar = 1; } /* we have to send that one if our own players quit */ else if (pl_nr == bman.p_nr || pl_nr == bman.p2_nr) { send_quit (&players[bman.p_servnr].net.addr, pl_nr, -1); } inpkg_delplayer (pl_nr); if (GT_MP_PTPM) { if (bman.notifygamemaster) send_ogc_update (); if (new_server >= 0 && new_server < MAX_PLAYERS) bman.p_servnr = new_server; } };
// loads or generate an map void map_new (char *filename) { int x, y; FILE *fmap; signed char old_maptype = map.type; int pl_cnt, pl; /* initialize the start_point array in the _map struct */ map_init_start_points(); if (filename) { fmap = fopen (filename, "r"); /* if we can't open the given filename for any reason, reverting to default value else, load the file map */ if (fmap) map_load (fmap); } else fmap = NULL; // Clean and create the field // if (fmap == NULL) map_genrandom (); /* Generate a More random map if requested */ if (map.map_selection == MAPS_morerand) map_genmorerandom(); if (map.type == -1) map.type = s_random (MAPT_max); if (map.type == MAPT_tunnel) { /* insert tunnels */ for (x = 0; x < GAME_MAX_TUNNELS; x++) map.tunnel[x].x = map.tunnel[x].y = -1; map.field[3][3].type = FT_tunnel; map.field[3][3].special = 0; map.field[map.size.x - 4][map.size.y - 4].type = FT_tunnel; map.field[map.size.x - 4][map.size.y - 4].special = 1; if (map.size.y > 12) { map.field[map.size.x - 4][3].type = FT_tunnel; map.field[map.size.x - 4][3].special = 2; map.field[3][map.size.y - 4].type = FT_tunnel; map.field[3][map.size.y - 4].special = 3; map.tunnel[0].x = map.size.x - 4; map.tunnel[0].y = 3; map.tunnel[1].x = 3; map.tunnel[1].y = map.size.y - 4; map.tunnel[2].x = map.size.x - 4; map.tunnel[2].y = map.size.y - 4; map.tunnel[3].x = 3; map.tunnel[3].y = 3; } else { map.tunnel[0].x = map.size.x - 4; map.tunnel[0].y = map.size.y - 4; map.tunnel[1].x = 3; map.tunnel[1].y = 3; } } /* delete the bfield data */ for (x = 0; x < MAX_FIELDSIZE_X; x++) for (y = 0; y < MAX_FIELDSIZE_Y; y++) map.bfield[x][y] = 0; /* count the number of players on this map so we know how many starting points * to find */ pl_cnt = 0; for (pl = 0; pl < MAX_PLAYERS; pl++) { if (PS_IS_used (players[pl].state)) { pl_cnt++; } } /* identify possible starting positions for players and store them in the * start_point array in the _map struct. This will always succeed. If * it cannot find starting points within the tolerance, it first attempts * to create start points within the tolerence and otherwise lowers the * tolerence until it can satisfy the proper number of start points. * eventually the tolerence reaches 0, so it can, in the worst case, start * all players at the same start point. */ map_find_and_add_start_points(pl_cnt - map_num_defined_start_points(), MAP_POSITION_TOLERENCE); /* Set the Playerinformation */ map_set_playerposition (fmap != NULL); /* put the fire powerups in the field */ map_fillitems (FT_fire, map.fire); /* put the bomb powerups in the field */ map_fillitems (FT_bomb, map.bombs); /* put the shoe powerup in the field */ map_fillitems (FT_shoe, map.shoes); /* put the death ?powerups? in the field */ map_fillitems (FT_death, map.death); /* put the mixed powerrup in the field */ map_fillitems (FT_mixed, map.mixed); /* put the trigger special in the field */ map_fillitems (FT_sp_trigger, map.sp_trigger); /* put the row special in the field */ map_fillitems (FT_sp_row, map.sp_row); /* put the push special in the field */ map_fillitems (FT_sp_push, map.sp_push); map_fillitems (FT_sp_liquid, map.sp_push); map_fillitems (FT_sp_moved, map.sp_push); /* put the push special in the field */ map_fillitems(FT_sp_kick,map.sp_kick); map.type = old_maptype; }
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; } } } }
void game_showresultteam (int pos_x, int pos_y, int pos_w, int pos_h) { int i, t_nr, p_nr; // counter for teams and players struct { _team *team; // pointer to the team _player *pl[MAX_PLAYERS]; // players in the team (sorted) int cnt; } tdata[MAX_TEAMS]; // hold some team informations (sorted) int t_count = 0, p_maxcount = 0, p_sumcount = 0; int sx, sy, p_y, p_x, dx, dy, col, x = 0; SDL_Rect dest, src; char text[255]; /* sort all teams */ for (t_nr = 0; t_nr < MAX_TEAMS; t_nr++) { tdata[t_nr].team = NULL; tdata[t_nr].cnt = 0; } for (t_nr = 0; t_nr < MAX_TEAMS; t_nr++) { for (p_nr = 0; (p_nr < MAX_PLAYERS && teams[t_nr].players[p_nr] == NULL); p_nr++); if (p_nr < MAX_PLAYERS && teams[t_nr].players[p_nr] != NULL) { tdata[t_count].team = &teams[t_nr]; i = t_count; while (i > 0 && (tdata[i - 1].team->wins < teams[t_nr].wins || (tdata[i - 1].team->wins == teams[t_nr].wins && tdata[i - 1].team->points < teams[t_nr].points))) { tdata[i].team = tdata[i - 1].team; i--; tdata[i].team = &teams[t_nr]; } t_count++; } } /* sort all players dependsing on the number of wins they have */ for (t_nr = 0; t_nr < t_count; t_nr++) for (p_nr = 0, tdata[t_nr].cnt = 0; p_nr < MAX_PLAYERS; p_nr++) { if (t_nr < t_count) { if (tdata[t_nr].team->players[p_nr] != NULL && PS_IS_used (tdata[t_nr].team->players[p_nr]->state)) { tdata[t_nr].pl[tdata[t_nr].cnt] = tdata[t_nr].team->players[p_nr]; i = tdata[t_nr].cnt; while (i > 0 && (tdata[t_nr].pl[i - 1]->wins < tdata[t_nr].team->players[p_nr]->wins || (tdata[t_nr].pl[i - 1]->wins == tdata[t_nr].team->players[p_nr]->wins && tdata[t_nr].pl[i - 1]->points < tdata[t_nr].team->players[p_nr]->points))) { tdata[t_nr].pl[i] = tdata[t_nr].pl[i - 1]; i--; tdata[t_nr].pl[i] = tdata[t_nr].team->players[p_nr]; } tdata[t_nr].cnt++; } } } /* check the max number of players in one team and number of all players */ for (t_nr = 0, p_maxcount = 0; t_nr < t_count; t_nr++) /* t_count + 1 */ if (p_maxcount < tdata[t_nr].cnt) p_maxcount = tdata[t_nr].cnt; for (p_sumcount = 0, p_nr = 0; p_nr < MAX_PLAYERS; p_nr++) if (PS_IS_used (players[p_nr].state)) p_sumcount++; /* calculate the best view */ p_x = dx = dy = 0; do { p_x++; p_y = 0; // calc. again for this setting for (t_nr = 0; t_nr < t_count; t_nr++) { p_y += ceil ((float) (((float) tdata[t_nr].cnt) / ((float) p_x))); } if (p_y == 0) p_y = 1; dy = (pos_h - (SHOWRESULT_TEAMHEAD * t_count)) / p_y; } while (dy < SHOWRESULT_TEAMPLAYER); if (dy > 2 * SHOWRESULT_TEAMPLAYER) dy = 2 * SHOWRESULT_TEAMPLAYER; /* draw everything */ sy = (pos_h - (SHOWRESULT_TEAMHEAD * t_count + dy * p_y)) / 2; for (t_nr = 0; t_nr < t_count; t_nr++) { sprintf (text, "%s Victorys %d (%d)", tdata[t_nr].team->name, tdata[t_nr].team->wins, tdata[t_nr].team->points); sx = (pos_w - strlen (text) * font[0].size.x) / 2; font_gfxdrawbold (10 + pos_x + sx, pos_y + sy + 3, text, 0, COLOR_brown, 1, 1); font_gfxdraw (10 + pos_x + sx, pos_y + sy + 3, text, 0, COLOR_yellow, 2); sy += SHOWRESULT_TEAMHEAD; dx = pos_w / p_x; sx = (dx - SHOWRESULT_TEAMPLAYERWIDTH) / 2; for (col = 0, p_nr = 0; p_nr < tdata[t_nr].cnt; p_nr++) { if (col == 0 || col >= p_x) { if (col >= p_x) sy += dy; col = 0; x = sx; } if (tdata[t_nr].pl[p_nr]->gfx != NULL) { dest.x = pos_x + x; dest.y = pos_y + sy; src.w = dest.w = tdata[t_nr].pl[p_nr]->gfx->small_image->w; src.h = dest.h = tdata[t_nr].pl[p_nr]->gfx->small_image->h; src.x = 0; src.y = 0; gfx_blit (tdata[t_nr].pl[p_nr]->gfx->small_image, &src, gfx.screen, &dest, 1); } else { dest.x = pos_x + x; dest.y = pos_y + sy; src.w = dest.w = gfx.ghost_small->w; src.h = dest.h = gfx.ghost_small->h; src.x = 0; src.y = 0; gfx_blit (gfx.ghost_small, &src, gfx.screen, &dest, 1); } sprintf (text, "%s(%d/%d)", tdata[t_nr].pl[p_nr]->name, tdata[t_nr].pl[p_nr]->wins, tdata[t_nr].pl[p_nr]->points); font_gfxdraw (10 + pos_x + x + GFX_SMALLPLAYERIMGSIZE_X * 2, pos_y + sy + 2, text, 0, 0, 2); x += dx; col++; } sy += dy; } }
/* load the images with the right scaleing */ void game_start () { int p, i; menu_displaytext ("Loading..", "Please Wait"); bman.players_nr_s = 0; bman.playnum += 1; for (p = 0; p < MAX_PLAYERS; p++) { if (PS_IS_used (players[p].state)) { bman.players_nr_s++; if (players[p].gfx_nr == -1) { players[p].gfx = NULL; players[p].state &= (0xff - (PSF_alife + PSF_playing)); } else { players[p].state |= PSF_alife + PSF_playing; players[p].gfx = &gfx.players[players[p].gfx_nr]; } } else players[p].state = 0; players[p].bombs_n = bman.start_bombs; players[p].range = bman.start_range; players[p].speed = bman.start_speed; players[p].collect_shoes = 0; players[p].special.type = SP_nothing; players[p].special.use = 0; players[p].special.clear = 0; players[p].m = 0; players[p].old.x = 0; players[p].old.y = 0; bman.updatestatusbar = 1; players[p].frame = 0.0f; players[p].d = 0; players[p].pos.x = 0.0; players[p].pos.y = 0.0; players[p].tunnelto = 0.0f; players[p].ready = 0; // add reset nbrKilled value players[p].nbrKilled = 0; /* all types of illnes turn them off */ for (i = 0; i < PI_max; i++) players[p].ill[i].to = 0.0f; // reset bombs for (i = 0; i < MAX_BOMBS; i++) { players[p].bombs[i].state = BS_off; players[p].bombs[i].ex_nr = -1; players[p].bombs[i].fdata = 0; players[p].bombs[i].dest.x = 0; players[p].bombs[i].dest.y = 0; players[p].bombs[i].mode = BM_normal; players[p].bombs[i].id.p = p; players[p].bombs[i].id.pIgnition = p; players[p].bombs[i].id.b = i; players[p].pos.x = 0; players[p].pos.x = 0; } } flitems_reset (); init_map_tileset (); tileset_load (map.tileset, -1, -1); gfx_load_players (gfx.block.x, gfx.block.y); snd_load (map.tileset); snd_music_start (); map.state = MS_normal; bman.timeout = bman.init_timeout; s_calctimesync (); // to clean up the timesyc s_calctimesync (); // data run this twice if (GT_MP_PTPM) net_send_servermode (); };
/* 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; }
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; };
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; };
/* this is needed to draw the whole uppdate of everything */ void draw_netupdatestate (char st) { char text[255]; unsigned char b; int y = 0, b1, z, zx = 200, i, j, s = map.size.y + MAX_PLAYERS + GAME_MAX_TUNNELS; SDL_Rect src, dest; z = gfx.res.x - zx - 30 - 8; for (i = 0; i < MAX_PLAYERS; i++) if (PS_IS_used (players[i].state)) { y += 50; if (st) { redraw_logo (0, y, gfx.res.x, y + 50); if (players[i].gfx_nr != -1) { dest.w = src.w = players[i].gfx->small_image->w; dest.h = src.h = players[i].gfx->small_image->h; src.x = players[i].gfx->small_image->w * down; src.y = 0; dest.x = 50; dest.y = y; SDL_BlitSurface (players[i].gfx->small_image, &src, gfx.screen, &dest); gfx_blitupdaterectadd (&dest); } dest.x = zx; dest.y = y; dest.w = menulistimages[1][0]->w; dest.h = menulistimages[1][0]->h; gfx_blit (menulistimages[1][0], NULL, gfx.screen, &dest, 10000); dest.x = z + zx + 4; gfx_blit (menulistimages[1][2], NULL, gfx.screen, &dest, 10000); // draw the bottom left and right of the list dest.y = y + 29; gfx_blit (menulistimages[1][8], NULL, gfx.screen, &dest, 10000); dest.x = zx; gfx_blit (menulistimages[1][6], NULL, gfx.screen, &dest, 10000); //top & bottom for (j = 4; j < z + 4; j += 4) { dest.x = j + zx; dest.y = y; gfx_blit (menulistimages[1][1], NULL, gfx.screen, &dest, 10000); dest.y = y + 29; gfx_blit (menulistimages[1][7], NULL, gfx.screen, &dest, 10000); } //left &right for (j = 4; j < 29; j += 4) { dest.x = zx; dest.y = y + j; gfx_blit (menulistimages[1][3], NULL, gfx.screen, &dest, 10000); dest.x = z + zx + 4; gfx_blit (menulistimages[1][5], NULL, gfx.screen, &dest, 10000); } sprintf (text, "%s", players[i].name); font_draw (80, y, text, 0, 4); } // calc percentage, this a range from 0 to 255) switch (players[i].net.net_istep) { case 3: sprintf (text, "Getting Tunnel Data %d.", players[i].net.net_status); b = (players[i].net.net_status + 1) * 255 / s; break; case 2: sprintf (text, "Getting Field Data %d of %d.", players[i].net.net_status, map.size.y); b = (players[i].net.net_status + 1 + GAME_MAX_TUNNELS) * 255 / s; break; case 1: sprintf (text, "Getting Player Data %d of %d.", players[i].net.net_status, MAX_PLAYERS); b = (players[i].net.net_status + 1 + GAME_MAX_TUNNELS + map.size.y) * 255 / s; break; default: sprintf (text, "Ready"); b = 255; break; } //draw bar if (b > 0) { b1 = b * z / 255; dest.x = zx + 4; dest.y = y + 4; dest.w = menubuttonimages[2][0]->w; dest.h = menubuttonimages[2][0]->h; gfx_blit (menubuttonimages[2][0], NULL, gfx.screen, &dest, 10000); dest.x = zx + 4 + b1 - menubuttonimages[1][2]->w; if (dest.x < zx + 4) dest.x = zx + 4; dest.w = menubuttonimages[2][2]->w; dest.h = menubuttonimages[2][2]->h; gfx_blit (menubuttonimages[2][2], NULL, gfx.screen, &dest, 10000); if (b1 > menubuttonimages[2][0]->w + menubuttonimages[2][2]->w) { dest.w = menubuttonimages[2][1]->w; dest.h = menubuttonimages[2][1]->h; for (j = menubuttonimages[2][0]->w; j < b1 - menubuttonimages[2][2]->w; j += menubuttonimages[2][1]->w) { dest.x = j + zx + 4; gfx_blit (menubuttonimages[2][1], NULL, gfx.screen, &dest, 10000); } } } // draw old status in case of debug if (!players[i].net.net_istep) font_draw (80, y + 20, text, 0, 4); else if (debug) { redraw_logo (80, y + 35, gfx.res.x - 80, 15); font_draw (80, y + 35, text, 0, 4); } } gfx_blitdraw (); return; }
/* single player game win/point screen * 1. setup all player data * 2. setup second local player and ai players * 3. setup all other game related data */ void single_playergame (int second_player, int ai_players) { int p, done = 0; bman.p_nr = -1; bman.p2_nr = -1; /* delete player and teams from the game */ for (p = 0; p < MAX_PLAYERS; p++) { players[p].points = 0; players[p].wins = 0; players[p].state = 0; players[p].team_nr = -1; players[p].gfx_nr = -1; players[p].gfx = NULL; memset (&players[p].net, 0x0, sizeof (_net_player)); } for (p = 0; p < MAX_TEAMS; p++) { teams[p].wins = 0; teams[p].points = 0; for (done = 0; done < MAX_PLAYERS; done++) teams[p].players[done] = NULL; } done = 0; for (bman.p_nr = -1, p = 0; (bman.p_nr == -1 && p < MAX_PLAYERS); p++) if (!(PS_IS_used (players[p].state))) bman.p_nr = p; players[bman.p_nr].team_nr = 0; if (bman.p_nr >= MAX_PLAYERS) { printf ("ERROR in function (single_game_new): couldn't find any free player\n"); exit (1); } strncpy (players[bman.p_nr].name, bman.playername, LEN_PLAYERNAME); do { done = playermenu_selgfx (bman.p_nr); } while (players[bman.p_nr].gfx_nr == -1 && done != -1); players[bman.p_nr].state = PSF_used + PSF_alife + PSF_playing; strncpy (players[bman.p_nr].name, bman.playername, LEN_PLAYERNAME); if (done != -1 && second_player) { player2_join (); do { done = playermenu_selgfx (bman.p2_nr); } while (players[bman.p2_nr].gfx_nr == -1 && done != -1); players[bman.p2_nr].team_nr = 0; } if (done == -1) return; single_create_ai (ai_players); if (bman.gametype == GT_team) { playermenu (); team_update (); ai_team_choosegfx (); } bman.state = GS_ready; while (!done && bman.state != GS_quit && bman.state != GS_startup) { single_game_new (); game_start (); bman.state = GS_running; game_loop (); game_end (); } gfx_blitdraw (); draw_logo (); gfx_blitdraw (); };