diff --git a/ChangeLog b/ChangeLog index c41d2ce..03a003f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,8 +1,23 @@ -$Id: ChangeLog,v 1.126 2008/07/27 11:24:32 stpohle Exp $ +$Id: ChangeLog,v 1.127 2009/05/11 20:51:25 stpohle Exp $ CVS Version =========== +11.5.2009 +- got a big patch file from Michel Bernay which fixes: + fixed: bug about compute points of the winner in multiplayer mode + fixed: bug for server for coputing point (Suppress all process in + reception of playerdata) + fixed: bug in cache managment (lot of messages lost by function + rscachedel) + added: function to find who player is owner of explosion to compute + the killer + added: function in debug for display player statistics + changed: display points on general menu + changed: scorring now a unique players wins a round add 1 point + (bonus for victory) and numer of player killed by thge + winner + 27.7.2008 - Added Warning if a game get startet with only one player selected Patch send in by: Carles Pina i Estany diff --git a/configure.in b/configure.in index 70a4c8a..d4c8e0c 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ dnl Please disable it in the Anjuta project configuration AC_INIT(configure.in) AC_CANONICAL_TARGET -AM_INIT_AUTOMAKE(bomberclone, 0.11.8) +AM_INIT_AUTOMAKE(bomberclone, 0.11.8.99-cvs) AM_CONFIG_HEADER(config.h) AC_EXEEXT diff --git a/include/bomb.h b/include/bomb.h index 8382bc5..3a4f428 100644 --- a/include/bomb.h +++ b/include/bomb.h @@ -1,4 +1,4 @@ -/* $Id: bomb.h,v 1.7 2007/01/12 11:15:44 stpohle Exp $ +/* $Id: bomb.h,v 1.8 2009/05/11 20:51:25 stpohle Exp $ * bomb include file */ @@ -29,6 +29,7 @@ struct { struct __bomb_id { // save the bomb id signed char p; // playernumber of this bomb signed char b; // bombnumber of this bomb + signed char pIgnition; // playernumber of ignition explode } id; float firer[4]; // range of the fire for the fire for each direction int firemaxr[4]; // max range reached? diff --git a/include/bomberclone.h b/include/bomberclone.h index 7f55df2..fa30e45 100644 --- a/include/bomberclone.h +++ b/include/bomberclone.h @@ -1,4 +1,4 @@ -/* $Id: bomberclone.h,v 1.36 2008/07/27 11:24:37 stpohle Exp $ */ +/* $Id: bomberclone.h,v 1.37 2009/05/11 20:51:25 stpohle Exp $ */ /* bomberclone.h */ #ifndef _BOMBERCLONE_H_ @@ -72,7 +72,7 @@ struct { signed char lastwinner; // number of the last winnet int maxplayer; // number of max players for the server - + int playnum; // Number of play int sock; // the server socket int net_ai_family; char port[LEN_PORT]; // what port we're using @@ -159,6 +159,7 @@ extern void d_in_pl_detail (char *head); extern void d_playerdetail (char *head); extern void d_gamedetail (char *head); extern void d_printf (char *fmt,...); +extern void d_playerstat(char *head); extern void d_bitprint (int bits, int nr); extern void d_fatal (char *fmt,...); extern void debug_ingameinfo(); diff --git a/include/packets.h b/include/packets.h index 6c50694..a64f239 100644 --- a/include/packets.h +++ b/include/packets.h @@ -1,4 +1,4 @@ -/* $Id: packets.h,v 1.38 2008/04/04 10:39:05 stpohle Exp $ +/* $Id: packets.h,v 1.39 2009/05/11 20:51:25 stpohle Exp $ * network packets.. */ #ifndef _PACKETS_H_ @@ -13,34 +13,34 @@ * only packets between client and server, all packets behinf PKG_field * are between all clients so they will be forwarded. */ enum _network_data { - PKG_error = 0, - PKG_gameinfo, - PKG_joingame, // every packet below here will checked - // if it comes from a orginal player - PKG_contest, - PKG_playerid, - PKG_servermode, - PKG_pingreq, - PKG_pingack, - PKG_getfield, - PKG_getplayerdata, - PKG_teamdata, - PKG_fieldline, - PKG_pkgack, - PKG_mapinfo, - PKG_tunneldata, - PKG_updateinfo, - PKG_field, // forward - always be the first field - PKG_playerdata, // forward - PKG_bombdata, // forward - PKG_playerstatus, // forward - PKG_playermove, // forward - PKG_chat, // forward - PKG_ill, // forward - PKG_special, // forward - PKG_dropitem, // forward - PKG_respawn, // forward - PKG_quit // forward - always the last known type forwarded type + PKG_error = 0, // 0 + PKG_gameinfo, // 1 + PKG_joingame, // 2 every packet below here will checked + // if it comes from a orginal player + PKG_contest, // 3 + PKG_playerid, // 4 + PKG_servermode, // 5 + PKG_pingreq, // 6 + PKG_pingack, // 7 + PKG_getfield, // 8 + PKG_getplayerdata, // 9 + PKG_teamdata, // 10 + PKG_fieldline, // 11 + PKG_pkgack, // 12 + PKG_mapinfo, // 13 + PKG_tunneldata, // 14 + PKG_updateinfo, // 15 + PKG_field, // 16 forward - always be the first field + PKG_playerdata, // 17 forward + PKG_bombdata, // 18 forward + PKG_playerstatus, // 19 forward + PKG_playermove, // 20 forward + PKG_chat, // 21 forward + PKG_ill, // 22 forward + PKG_special, // 23 forward + PKG_dropitem, // 24 forward + PKG_respawn, // 25 forward + PKG_quit // 26 forward - always the last known type forwarded type }; @@ -176,6 +176,7 @@ struct pkg_playerid { signed char netflags; // network flags Sint16 points; Sint16 wins; + Sint16 nbrKilled; signed char team_nr; // team number Sint16 team_points; // team points Sint16 team_wins; // team wins @@ -185,6 +186,7 @@ struct pkg_playerdata { struct pkgheader h; signed char p_nr; // Playernumber Sint16 points; // points + Sint16 nbrKilled; // number of player kill during a round Sint16 wins; // how many times we win signed char gfx_nr; // the gfx number we want to use signed char team_nr; // teamnumber of the player @@ -211,6 +213,7 @@ struct pkg_playermove { struct pkg_bombdata { struct pkgheader h; unsigned char p_nr; + unsigned char pi_nr; unsigned char b_nr; Sint16 x; Sint16 y; diff --git a/include/player.h b/include/player.h index e7d8c6a..27ea2d4 100644 --- a/include/player.h +++ b/include/player.h @@ -1,4 +1,4 @@ -/* $Id: player.h,v 1.11 2007/01/12 22:42:31 stpohle Exp $ +/* $Id: player.h,v 1.12 2009/05/11 20:51:25 stpohle Exp $ * playerinclude file */ @@ -8,16 +8,16 @@ #include "bomb.h" enum _specials { - SP_nothing=0, // player has no special - SP_trigger, // triggered bomb - SP_row, // bomb row - SP_push, // push bombs - SP_moved, // moved bombs - SP_liquid, // liquid bombs - SP_kick, // kick bombs + SP_nothing=0, // 0 player has no special + SP_trigger, // 1 triggered bomb + SP_row, // 2 bomb row + SP_push, // 3 push bombs + SP_moved, // 4 moved bombs + SP_liquid, // 5 liquid bombs + SP_kick, // 6 kick bombs - SP_max, // just to know how many types there are - SP_clear // needed to let the server know we removed the special + SP_max, // 7 just to know how many types there are + SP_clear // 8 needed to let the server know we removed the special }; @@ -43,6 +43,7 @@ enum _playerstateflags { // not Set | Set PSF_respawn = 32 // | Player is Respawning }; + #define PSFM_used (PSF_used + PSF_playing) #define PSFM_alife (PSF_used + PSF_alife + PSF_playing) #define PS_IS_dead(__ps) (((__ps) & (PSFM_alife + PSF_respawn)) == (PSFM_used)) @@ -53,6 +54,12 @@ enum _playerstateflags { // not Set | Set #define PS_IS_used(__ps) (((__ps) & (PSFM_used)) != 0) #define PS_IS_aiplayer(__ps) ((((__ps) & (PSFM_used)) != 0) && (((__ps) & (PSF_ai)) == PSF_ai)) +struct { + int killedBy[MAX_PLAYERS]; + int killed; + int unknown; + int isaplayer; +} typedef _gamestats; struct { float to; // if (to > 0) the ilness is still working @@ -106,10 +113,12 @@ struct { signed char in_nr; // number of the connected player entry int points; // points + int nbrKilled; // number of player killed during a round int wins; // wins signed char dead_by; // player who killed this player _net_player net; // holds all important network data + _gamestats gamestats; } typedef _player; diff --git a/src/bomb.c b/src/bomb.c index b8f2579..8dc38a1 100644 --- a/src/bomb.c +++ b/src/bomb.c @@ -1,4 +1,4 @@ -/* $Id: bomb.c,v 1.70 2007/02/22 21:40:39 stpohle Exp $ */ +/* $Id: bomb.c,v 1.71 2009/05/11 20:51:25 stpohle Exp $ */ /* everything what have to do with the bombs */ #include "bomberclone.h" @@ -63,7 +63,7 @@ void draw_bomb (_bomb * bomb) { void bomb_explode (_bomb *bomb, int net) { int d; - d_printf ("Bomb Explode p:%d, b:%d [%f,%f]\n", bomb->id.p, bomb->id.b, bomb->pos.x, bomb->pos.y); + d_printf ("Bomb Explode p:%d, b:%d, pI:%d, exe_nr:%d [%f,%f]\n", bomb->id.p, bomb->id.b, bomb->id.pIgnition, bomb->ex_nr, bomb->pos.x, bomb->pos.y); if (bomb->ex_nr == -1) bomb->ex_nr = bman.last_ex_nr++; // set bomb explosion id @@ -463,6 +463,9 @@ int explosion_check_field (int x, int y, _bomb *bomb) if (tmpbomb != bomb && tmpbomb->state != BS_exploding && tmpbomb->mode != BM_kicked) { tmpbomb->ex_nr = bomb->ex_nr; // set the ex_nr to identify explosions + // Add propagation of owner first explosion propagation + tmpbomb->id.pIgnition = bomb->id.pIgnition; + // d_printf ("explosion_check_field: launch bomb_explode == ex_nr:%d pl:%d pli:%d\n", tmpbomb->ex_nr, tmpbomb->id.p, tmpbomb->id.pIgnition); bomb_explode (tmpbomb, 1); } } @@ -473,9 +476,15 @@ int explosion_check_field (int x, int y, _bomb *bomb) if (((tmpplayer->state & PSF_alife) != 0) && (GT_SP || (GT_MP && (&players[bman.p_nr] == tmpplayer || (IS_LPLAYER2 && &players[bman.p2_nr] == tmpplayer))) - || (GT_MP_PTPM && PS_IS_aiplayer (tmpplayer->state)))) + || (GT_MP_PTPM && PS_IS_aiplayer (tmpplayer->state)))){ + + // Check if the bomb owner is the player killed in this case the killer is owner of bomb ignition + if (tmpplayer == &players[bomb->id.p]) // suicide case + player_died (tmpplayer, bomb->id.pIgnition, 0); + else player_died (tmpplayer, bomb->id.p, 0); } + } // let the stones right beside explode if (map.field[x][y].type != FT_nothing && map.field[x][y].type != FT_tunnel diff --git a/src/configuration.c b/src/configuration.c index 14d5890..e33fa99 100644 --- a/src/configuration.c +++ b/src/configuration.c @@ -1,4 +1,4 @@ -/* $Id: configuration.c,v 1.83 2008/07/27 11:24:37 stpohle Exp $ +/* $Id: configuration.c,v 1.84 2009/05/11 20:51:25 stpohle Exp $ * configuration */ #include @@ -88,6 +88,7 @@ config_init (int argc, char **argv) bman.p_nr = -1; bman.p2_nr = -1; bman.gamename[0] = 0; + bman.playnum = 0; sprintf (bman.playername, "Player1"); sprintf (bman.player2name, "Player2"); sprintf (bman.port, "%d", DEFAULT_UDPPORT); @@ -111,7 +112,7 @@ config_init (int argc, char **argv) map.size.y = 17; map.map[0] = 0; map.map_selection = 2; - map.type = -1; + map.type = 1; bman.firewall = 0; bman.init_timeout = GAME_TIMEOUT; bman.ai_players = 1; @@ -335,6 +336,9 @@ config_read () if (!strcmp (keyword, "mapselection")) { map.map_selection = atoi (value); } + if (!strcmp (keyword, "maptype")) { + map.type = atoi (value); + } if (!strcmp (keyword, "randomtileset")) { map.random_tileset = atoi (value); } @@ -368,6 +372,21 @@ config_read () if (!strcmp (keyword, "start_speed")) { sscanf (value, "%f", &bman.start_speed); } + if (!strcmp (keyword, "special_itembombs")) { + sscanf (value, "%d", &map.bombs); + } + if (!strcmp (keyword, "special_itemfire")) { + sscanf (value, "%d", &map.fire); + } + if (!strcmp (keyword, "special_itemshoes")) { + sscanf (value, "%d", &map.shoes); + } + if (!strcmp (keyword, "special_itemmixed")) { + sscanf (value, "%d", &map.mixed); + } + if (!strcmp (keyword, "special_itemdeath")) { + sscanf (value, "%d", &map.death); + } if (!strcmp (keyword, "special_trigger")) { sscanf (value, "%d", &map.sp_trigger); } @@ -499,6 +518,7 @@ config_write () fprintf (config, "bitsperpixel=%d\n", gfx.bpp); fprintf (config, "randomtileset=%d\n", map.random_tileset); fprintf (config, "mapselection=%d\n", map.map_selection); + fprintf (config, "maptype=%d\n", map.type); fprintf (config, "sndrate=%d\n", snd.audio_rate); fprintf (config, "sndchannels=%d\n", snd.audio_channels); fprintf (config, "sndformat=%d\n", snd.audio_format); @@ -507,6 +527,11 @@ config_write () fprintf (config, "start_bombs=%d\n", bman.start_bombs); fprintf (config, "start_range=%d\n", bman.start_range); fprintf (config, "start_speed=%f\n", bman.start_speed); + fprintf (config, "special_itembombs=%d\n", map.bombs); + fprintf (config, "special_itemfire=%d\n", map.fire); + fprintf (config, "special_itemshoes=%d\n", map.shoes); + fprintf (config, "special_itemmixed=%d\n", map.mixed); + fprintf (config, "special_itemdeath=%d\n", map.death); fprintf (config, "special_trigger=%d\n", map.sp_trigger); fprintf (config, "special_row=%d\n", map.sp_row); fprintf (config, "special_push=%d\n", map.sp_push); diff --git a/src/debug.c b/src/debug.c index 418b001..aca2210 100644 --- a/src/debug.c +++ b/src/debug.c @@ -34,13 +34,44 @@ void d_printf (char *fmt,...) { }; +void d_playerstat (char *head) { + int i, j; + char text[255]; + + d_printf ("---------------> %s nb play: %d\n", head, bman.playnum); + + sprintf (text, "id Name killed Unknown"); + for (i = 0; i < MAX_PLAYERS; i++) + if (players[i].gamestats.isaplayer == 1) + sprintf(text, "%s %02d", text, i); + sprintf(text, "%s\n", text); + d_printf (text); + + for (i = 0; i < MAX_PLAYERS; i++){ + if (players[i].gamestats.isaplayer == 1 ) { + sprintf(text, "%02d %-16s %2d %d ", i, players[i].name, players[i].gamestats.killed, players[i].gamestats.unknown); + for (j = 0; j < MAX_PLAYERS; j++) + if (players[j].gamestats.isaplayer == 1 ) + sprintf(text, "%s %2d", text, players[i].gamestats.killedBy[j]); + sprintf(text, "%s\n", text); + d_printf (text); + } + } +}; + + +// int killed[MAX_PLAYERS]; + + + void d_playerdetail (char *head) { int i; d_printf ("---------------> %s\n", head); - d_printf ("Nr Name GFX Sta Pkt Win Team net_flag [Addr]\n"); + d_printf ("Nr Name GFX Sta Pkt Win kil Team net_flag [Addr]\n"); for (i = 0; i < MAX_PLAYERS; i++) - d_printf ("%2d %16s %3d %3d %3d %3d %4d %3d %p[%s:%s]\n",i, players[i].name, players[i].gfx_nr, players[i].state, players[i].points, players[i].wins, players[i].team_nr, players[i].net.flags, players[i].net.addr.host, &players[i].net.addr, players[i].net.addr.port); + if (players[i].gfx_nr != -1 ) + d_printf ("%2d %16s %3d %3d %3d %3d %3d %4d %3d %p[%s:%s]\n",i, players[i].name, players[i].gfx_nr, players[i].state, players[i].points, players[i].wins, players[i].nbrKilled, players[i].team_nr, players[i].net.flags, players[i].net.addr.host, &players[i].net.addr, players[i].net.addr.port); }; @@ -109,3 +140,4 @@ void debug_ingameinfo() { sprintf (text, "Pl_nr: %d TO: %3.2f", bman.players_nr, bman.timeout); font_gfxdraw (100, gfx.res.y-font[0].size.y, text, 0, 0, (map.size.y*256)+10); }; + diff --git a/src/game.c b/src/game.c index 01c0d4b..4fb3ac6 100644 --- a/src/game.c +++ b/src/game.c @@ -1,4 +1,4 @@ -/* $Id: game.c,v 1.119 2008/07/27 11:24:37 stpohle Exp $ +/* $Id: game.c,v 1.120 2009/05/11 20:51:25 stpohle Exp $ game.c - procedures for the game. */ #include @@ -64,7 +64,7 @@ game_draw_info () SDL_BlitSurface (players[i].gfx->small_image, &src, gfx.screen, &dest); } - sprintf (scrtext, "%10s:%2d", players[i].name, players[i].points); + 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; @@ -80,7 +80,7 @@ game_draw_info () font_draw (x, j, scrtext, 0, col); - x = x + 170; + x = x + 180; if (x >= gfx.res.x - (120 + 170)) { x = 0; j = j + 1.5 * font[0].size.x; @@ -196,14 +196,7 @@ game_keys_loop () bman.updatestatusbar = 1; // force an update } - /* - if (keys[SDLK_F9] && event.type == SDL_KEYDOWN) { - // Switch Debugmode - debug = !debug; - bman.updatestatusbar = 1; // force an update - } - */ - + if (keyb_gamekeys.state[BCK_esc] && !keyb_gamekeys.old[BCK_esc]) { if (chat.active && (bman.state == GS_ready || bman.state == GS_running) && IS_LPLAYER2) { chat.active = 0; @@ -439,16 +432,23 @@ game_end () /* 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++) + 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) - players[bman.lastwinner].points += bman.players_nr_s; + } + + 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; @@ -505,7 +505,7 @@ game_start () 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++; @@ -538,6 +538,8 @@ game_start () 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++) @@ -552,6 +554,7 @@ game_start () 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; @@ -766,12 +769,15 @@ game_showresultnormal (int pos_x, int pos_y, int pos_w, int pos_h) /* 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]->wins < players[p].wins - || (pl[i - 1]->wins == players[p].wins - && pl[i - 1]->points < players[p].points))) { + 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]; @@ -813,7 +819,7 @@ game_showresultnormal (int pos_x, int pos_y, int pos_w, int pos_h) font_gfxdraw (10 + pos_x + x + GFX_MENUPLAYERIMGSIZE_X, pos_y + y - 10, pl[p]->name, 0, COLOR_gray, 1); - sprintf (text, "%3d (%3d)", pl[p]->wins, pl[p]->points); + 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) { diff --git a/src/map.c b/src/map.c index c4dd035..706fdcf 100644 --- a/src/map.c +++ b/src/map.c @@ -1,4 +1,4 @@ -/* $Id: map.c,v 1.27 2006/07/30 11:44:57 stpohle Exp $ */ +/* $Id: map.c,v 1.28 2009/05/11 20:51:25 stpohle Exp $ */ /* map handling, like generate and load maps. */ #include "bomberclone.h" @@ -112,11 +112,8 @@ map_new (char *filename) */ pl_cnt = 0; - for (pl = 0; pl < MAX_PLAYERS; pl++) { - if (PS_IS_used (players[pl].state)) { - pl_cnt++; } } diff --git a/src/netmenu.c b/src/netmenu.c index 568696d..56b134b 100644 --- a/src/netmenu.c +++ b/src/netmenu.c @@ -121,11 +121,17 @@ multiplayer_firstrun () players[i].gfx = NULL; players[i].net.timestamp = timestamp; players[i].points = 0; + players[i].nbrKilled = 0; players[i].wins = 0; players[i].net.pingreq = 20; players[i].net.pingack = 22; players[i].state = 0; players[i].team_nr = -1; + players[i].gamestats.killed = 0; + players[i].gamestats.unknown = 0; + players[i].gamestats.isaplayer = 0; + for (j = 0; j < MAX_PLAYERS; j++) + players[i].gamestats.killedBy[j] = 0; } for (i = 0; i < MAX_TEAMS; i++) { @@ -172,6 +178,7 @@ void host_multiplayer_game () { /* the loop for the multiplayer games */ void multiplayer_game () { + int olddebug = debug; while (bman.state != GS_startup && bman.state != GS_quit && bman.sock != -1) { /* check players and in_pl lists */ @@ -206,7 +213,13 @@ void multiplayer_game () { else game_end (); } + } + // Only for update statistics + debug = 1; + d_playerstat("Stats at the end of game"); + debug = olddebug; + }; diff --git a/src/packets.c b/src/packets.c index b23634e..a166f4b 100644 --- a/src/packets.c +++ b/src/packets.c @@ -146,6 +146,7 @@ void do_joingame (struct pkg_joingame *p_jg, _net_addr * addr) { d_printf (" Player Added : Nr:[%d] Name:%10s\n", i, p_jg->name); pl->points = 0; pl->wins = 0; + pl->nbrKilled = 0; pl->team_nr = -1; team_choose (pl); @@ -175,13 +176,13 @@ void do_joingame (struct pkg_joingame *p_jg, _net_addr * addr) { pl->net.flags = NETF_firewall; pl->net.addr.pl_nr = i; bman.players_nr_s++; + addr->pl_nr = i; /* send to the new client the servermode and the complete playerlist */ if ((!p_jg->secondplayer) && !(players[j].net.flags & NETF_local2)) send_mapinfo (addr); send_servermode (addr, i); // with this packet the client know it'S pl_nr - addr->pl_nr = i; } else if (GS_WAITRUNNING) { @@ -392,6 +393,7 @@ do_playerid (struct pkg_playerid *p_id, _net_addr * addr) if (GT_MP_PTPS) { pl->points = NTOH16 (p_id->points); + pl->nbrKilled = NTOH16 (p_id->nbrKilled); pl->wins = NTOH16 (p_id->wins); pl->team_nr = p_id->team_nr; if (pl->team_nr >= 0 && pl->team_nr < MAX_TEAMS) { @@ -454,6 +456,7 @@ send_playerid (_net_addr * addr, char *name, char *pladdr, char *plport, if (pl_nr != -1) { p_id.points = HTON16 (players[pl_nr].points); p_id.wins = HTON16 (players[pl_nr].wins); + p_id.nbrKilled = HTON16 (players[pl_nr].nbrKilled); p_id.state = players[pl_nr].state; p_id.team_nr = team_nr; if (team_nr >= 0 && team_nr < MAX_TEAMS) { @@ -464,6 +467,7 @@ send_playerid (_net_addr * addr, char *name, char *pladdr, char *plport, else { p_id.points = 0; p_id.wins = 0; + p_id.nbrKilled = 0; p_id.state = 0; p_id.team_nr = -1; p_id.team_points = 0; @@ -490,8 +494,7 @@ do_teamdata (struct pkg_teamdata *td, _net_addr * addr) if (addr->pl_nr == -1) return; - d_printf ("do_teamdata (addr->pl_nr: %d): team:%d col:%d wins:%d\n", addr->pl_nr, td->team_nr, - td->col, td->wins); + d_printf ("do_teamdata (addr->pl_nr: %d): team:%d col:%d wins:%d\n", addr->pl_nr, td->team_nr, td->col, td->wins); if (addr->pl_nr == bman.p_servnr) { /* packet comes from the server */ if (td->team_nr >= 0 && td->team_nr < MAX_TEAMS) { @@ -817,6 +820,7 @@ send_playerdata (_net_addr * addr, int p_nr, _player * pl) p_dat.state = pl->state; p_dat.wins = HTON16 (pl->wins); p_dat.points = HTON16 (pl->points); + p_dat.nbrKilled = HTON16 (pl->nbrKilled); p_dat.dead_by = pl->dead_by; p_dat.frame = HTON16 (FTOI16 (pl->frame)); p_dat.p_nr = p_nr; @@ -845,6 +849,7 @@ do_playerdata (struct pkg_playerdata *p_dat, _net_addr * addr) if (bman.state == GS_running && bman.p_nr != p_dat->p_nr) { pl->points = NTOH16 (p_dat->points); + pl->nbrKilled = NTOH16 (p_dat->nbrKilled); pl->dead_by = NTOH16 (p_dat->dead_by); pl->team_nr = p_dat->team_nr; } @@ -852,6 +857,7 @@ do_playerdata (struct pkg_playerdata *p_dat, _net_addr * addr) pl->pos.x = I16TOF (NTOH16 (p_dat->pos.x)); pl->pos.y = I16TOF (NTOH16 (p_dat->pos.y)); pl->dead_by = p_dat->dead_by; + pl->nbrKilled = NTOH16 (p_dat->nbrKilled); pl->points = NTOH16 (p_dat->points); pl->d = p_dat->d; pl->bombs_n = p_dat->bombs_n; @@ -869,15 +875,8 @@ do_playerdata (struct pkg_playerdata *p_dat, _net_addr * addr) /* check if the player just died */ if (PS_IS_alife (pl->state) && PS_IS_dead (p_dat->state)) { /* 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); player_died (pl, p_dat->dead_by, 1); } - } pl->state = p_dat->state; } @@ -1012,16 +1011,16 @@ void do_bombdata (struct pkg_bombdata *b_dat, _net_addr * addr) { if (b_dat->state == BS_off) return; // if there was a bomb let it explose don't delete the bomb - d_printf ("do_bombdata [%f,%f] Player: %d Bomb: %d, ex_nr:%d\n", - I16TOF (NTOH16 (b_dat->x)), I16TOF (NTOH16 (b_dat->y)), b_dat->p_nr, - b_dat->b_nr, NTOH32 (b_dat->ex_nr)); + d_printf ("do_bombdata [%f,%f] Player: %d PlayerIgnition: %d Bomb: %d, ex_nr:%d\n", + I16TOF (NTOH16 (b_dat->x)), I16TOF (NTOH16 (b_dat->y)), b_dat->p_nr, b_dat->pi_nr, b_dat->b_nr, NTOH32 (b_dat->ex_nr)); bomb = &players[b_dat->p_nr].bombs[b_dat->b_nr]; if (bomb->state == BS_exploding) { d_printf ("do_bombdata ---> bomb is already exploding\n"); return; } - + // Update player ignition + bomb->id.pIgnition = b_dat->pi_nr; if ((bomb->pos.x != NTOH16 (b_dat->x) || bomb->pos.y != NTOH16 (b_dat->y)) && bomb->state == BS_exploding && b_dat->state != BS_exploding) d_printf ("do_bombdata WARNING : bomb explosion haven't finished\n"); @@ -1083,6 +1082,7 @@ send_bombdata (_net_addr * addr, int p, int b, _bomb * bomb) b_dat.state = (bomb->mode << 4) | (bomb->state); b_dat.b_nr = b; b_dat.p_nr = p; + b_dat.pi_nr = bomb->id.pIgnition; b_dat.h.flags = PKGF_ackreq; b_dat.fdata = HTON16 (FTOI16 (bomb->fdata)); b_dat.destx = HTON16 (FTOI16 (bomb->dest.x)); @@ -1473,8 +1473,9 @@ send_pkgack (_net_addr * addr, unsigned char typ, short int id) void do_pkgack (struct pkg_pkgack *p_ack, _net_addr * addr) { - d_printf ("do_pkgack (%s:%s)\n", addr->host, addr->port); - rscache_del (addr, p_ack->typ, NTOH16 (p_ack->id)); + d_printf ("do_pkgack pl_nr:%d type:%u id:%u\n", addr->pl_nr, p_ack->typ, p_ack->id); + if ( ! rscache_del (addr, p_ack->typ, NTOH16 (p_ack->id))) + d_printf ("do_pkgack ERROR rscache_del data not found : pl_nr:%d type:%u id:%u\n", addr->pl_nr, p_ack->typ, p_ack->id); }; @@ -1799,6 +1800,8 @@ inpkg_delplayer (int pl_nr) void send_pkg (struct pkg *packet, _net_addr * addr) { + d_printf ("send_pkg: plnr:%d, typ:%u id:%u\n", addr->pl_nr, packet->h.typ, packet->h.id); + /* check if the packet would be send to * an AI_Player, so ignore it. */ if ((addr->pl_nr >= 0 && addr->pl_nr < MAX_PLAYERS) @@ -1850,7 +1853,7 @@ fwd_pkg (struct pkg *packet, _net_addr * addr) void do_pkg (struct pkg *packet, _net_addr * addr, int len) { - // d_printf ("do_pkg: addr %p, pkg %p\n", addr, packet); + d_printf ("do_pkg: plnr:%d, typ:%u id:%u\n", addr->pl_nr, packet->h.typ, packet->h.id); if (((packet->h.flags & PKGF_ipv6) == 0 && bman.net_ai_family != PF_INET) || ((packet->h.flags & PKGF_ipv6) != 0 && bman.net_ai_family == PF_INET)) { d_printf ("do_pkg: packet comes from the wrong network type\n"); @@ -1891,7 +1894,7 @@ do_pkg (struct pkg *packet, _net_addr * addr, int len) * the bomb is dropped twice bug. */ if (inpkg_check (packet->h.typ, NTOH16 (packet->h.id), addr) != -1) { /* we have got this packet already */ - d_printf ("do_pkg: double packet ignoring addr->pl_nr=%d\n", addr->pl_nr); + d_printf ("do_pkg: double packet ignoring addr->pl_nr=%d type:%d\n", addr->pl_nr, packet->h.typ); if (addr->pl_nr >= 0 && addr->pl_nr < MAX_PLAYERS) players[addr->pl_nr].net.pkgopt.to_2sec++; return; diff --git a/src/pkgcache.c b/src/pkgcache.c index 5ba7243..1b49746 100644 --- a/src/pkgcache.c +++ b/src/pkgcache.c @@ -1,4 +1,4 @@ -/* $Id: pkgcache.c,v 1.13 2006/08/19 23:41:47 stpohle Exp $ +/* $Id: pkgcache.c,v 1.14 2009/05/11 20:51:25 stpohle Exp $ * Resendcache work, We need this to resend lost packets over the network. * we will keep every packet with the PKGF_ackreq flag as long as we haven't * got any answer from the destination host. And resend the packet after a givin @@ -21,7 +21,7 @@ void rscache_init () { void rscache_add (_net_addr *addr, struct pkg *packet) { int len; - // d_printf ("rscache_add: addr %p, pkg %p\n", addr, packet); + // d_printf ("rscache_add: pl:%p, typ:%u id:%u\n", addr->pl_nr, packet->h.typ, packet->h.id); /* check if there is still some free space left. */ if (rscache.count >= PKG_RESENDCACHE_SIZE) { d_printf ("rscache_add no free rscache entry left.\n"); @@ -44,9 +44,9 @@ void rscache_delnr (int nr) { if (nr >= 0 && nr < PKG_RESENDCACHE_SIZE) { for (a = nr; a < rscache.count - 1; a++) - rscache.entry[nr] = rscache.entry[nr+1]; - rscache.count--; - // d_printf ("rscache_delnr: element %d deleted.\n", nr); + rscache.entry[a] = rscache.entry[a+1]; + rscache.count--; + d_printf ("rscache_delnr: element %d deleted.\n", nr); } else d_printf ("rscache_delnr: number is out of range (%d)\n", nr); @@ -58,7 +58,7 @@ void rscache_delnr (int nr) { int rscache_del (_net_addr *addr, unsigned char typ, short unsigned int id) { int i; - // d_printf ("rscache_del: addr %p (pl_nr:%d, typ:%d, id:%d\n", addr, addr->pl_nr, typ, id); + // d_printf ("rscache_del: addr %p (pl_nr:%d, typ:%d, id:%u\n", addr, addr->pl_nr, typ, id); for (i = 0; (i < rscache.count) && (i < PKG_RESENDCACHE_SIZE); i++) { if (rscache.entry[i].addr.pl_nr == addr->pl_nr && @@ -85,8 +85,8 @@ void rscache_loop () { && rscache.entry[i].retry < RESENDCACHE_RETRY) { /* send it again */ d_printf - ("Data Send Timeout (%s:%s) Resend now Package Fill %d, Pos %d\n", - rscache.entry[i].addr.host, rscache.entry[i].addr.port, rscache.count,i); + ("Data Send Timeout Resend pl:%p, typ:%u id:%u Fill:%d Pos:%d\n", + rscache.entry[i].addr.pl_nr, rscache.entry[i].packet.h.typ, rscache.entry[i].packet.h.id, rscache.count, i); udp_send (bman.sock, (char *) &rscache.entry[i].packet, NTOH16 (rscache.entry[i].packet.h.len), @@ -100,8 +100,9 @@ void rscache_loop () { if (timestamp - rscache.entry[i].timestamp >= timeout && rscache.entry[i].retry >= RESENDCACHE_RETRY) { - d_printf ("Data Send Timeout (%s:%s) Delete Fill %d, Pos %d\n", - rscache.entry[i].addr.host, rscache.entry[i].addr.port, rscache.count, i); + d_printf + ("Data Send Timeout Delete pl:%p, typ:%u id:%u Fill:%d Pos:%d\n", + rscache.entry[i].addr.pl_nr, rscache.entry[i].packet.h.typ, rscache.entry[i].packet.h.id, rscache.count, i); if (rscache.entry[i].addr.pl_nr >= 0 && rscache.entry[i].addr.pl_nr < MAX_PLAYERS) players[rscache.entry[i].addr.pl_nr].net.pkgopt.to_2sec++; diff --git a/src/player.c b/src/player.c index 3b2bfc8..cbec397 100644 --- a/src/player.c +++ b/src/player.c @@ -1,4 +1,4 @@ -/* $Id: player.c,v 1.106 2007/12/09 22:37:38 stpohle Exp $ +/* $Id: player.c,v 1.107 2009/05/11 20:51:25 stpohle Exp $ * player.c - everything what have to do with the player */ #include @@ -292,6 +292,7 @@ stepmove_player (int pl_nr) _point bomb1[MAX_PLAYERS * MAX_BOMBS], bomb2[MAX_PLAYERS * MAX_BOMBS]; _player *p = &players[pl_nr]; + int i, j, f; @@ -421,6 +422,24 @@ player_checkpos (int x, int y) }; + +/* Search if an killer exist for explosion at position */ +/* Must be used after check_exfield function */ +int +get_killer_for_explosion (short int x, short int y) +{ + int killer = -1, i; + + //for (i = 0; (i < 4 && killer == -1); i++) + for (i = 0; i < 4; i++) + if (map.field[x][y].ex[i].count > 0) { + if (players[map.field[x][y].ex[i].bomb_p].bombs[map.field[x][y].ex[i].bomb_b].ex_nr == map.field[x][y].ex_nr ) + killer = map.field[x][y].ex[i].bomb_p; + d_printf("get_killer_for_explosion: found killer pl_nr:%d killer:%d for index %d\n", map.field[x][y].ex[i].bomb_p, killer, i); + } + return killer; +} + /* move the player if he have to move AND check if we are on a block or over fire */ void @@ -460,15 +479,15 @@ player_move (int pl_nr) /* check the players position */ if (PS_IS_alife (p->state) && (CUTINT(p->pos.x) > EXPLOSION_SAVE_DISTANCE && (p->d == left || p->d == right)) && (!check_exfield (p->pos.x + 1.0f, p->pos.y))) - player_died (p, -1, 0); - if (PS_IS_alife (p->state) && (CUTINT(p->pos.y) > EXPLOSION_SAVE_DISTANCE && (p->d == up || p->d == down)) + player_died (p, get_killer_for_explosion(p->pos.x + 1.0f, p->pos.y), 0); + else if (PS_IS_alife (p->state) && (CUTINT(p->pos.y) > EXPLOSION_SAVE_DISTANCE && (p->d == up || p->d == down)) && (!check_exfield (p->pos.x, p->pos.y + 1.0f))) - player_died (p, -1, 0); - if (PS_IS_alife (p->state) && ((CUTINT(p->pos.x) < (1.0f - EXPLOSION_SAVE_DISTANCE) && (p->d == left || p->d == right)) + player_died (p, get_killer_for_explosion(p->pos.x, p->pos.y + 1.0f), 0); + else if (PS_IS_alife (p->state) && ((CUTINT(p->pos.x) < (1.0f - EXPLOSION_SAVE_DISTANCE) && (p->d == left || p->d == right)) || (CUTINT(p->pos.y) < (1.0f - EXPLOSION_SAVE_DISTANCE) && (p->d == up || p->d == down))) && (!check_exfield (p->pos.x, p->pos.y))) - player_died (p, -1, 0); + player_died (p, get_killer_for_explosion(p->pos.x, p->pos.y), 0); } }; @@ -550,19 +569,34 @@ player_died (_player * player, signed char dead_by, int network) return; // player die ! - d_printf ("player_died (pl_nr:%d : %10s) current state: %d\n", player - players, player->name, player->state); + d_printf ("player_died net:%d pl_nr:%d dead_by_nr:%d - %-10s\n", network, player - players, dead_by, players[dead_by].name); bman.updatestatusbar = 1; // force an update - if (PS_IS_alife (player->state) && dead_by >= 0 && dead_by < MAX_PLAYERS) + if (PS_IS_alife (player->state) && dead_by >= 0 && dead_by < MAX_PLAYERS){ + // Update player's statistics + players[player - players].gamestats.killedBy[dead_by]++; + // Update player's data if (player - players != dead_by) { players[dead_by].points++; + players[dead_by].nbrKilled++; 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++; + // refresh data for killer when the dead is local + if (GT_MP && !network) + net_game_send_player (dead_by); + } } + else if ( dead_by == -1 ){ + players[player - players].gamestats.unknown++; + d_printf("ERRROR get killer it is impossible check get_the_killer_for_explosion and player_move funtion traces\n"); + } + player->frame = 0; player->state &= (0xFF - PSF_alife); player->dead_by = dead_by; special_clear (player - players); + + // Send player died when is local if (GT_MP && !network) net_game_send_player (player - players);