unofficial version 0.7.2: mainly sync/reset fixes
[netris.git] / game.c
diff --git a/game.c b/game.c
index b88e05d2f789199bbf24cad58cd98a3c19453220..de0d605cfcdd0ee12648629d3548e1bd3c7224fc 100644 (file)
--- 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;