From: Mischa POSLAWSKY Date: Sun, 25 Aug 2002 20:17:00 +0000 (+0200) Subject: unofficial version 0.7.2: mainly sync/reset fixes X-Git-Tag: v0.7.2 X-Git-Url: http://git.shiar.net/netris.git/commitdiff_plain/45dc9d995860486f1758dcf79fd2d8cd8dfb210a unofficial version 0.7.2: mainly sync/reset fixes --- diff --git a/CHANGES b/CHANGES index be0fa70..be5e370 100644 --- a/CHANGES +++ b/CHANGES @@ -134,9 +134,30 @@ -- v0.7.819 ------ * shadow piece (preview current piece dropped down) + * new players' fields are cleared at start * players are now 'fragged' by the player last adding them lines * ^ when that last player was himself(m/f) (s)he just 'died' * 'Close connection' message no longer displayed * players in teams are displayed in their teamcolor + -- v0.7.820 + + * server doesn't quit, but just stops game when 1 player/team left + * when a game stops, all players are paused and their fields reset + * server handles disconnecting clients correctly again + * 'player quit' displayed when a client disconnects from server + * game ended messages not displayed when a game was ready but not yet started + * server sends new game seed at game stop + * players' scores and (next) pieces and stuff are reset at new game + * scores are erased instead of not drawn (apm/ppm remained at new game) + + -- v0.7.821 + + * colorcoding altered a bit (server messages white, player stuff colored) + * when no team specified, server assigns a team and sends it to player + * client displays teamname of joining players + * client disconnects also transmitted to g/o players + * lag could delay changes to another game, desyncing clients + now game info is not transmitted when game has stopped + ------------------------------------------------------------------------------ diff --git a/TODO b/TODO index 3696e06..819dfce 100644 --- a/TODO +++ b/TODO @@ -1,37 +1,81 @@ + * check out quadra gravity: single block over multiplayer junkhole + ---- near-future: ------------------------------------------------------------ - * everybody in a team - * teams are colored - * server never quits - * 'you won' message, remove 'close connection' echo - * (check if commandprompt is below game) + * correct cursorposition at quit * transmit player fields of game in progress to new player * server has to maintain copy of player fields - * empty new player's field (in case of recycle) * completely fix redraw * redraw on window resize * message position/size * allow custom nicks + * server should deny duplicate nicks * move piece when unable to rotate at screenedge + * display total frags for players (by server?) + * spacebar toggles ready as well ---- asap: ------------------------------------------------------------------- + * quadra-style gravity option + * pieces stored as bitmaps + * blocks in shape stick together horizontally + * different key procedure? (allowing for multiple keys simoultaniously?) + * player messages (caps toggles typing mode?) + * commands (/team) * observers (join as g/o player) * fix -f * half width enemy fields if out of screen space * fix bot * multiplayer stats * time-based singleplayer leveling? - * shapes stored as bitmap, rotate by modifying for + * shapes stored as bitmap, rotate by modifying for (should be smaller) ---- distant future: --------------------------------------------------------- * horizontally _and_ vertically resize enemy fields + * server can add lines after specified time + * sounds + * line clear animations (flash) + * multiple next pieces * special blocks - * tetrinet compatible? + * inventory + * player keys + * delete key? + * blocks+actions + * tetrinet: + * a: add (junk)line + * b: remove specials on field + * c: clear (bottom) line + * g: gravity (move all blocks down) + * n: nuke field + * o: block bomb (blocks around any bombs on field are moved) + * q: quake (shift lines left or right) + * r: remove 10 blocks at random + * s: swap fields + * suggested: + * d: donate (next inv block given to other player) + * f: flip (symetric vertical inversion) + * h: hide (replaces inventory blocks by ?) + (one block restored per line added?) + * l: lower (all specials from field going down (g)) + * p: purge (half remove special blocks from inventory) + * t: take (take 2 specials from target player field) + * ?: mystery (block only revealed in inventory) + * tetrinet 2: + * d: darkness (temporarily blackens your field except + around current piece) + * f: confusion (temporarily rearranges controls) + * i: attack immunity (invincible to attacks) + * m: mutated pieces (gives several difficult pieces) + * v: clear column (erases vertical line) + * ideas: + * x: seperate blocks (cut all shared pieces in quadra) + * quadra compatible? + * tetrinet compatible? (prolly not) * remove bot delay (make it humanplayer-like) * new+better bot? - * replay ability? (tspec replay compatible?) + * ipv6 + * replay ability? (tspec replay or quadra rec compatible?) diff --git a/curses.c b/curses.c index 030ed25..8d500d9 100644 --- a/curses.c +++ b/curses.c @@ -242,7 +242,12 @@ ExtFunc void DrawField(int scr) } //add robot indicator } //display playername/host - // draw blocks (which is usually just clear field) + { + int x, y; + for (y = 0; y <= Players[scr].boardVisible; y++) + for (x = 0; x <= Players[scr].boardWidth; x++) + PlotBlock(scr, y, x, GetBlock(scr, y, x)); + } //draw field ShowPause(scr); } //DrawField @@ -342,19 +347,6 @@ ExtFunc void PlotBlock(int scr, int y, int x, BlockType type) PlotBlock1(scr, boardYPos[scr] - y, boardXPos[scr] + 2 * x, type); } //PlotBlock -ExtFunc void PlotShadowBlock1(int scr, int y, int x, BlockType type) -{ - move(y, x); - if (type == BT_none) addstr(" "); - else addstr("::"); -} //PlotShadowBlock1 -ExtFunc void PlotShadowBlock(int scr, int y, int x, BlockType type) -{ - if (y >= 0 && y < Players[scr].boardVisible && - x >= 0 && x < Players[scr].boardWidth) - PlotShadowBlock1(scr, boardYPos[scr] - y, boardXPos[scr] + 2 * x, type); -} //PlotShadowBlock - ExtFunc void PlotBlockS1(int scr, int y, int x, BlockType type) { //DOESN"T WORK YET... move(y, x); @@ -402,7 +394,12 @@ ExtFunc void ShowScore(int scr, struct _Score score) "yield %3d%%", 100 * score.adds / score.lines); mvprintw(10, statusXPos, "apm %9.1f", score.adds * 60 / timer); } - } + } //display [ap]pm + else { + int i; + for (i = 7; i <= 10; i++) + mvaddstr(i, statusXPos, " "); + } //too early to display stats, remove old.. } //ShowScore ExtFunc void FieldMessage(int playa, char *message) diff --git a/game.c b/game.c index b88e05d..de0d605 100644 --- a/game.c +++ b/game.c @@ -61,6 +61,7 @@ static char keyTable[KT_numKeys+1]; static char *hostStr; static int paused = 0; +static char lastadd; static sigjmp_buf close_env; @@ -245,17 +246,34 @@ ExtFunc void checkPaused(void) int i; paused = Game.started < 1; - for (i = 1; i < MAX_SCREENS; i++) if (Players[i].alive) + for (i = 1; i < MAX_SCREENS; i++) if (Players[i].alive > 0) paused |= Players[i].flags & SCF_paused; if (paused) paused = 1; - else if (Game.started == 1) { - Game.started = 2; - Messagef("The game has started"); - for (i = 1; i < MAX_SCREENS; i++) if (Players[i].alive) - ShowPause(i); - } //everybody ready } //checkPaused +ExtFunc void StartGame(void) +{ //init new game + int i; + + maxPlayer = lastadd = me; + SRandom(Game.seed); + Game.speed = Game.initspeed; + for (i = 1; i < Players[me].score.level; i++) + Game.speed /= SPEEDINC; + if (Game.speed < SPEEDMINIMUM) + Game.speed = SPEEDMINIMUM; + ResetBaseTime(); //reset timer + InitFields(); + SetITimer(Game.speed, Game.speed); + Players[me].nextShape = ChooseOption(stdOptions); + for (i = 1; i < MAX_SCREENS; i++) { + Players[i].score.score = Players[i].score.drops + = Players[i].score.lines = Players[i].score.adds = 0; + ClearField(i); + DrawField(i); + } //reset all players +} //StartGame + ExtFunc void OneGame(void) { MyEvent event; @@ -267,47 +285,41 @@ ExtFunc void OneGame(void) int key; char *p, *cmd; int playercount; - char lastadd; int linevalues[4] = { 40, 100, 400, 1200 }; //= 50*lines! - 10*(lines==1) + char teams[10][7] = { "", "Green", "Cyan", "Blue", "Purple", + "Red", "Grey", "White", "*Orange" }; int i; - maxPlayer = lastadd = me; - Game.speed = Game.initspeed; - for (i = 1; i < Players[me].score.level; i++) - Game.speed /= SPEEDINC; - if (Game.speed < SPEEDMINIMUM) - Game.speed = SPEEDMINIMUM; - ResetBaseTime(); //reset timer - ClearField(me); - InitFields(); - SetITimer(Game.speed, Game.speed); + StartGame(); if (robotEnable) { int counter; RobotCmd(0, "GameType %s\n", gameNames[game]); RobotCmd(0, "BoardSize 0 %d %d\n", Players[me].boardVisible, Players[me].boardWidth); - for (i = 1; i < MAX_SCREENS; i++) if (Players[i].alive && i != me) { - RobotCmd(0, "BoardSize %d %d %d\n", - counter, Players[i].boardVisible, Players[i].boardWidth); - RobotCmd(0, "Opponent %d %s %s\n", - counter, Players[i].name, Players[i].host); - if (Players[i].flags & SCF_usingRobot) - RobotCmd(0, "OpponentFlag %d robot\n", i); - if (Players[i].flags & SCF_fairRobot) - RobotCmd(0, "OpponentFlag %d fairRobot\n", i); - counter++; - } + for (i = 1; i < MAX_SCREENS; i++) + if ((Players[i].alive >= 0) && (i != me)) { + RobotCmd(0, "BoardSize %d %d %d\n", + counter, Players[i].boardVisible, Players[i].boardWidth); + RobotCmd(0, "Opponent %d %s %s\n", + counter, Players[i].name, Players[i].host); + if (Players[i].flags & SCF_usingRobot) + RobotCmd(0, "OpponentFlag %d robot\n", i); + if (Players[i].flags & SCF_fairRobot) + RobotCmd(0, "OpponentFlag %d fairRobot\n", i); + counter++; + } //enemy RobotCmd(0, "TickLength %.3f\n", Game.speed / 1.0e6); RobotCmd(0, "BeginGame\n"); RobotTimeStamp(); } - Players[me].nextShape = ChooseOption(stdOptions); while (1) { - if (Players[me].alive) { +GameLoop: + if (Players[me].alive > 0) { if (!StartNewPiece(me, ChooseOption(stdOptions))) { netint4 data[4]; Players[me].alive = 0; - if (lastadd == me) Messagef("You died"); + if (lastadd == me) Messagef("\\%dYou died", + Players[me].team > 7 ? 7 : Players[me].team); else Messagef("\\%d%s fragged you", Players[lastadd].team > 7 ? 7 : Players[lastadd].team, Players[lastadd].name); @@ -332,7 +344,7 @@ ExtFunc void OneGame(void) } //new piece while (1) { for (i = 1; i < MAX_SCREENS; i++) - if (Players[i].alive && Players[i].spy) + if (Players[i].alive > 0 && Players[i].spy) changed |= RefreshBoard(i); if (changed) { if (!paused) ShowTime(); @@ -341,18 +353,19 @@ ExtFunc void OneGame(void) } //screen update playercount = 0; for (i = 1; i < MAX_SCREENS; i++) - if (Players[i].alive) playercount++; + if (Players[i].alive >= 0) playercount++; if (playercount < 1) goto gameOver; CheckNetConn(); switch (WaitMyEvent(&event, EM_any)) { case E_alarm: - if (!paused && Players[me].alive) + if (!paused && Players[me].alive > 0) if (!MovePiece(me, -1, 0)) goto nextPiece; else if (spied) SendPacket(me, NP_down, 0, NULL); break; case E_key: + Messagef("key: %d", event.u.key); p = strchr(keyTable, tolower(event.u.key)); key = p - keyTable; if (robotEnable) { @@ -363,7 +376,7 @@ ExtFunc void OneGame(void) } //let robot handle keypress if (!p) break; keyEvent: - if (!Players[me].alive && key != KT_quit) break; + if (Players[me].alive <= 0 && key != KT_quit) break; if (paused && key < KT_pause) break; switch(key) { case KT_left: @@ -429,7 +442,7 @@ ExtFunc void OneGame(void) InitFields(); // ScheduleFullRedraw(); for (i = 1; i < MAX_SCREENS; i++) - if (Players[i].alive && Players[i].spy) + if (Players[i].spy && Players[i].alive > 0) RefreshBoard(i); refresh(); break; @@ -513,7 +526,7 @@ ExtFunc void OneGame(void) netint2 data[2]; short column; - if (!Players[me].alive) break; + if (Players[me].alive <= 0) break; memcpy(data, event.u.net.data, sizeof(data[0])); column = Random(0, Players[me].boardWidth); data[1] = hton2(column); @@ -530,10 +543,32 @@ ExtFunc void OneGame(void) } //receive junklines case NP_start: { - Game.started = 1; - checkPaused(); + Game.started = 2; + paused = 0; + Messagef("The game has started"); + for (i = 1; i < MAX_SCREENS; i++) + if (Players[i].alive > 0) ShowPause(i); break; } //start game + case NP_stop: + { + if (Game.started > 1) + Messagef("The game has ended"); + Game.started = 0; + memcpy(&Game.seed, event.u.net.data, + event.u.net.size); + for (i = 1; i < MAX_SCREENS; i++) + if (Players[i].alive >= 0) { + Players[i].alive = 1; + Players[i].flags |= SCF_paused; + } //reset players + StartGame(); //reset everything + ShowTime(); //redraw timer while unpaused + checkPaused(); //pause + oldPaused = 0; //reset pause + changed = 1; + goto GameLoop; + } //stop game case NP_newPlayer: { if (event.u.net.uid > maxPlayer) @@ -541,10 +576,13 @@ ExtFunc void OneGame(void) memcpy(&Players[event.u.net.uid], event.u.net.data, event.u.net.size); ClearField(event.u.net.uid); - Messagef("\\%d%s joins the game", - Players[event.u.net.uid].team > 7 ? 7 - : Players[event.u.net.uid].team, - Players[event.u.net.uid].name); + if (Players[event.u.net.uid].team > 7) + Messagef("%s joined the game", + Players[event.u.net.uid].name); + else + Messagef("%s joined %s team", + Players[event.u.net.uid].name, + teams[Players[event.u.net.uid].team]); if (Players[event.u.net.uid].flags & SCF_paused) { checkPaused(); if (robotEnable) @@ -567,10 +605,8 @@ ExtFunc void OneGame(void) else strcpy(s, Players[event.u.net.uid].flags & SCF_paused - ? "is not ready" : "is good to go"); - Messagef("\\%d%s %s", - Players[event.u.net.uid].team > 7 ? 7 - : Players[event.u.net.uid].team, + ? "is not ready" : "is ready"); + Messagef("%s %s", Players[event.u.net.uid].name, s); checkPaused(); if (robotEnable) RobotCmd(1, "Pause %d\n", paused); @@ -578,12 +614,25 @@ ExtFunc void OneGame(void) changed = 1; break; } //(un)pause + case NP_part: + checkPaused(); + oldPaused = 0; + { + Players[event.u.net.uid].alive = -1; + Messagef("%s left", + Players[event.u.net.uid].name); + checkPaused(); + ShowPause(event.u.net.uid); + changed = 1; + break; + } //player left case NP_argghhh: { char i; memcpy(&i, event.u.net.data, sizeof(i)); Players[event.u.net.uid].alive = 0; - if (i == me) Messagef("You fragged %s", + if (i == me) Messagef("\\%dYou fragged %s", + Players[me].team > 7 ? 7 : Players[me].team, Players[event.u.net.uid].name); else if (i == event.u.net.uid) Messagef("\\%d%s died", @@ -647,7 +696,8 @@ ExtFunc void OneGame(void) junkLines = linesCleared - (linesCleared < 4); data[0] = hton2(junkLines); SendPacket(me, NP_giveJunk, sizeof(data), data); - Messagef("You sent %d lines", junkLines); + Messagef("\\%dYou sent %d lines", + Players[me].team > 7 ? 7 : Players[me].team, junkLines); } //send junk to others } //new piece loop gameOver: @@ -672,11 +722,13 @@ ExtFunc int main(int argc, char **argv) char *userName; for (i = 0; i < MAX_SCREENS; i++) { + Players[i].alive = -1; Players[i].score.level = Players[i].spy = 1; Players[i].boardWidth = 10; Players[i].boardHeight = MAX_BOARD_HEIGHT; Players[i].boardVisible = 20; strcpy(Players[i].name, "???"); + ClearField(i); } if (!(userName = getenv("LOGNAME")) || !userName[0]) if (!(userName = getenv("USER")) || !userName[0]) @@ -701,7 +753,6 @@ ExtFunc int main(int argc, char **argv) fatal("You can't use the -F option without the -r option"); // WriteConf(); - SRandom(time(0)); //randomize if (sigsetjmp(close_env, 1)) exit(0); signal(SIGINT, CatchInt); //handle exit (^C) @@ -717,6 +768,7 @@ ExtFunc int main(int argc, char **argv) } //client else { game = GT_onePlayer; + Game.seed = time(0); Game.started = 2; Game.maxplayers = 1; me = 1; diff --git a/inet.c b/inet.c index 2caca52..1549aa0 100644 --- a/inet.c +++ b/inet.c @@ -91,6 +91,12 @@ ExtFunc void HandShake(void) &Players[me]); break; } + case NP_team: + { //receive your teamnumber + memcpy(&Players[event.u.net.uid].team, event.u.net.data, + event.u.net.size); + break; + } //NP_team case NP_gamedata: { static struct { @@ -104,16 +110,16 @@ ExtFunc void HandShake(void) memcpy(&data, event.u.net.data, event.u.net.size); memcpy(&Players[me].flags, &data, sizeof(data.playerflags)); + memcpy(&Players[me].flags, &data, sizeof(data.playerflags)); memcpy(&Game, &data.maxplayers, sizeof(data) - sizeof(data.playerflags)); - SRandom(Game.seed); break; - } + } //NP_gamedata case NP_error: { fprintf(stderr, "Rejected by server: %s\n", event.u.net.data); exit(1); - } + } //NP_error default: break; } diff --git a/netris.h b/netris.h index 7bbfc3c..a361c2f 100644 --- a/netris.h +++ b/netris.h @@ -28,7 +28,7 @@ #include #include -#define version_string "0.7.819" +#define version_string "0.7.821" #define ExtFunc /* Marks functions that need prototypes */ @@ -106,7 +106,9 @@ typedef enum _NetPacketType { NP_pause, //player (un)pauses NP_stop, //game ended NP_newPlayer, //add new player + NP_team, //player switched teams NP_argghhh, //player died + NP_part, //player left NP_newPiece, //new piece info NP_rotright, //rotate piece clockwise diff --git a/server.c b/server.c index f67721f..6fe46f0 100644 --- a/server.c +++ b/server.c @@ -49,7 +49,7 @@ static struct option options[] = { }; static char minplayers = 2; -static char countPlayers = 0; +static char playercount; static char verbose = 0; struct sockaddr_in addr; @@ -166,8 +166,10 @@ ExtFunc void SCloseNet(short playa) MyEvent event; if (netGen[playa].fd >= 0) { - SendPacketTo(playa, 0, NP_endConn, 0, NULL); - do{} while (WaitMyEvent(&event, EM_net) != E_lostConn); + if (Players[playa].alive >= 0) { + SendPacketTo(playa, 0, NP_endConn, 0, NULL); + do{} while (WaitMyEvent(&event, EM_net) != E_lostConn); + } //say bye to player close(netGen[playa].fd); netGen[playa].fd = -1; } @@ -313,22 +315,38 @@ static MyEventType ConnGenFunc(EventGenRec *gen, MyEvent *event) return E_connect; } //ConnGenFunc +ExtFunc void CountPlayers(void) +{ //count number of players/teams + int i, j; + playercount = 0; + for (i = 1; i < MAX_SCREENS; i++) if (Players[i].alive > 0) { + if (Players[i].team < 128) for (j = 1; j < i; j++) + if (Players[j].alive > 0 && (Players[j].team == Players[i].team)) { + playercount--; + break; + } //player of same team counted before + playercount++; + } //player alive +} //CountPlayers + ExtFunc int StartServer(void) { MyEvent event; netint2 currentpiece[MAX_SCREENS]; - int playercount; int playersReady = 0; + int paused = 1; int i; + char teams[10][7] = { "", "Green", "Cyan", "Blue", "Purple", + "Red", "Grey", "White", "*Orange" }; do { switch (WaitMyEvent(&event, EM_any)) { case E_lostConn: //client went away :( - Players[event.u.net.sender].alive = 0; + Players[event.u.net.sender].alive = -1; for (i = 1; i < MAX_SCREENS; i++) - if (Players[i].alive) + if (Players[i].alive >= 0) SendPacketTo(i, event.u.net.sender, - NP_argghhh, sizeof(Players[0].alive), + NP_part, sizeof(Players[0].alive), &Players[event.u.net.sender].alive); SCloseNet(event.u.net.sender); break; //NP_endConn @@ -366,14 +384,20 @@ ExtFunc int StartServer(void) //receive player details and return other players memcpy(&Players[event.u.net.sender], event.u.net.data, event.u.net.size); - if (!Players[event.u.net.sender].team) + if (Players[event.u.net.sender].team < 1 + || Players[event.u.net.sender].team > 7) { Players[event.u.net.sender].team = - 256 - event.u.net.sender; + event.u.net.sender % 7 + 1; + SendPacketTo(event.u.net.sender, + event.u.net.sender, NP_team, + sizeof(Players[event.u.net.sender].team), + &Players[event.u.net.sender].team); + } //invalid team if (Game.started < 2) Players[event.u.net.sender].flags |= SCF_paused; if (!Game.continuous && Game.started >= 2) { char data[40]; - strcpy(data,"Can't join: Game has already started"); + strcpy(data, "Can't join: Game has already started"); fprintf(stderr, "- Can't join player #%d in " "non-continuous game\n", event.u.net.sender); SendPacketTo(event.u.net.sender, 0, NP_error, @@ -414,21 +438,22 @@ ExtFunc int StartServer(void) - sizeof(Players[0].small), &Players[event.u.net.sender]); } //send (to) players - fprintf(stderr, "> Joined player #%d: %s <%s>\n", + fprintf(stderr, "> Joined player #%d: %s <%s> (%s)\n", event.u.net.sender, Players[event.u.net.sender].name, - Players[event.u.net.sender].host); + Players[event.u.net.sender].host, + teams[Players[event.u.net.sender].team]); if (++playersReady >= minplayers) { - if (Game.started) + if (Game.started > 1) SendPacketTo(event.u.net.sender, 0, NP_start, 0, NULL); - else { +/* else { fprintf(stderr, "* Starting game (%010d)\n", Game.seed); for (i = 1; i < MAX_SCREENS; i++) SendPacketTo(i, 0, NP_start, 0, NULL); Game.started++; - } //first goahead (to all) + } //first goahead (to all)*/ } //give go ahead break; //NP_playerdata case NP_newPiece: @@ -442,18 +467,22 @@ ExtFunc int StartServer(void) //check for unpaused game case NP_pause: { - int paused; Players[event.u.net.sender].flags ^= SCF_paused; paused = Game.started < 1; - for (i = 1; i < MAX_SCREENS; i++) if (Players[i].alive) - paused |= Players[i].flags & SCF_paused; + for (i = 1; i < MAX_SCREENS; i++) + if (Players[i].alive > 0) + paused |= Players[i].flags & SCF_paused; + fprintf(stderr, "* Player #%d (un)paused (pause=%d)\n", + event.u.net.sender, paused); if (paused) paused = 1; - else if (Game.started == 1) Game.started++; goto sendtoall; } //NP_pause default: //relay data to all players sendtoall: // if (event.u.net.type >= NP_pause) + if (event.u.net.type >= NP_rotright + && Game.started < 2) + break; for (i = 1; i < MAX_SCREENS; i++) if (i != event.u.net.sender) if (event.u.net.type != NP_giveJunk || @@ -474,20 +503,36 @@ ExtFunc int StartServer(void) break; } //E_connect } //event - { - int j; - playercount = 0; - for (i = 1; i < MAX_SCREENS; i++) if (Players[i].alive) { - if (Players[i].team < 128) for (j = 1; j < i; j++) - if (Players[j].alive - && (Players[j].team == Players[i].team)) { - playercount--; - break; - } //player of same team counted before - playercount++; - } //player alive - } //count players - } while (Game.started < 2 || playercount > 1 || Game.continuous); + CountPlayers(); + if (Game.started < 1) { + if (playercount > 1) { + fprintf(stderr, "* Game (%010d) ready to start\n", Game.seed); + Game.started++; + } //give goahead + } //game not yet started + else { + if (playercount < 2) { + fprintf(stderr, "* Stopping game\n"); + if (Game.seed) Game.seed++; + if (Game.started > 1) for (i = 1; i < MAX_SCREENS; i++) + if (Players[i].alive >= 0) { + Players[i].alive = 1; + Players[i].flags |= SCF_paused; + SendPacketTo(i, 0, NP_stop, + sizeof(Game.seed), &Game.seed); + } //transmit game stop and set players not ready + paused = 1; + Game.started = 0; + } //too few players for game + if (Game.started == 1 && !paused) { + Game.started++; + fprintf(stderr, "* Game starts\n"); + for (i = 1; i < MAX_SCREENS; i++) + if (Players[i].alive > 0) + SendPacketTo(i, 0, NP_start, 0, NULL); + } //everybody ready to start + } //game (ready to) start(ed) + } while (1); fprintf(stderr, "* Exiting server\n"); } //StartServer @@ -639,6 +684,12 @@ ExtFunc int main(int argc, char **argv) Game.maxplayers = 8; Game.initspeed = DEFAULT_INTERVAL; Game.seed = time(0); + { + int i; + + for (i = 1; i < MAX_SCREENS; i++) + Players[i].alive = -1; + } // if (getopt(argc, argv, "f:") == 'f') // ReadConf(optarg);