diff --git a/include/packets.h b/include/packets.h index ae0e4cb..45e0560 100644 --- a/include/packets.h +++ b/include/packets.h @@ -1,4 +1,4 @@ -/* $Id: packets.h,v 1.25 2004/09/12 20:54:24 stpohle Exp $ +/* $Id: packets.h,v 1.26 2004/09/26 22:06:46 stpohle Exp $ * network packets.. */ #ifndef _PACKETS_H_ @@ -167,9 +167,12 @@ struct pkg_playerid { signed char gfx_nr; // number of the graphic signed char state; signed char netflags; // network flags - signed char team_nr; // team number Sint16 points; Sint16 wins; + + signed char team_nr; // team number + Sint16 team_points; // team points + Sint16 team_wins; // team wins }; diff --git a/src/game.c b/src/game.c index dbafbc3..1f93849 100644 --- a/src/game.c +++ b/src/game.c @@ -1,4 +1,4 @@ -/* $Id: game.c,v 1.93 2004/09/26 02:28:06 stpohle Exp $ +/* $Id: game.c,v 1.94 2004/09/26 22:06:57 stpohle Exp $ game.c - procedures for the game. */ #include @@ -305,8 +305,15 @@ game_loop () * check if we only one player left or only ai players are left. * check also if we there is only one team alife */ +#define ENDGAME_CHECK_AGAIN 1.0f 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) { /* @@ -315,21 +322,23 @@ int game_check_endgame () { 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 _player *p; - for (t_nr = 0; t_nr < MAX_TEAMS; t_nr++) - for (p_nr = 0; p_nr < MAX_PLAYERS; p_nr++) { + 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) && (!PS_IS_aiplayer (p->state)) && h_team_last != t_nr) { - h_team++; - h_team_last = t_nr; + if (PS_IS_used (p->state) && PS_IS_alife (p->state)) { + ateam++; + if ((!PS_IS_aiplayer (p->state)) && h_team_last != t_nr) { + h_team++; + h_team_last = t_nr; + } } } - } - if (h_team_last < 1) + if (h_team < 1 || ateam < 2) res = 1; } else if (bman.gametype == GT_bomberman) { @@ -352,29 +361,66 @@ int game_check_endgame () { return res; }; - +#undef ENDGAME_CHECK_AGAIN /* check which player won and free all unnneded data */ void game_end () { int i; - + int cnt_left = 0; + gfx_free_players (); tileset_free (); snd_music_stop (); snd_free (); - /* count the points */ + /* 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++) if (PS_IS_used (players[i].state)) { if (PS_IS_alife (players[i].state)) { bman.lastwinner = i; + cnt_left++; players[i].wins++; - players[i].points += bman.players_nr_s; } } + if (cnt_left == 1) + players[bman.lastwinner].points += bman.players_nr_s; + else bman.lastwinner = -1; + /* check which team was alife */ + if (bman.gametype == GT_team) { + int t_nr; + + 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 (); @@ -462,14 +508,125 @@ game_start () * show the diffrent screens one for players and one for teams */ /* Teamplay */ +#define SHOWRESULT_TEAMHEAD 24 +#define SHOWRESULT_TEAMPLAYER 16 +#define SHOWRESULT_TEAMPLAYERWIDTH 150 static void game_showresultteam () { + 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; + 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 (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++) + 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 = (gfx.res.y - 100 - (SHOWRESULT_TEAMHEAD * t_count)) / p_y; + } while (dy < SHOWRESULT_TEAMPLAYER); + + if (dy > 2*SHOWRESULT_TEAMPLAYER) dy = 2*SHOWRESULT_TEAMPLAYER; + + /* draw everything */ + sy = (gfx.res.y - (SHOWRESULT_TEAMHEAD * t_count + dy * p_y)) / 2; + for (t_nr = 0; t_nr < t_count; t_nr++) { + sx = (gfx.res.y - strlen (tdata[t_nr].team->name) * font[1].size.x) / 2; + sprintf (text, "%s Victorys %d (%d)", tdata[t_nr].team->name, tdata[t_nr].team->wins, tdata[t_nr].team->points); + font_drawbold (sx, sy+3, text, 0, COLOR_brown, 1); + font_draw (sx, sy+3, text, 0, COLOR_yellow); + sy += SHOWRESULT_TEAMHEAD; + dx = (gfx.res.x - 40) / p_x; + sx = 20 + (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; + } + + dest.x = x; + dest.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); + + 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_draw (x + GFX_SMALLPLAYERIMGSIZE_X*2, sy + 2, text, 0, 0); + x += dx; + col++; + } + gfx_blitdraw (); + sy += dy; + } } +#undef SHOWRESULT_TEAMHEAD +#undef SHOWRESULT_TEAMPLAYER +#undef SHOWRESULT_TEAMPLAYERWIDTH +/* Bomberman/Deathmatch Version Play */ #define SHOWRESULT_WIDTH 150 #define SHOWRESULT_HEIGHT 80 -/* Bomberman/Deathmatch Version Play */ static void game_showresultnormal () { char text[255]; int i, p, x, y, pl_cnt = 0, @@ -487,7 +644,9 @@ static void game_showresultnormal () { pl[pl_cnt] = &players[p]; i = pl_cnt; - while (i > 0 && pl[i-1]->wins < players[p].wins) { + while (i > 0 && (pl[i-1]->wins < players[p].wins + || (pl[i-1]->wins == players[p].wins + && pl[i-1]->points < players[p].points))) { pl[i] = pl[i-1]; i--; pl[i] = &players[p]; diff --git a/src/packets.c b/src/packets.c index 097e320..be1e6fb 100644 --- a/src/packets.c +++ b/src/packets.c @@ -222,8 +222,9 @@ send_joingame (_net_addr * addr, char *name, int flags) /*** - *** Packettype: pingack/pingreq - *** Update Playerinformation, add players into the current game + *** Packettype: playerid + *** Update Playerinformation, Teampoints of a Player, Points + *** *** *** if : the pl_nr == -1 send the whole list to the sender *** else: set the new values for this player @@ -283,6 +284,11 @@ do_playerid (struct pkg_playerid *p_id, _net_addr * addr) pl->points = NTOH16 (p_id->points); pl->wins = NTOH16 (p_id->wins); pl->team_nr = p_id->team_nr; + if (pl->team_nr >= 0 && pl->team_nr < MAX_TEAMS) { + teams[pl->team_nr].points = NTOH16(p_id->team_points); + teams[pl->team_nr].wins = NTOH16(p_id->team_wins); + } + team_update (); } /* Send all connected players the new PlayerID */ @@ -335,12 +341,18 @@ send_playerid (_net_addr * addr, char *name, char *pladdr, char *plport, p_id.wins = HTON16 (players[pl_nr].wins); p_id.state = players[pl_nr].state; p_id.team_nr = team_nr; + if (team_nr >= 0 && team_nr < MAX_TEAMS) { + p_id.team_points = teams[team_nr].points; + p_id.team_wins = teams[team_nr].wins; + } } else { p_id.points = 0; p_id.wins = 0; p_id.state = 0; p_id.team_nr = -1; + p_id.team_points = 0; + p_id.team_wins = 0; } send_pkg ((struct pkg *) &p_id, addr); @@ -615,6 +627,7 @@ send_playerdata (_net_addr * addr, int p_nr, _player * pl) p_dat.frame = HTON16 (FTOI16 (pl->frame)); p_dat.p_nr = p_nr; + send_pkg ((struct pkg *) &p_dat, addr); }; @@ -650,6 +663,8 @@ do_playerdata (struct pkg_playerdata *p_dat, _net_addr * addr) pl->range = p_dat->range; pl->frame = I16TOF (NTOH16 (p_dat->frame)); pl->state = p_dat->state; + pl->team_nr = p_dat->team_nr; + team_update (); } if (p_dat->dead_by < 0 || p_dat->dead_by >= MAX_PLAYERS) /* set player state no matter what */ @@ -660,6 +675,8 @@ do_playerdata (struct pkg_playerdata *p_dat, _net_addr * addr) /* player just died */ if (p_dat->p_nr != p_dat->dead_by) { players[p_dat->dead_by].points++; + if (bman.gametype == GT_team && players[p_dat->dead_by].team_nr >= 0 && players[p_dat->dead_by].team_nr < MAX_TEAMS) + teams[players[p_dat->dead_by].team_nr].points++; net_game_send_player (p_dat->dead_by); } } diff --git a/src/player.c b/src/player.c index 8ca55c8..b6943ed 100644 --- a/src/player.c +++ b/src/player.c @@ -1,4 +1,4 @@ -/* $Id: player.c,v 1.87 2004/09/23 13:31:51 stpohle Exp $ +/* $Id: player.c,v 1.88 2004/09/26 22:06:58 stpohle Exp $ * player.c - everything what have to do with the player */ #include @@ -546,8 +546,11 @@ player_died (_player * player, signed char dead_by) bman.updatestatusbar = 1; // force an update if (PS_IS_alife (player->state) && dead_by >= 0 && dead_by < MAX_PLAYERS) - if (player - players != dead_by) + if (player - players != dead_by) { players[dead_by].points++; + if (bman.gametype == GT_team && players[dead_by].team_nr >= 0 && players[dead_by].team_nr < MAX_TEAMS) + teams[players[dead_by].team_nr].points++; + } player->frame = 0; player->state &= (0xFF - PSF_alife); player->dead_by = dead_by;