X-Git-Url: http://git.shiar.nl/netris.git/blobdiff_plain/45dc9d995860486f1758dcf79fd2d8cd8dfb210a..0e779d807aa1830dde2f4a75117fd16f5627dc76:/game.c diff --git a/game.c b/game.c index de0d605..6ad7e8b 100644 --- a/game.c +++ b/game.c @@ -21,24 +21,28 @@ #define NOEXT #include "netris.h" + #include #include #include #include #include -#include + +#include "client.h" +#include "util.h" +#include "board.h" +#include "curses.h" +#include "inet.h" +#include "msg.en.h" static struct option options[] = { { "ascii", 2, 0, 'a' }, { "connect", 1, 0, 'c' }, { "port", 1, 0, 'p' }, { "level", 1, 0, 'l' }, + { "nick", 1, 0, 'n' }, { "team", 1, 0, 't' }, - { "spy", 1, 0, 1 }, - { "robot", 1, 0, 'r' }, - { "fair-robot", 0, 0, 'F' }, { "dropmode", 2, 0, 'd' }, - { "instadrop", 2, 0, 'D' }, { "color", 2, 0, 'C' }, { "slowterm", 2, 0, 'S' }, { "keys", 1, 0, 'k' }, @@ -55,7 +59,7 @@ static char *keyNames[KT_numKeys+1] = { "Left", "Right", "RotRight", "RotLeft", "Drop", "Down", "Faster", "Pause", "Redraw", "Quit", NULL }; -static char *gameNames[GT_len] = { "OnePlayer", "ClassicTwo" }; +_Sets Sets = {7, 0, 1, 1, 1}; //Sets static char keyTable[KT_numKeys+1]; @@ -63,14 +67,13 @@ static char *hostStr; static int paused = 0; static char lastadd; -static sigjmp_buf close_env; - -ExtFunc void MapKeys(char *newKeys) +void MapKeys(char *newKeys) { int i, k, ch; char used[256]; int errs = 0; + char scratch[6]; /* XXX assumptions about ASCII encoding here */ for (i = k = 0; newKeys[i] && k < KT_numKeys; i++,k++) { @@ -101,7 +104,7 @@ ExtFunc void MapKeys(char *newKeys) exit(1); } //MapKeys -ExtFunc void WriteConf(void) +void WriteConf(void) { FILE *file_out; @@ -115,15 +118,15 @@ ExtFunc void WriteConf(void) fprintf(stderr, "Wrote new game configuration to %s\n", CONFIG_FILE); } //WriteConf -ExtFunc void HandleOption(char tag, char *value) +void HandleOption(char tag, char *value) { switch (tag) { case 'a': //ascii - if (value && !strcasecmp(value, "0")) Game.ascii = 0; - else Game.ascii = 1; + if (value && !strcasecmp(value, "0")) Sets.ascii = 0; + else Sets.ascii = 1; break; case 'c': //connect - initConn = 1; + game = GT_classicTwo; hostStr = value; break; case 'p': //port @@ -138,40 +141,22 @@ ExtFunc void HandleOption(char tag, char *value) if (Players[0].score.level > 15) Players[0].score.level = 15; break; + case 'n': //nick + memcpy(Players[0].name, value, strlen(value) + 1); + break; case 't': //team Players[0].team = atoi(value); break; - case 1: //spy - { - int i; - i = atof(value); - Players[i / 10].spy = i % 10; - } - break; - case 'r': //robot - robotEnable = 1; - Players[0].flags |= SCF_usingRobot; - InitRobot(value); - break; - case 'F': //fair robot - fairRobot = 1; - Players[0].flags |= SCF_fairRobot; - break; - case 'd': //drop mode - if (value && !strcasecmp(value, "0")) Players[0].dropmode &= 254; - else Players[0].dropmode |= 1; - break; - case 'D': //instadrop - if (value && !strcasecmp(value, "0")) Players[0].dropmode &= 253; - else Players[0].dropmode |= 2; + case 'd': //dropmode + Sets.dropmode = atoi(value); break; case 'C': //color - if (value && !strcasecmp(value, "1")) Game.color = 1; - else Game.color = 0; + if (value && !strcasecmp(value, "1")) Sets.color = 1; + else Sets.color = 0; break; case 'S': //slowterm - if (value && !strcasecmp(value, "1")) Game.standout = 1; - else Game.standout = 0; + if (value && !strcasecmp(value, "1")) Sets.standout = 1; + else Sets.standout = 0; break; case 'k': //keys MapKeys(value); break; @@ -186,7 +171,7 @@ ExtFunc void HandleOption(char tag, char *value) } } //HandleParam -ExtFunc void ReadConf(char *filename) +void ReadConf(char *filename) { FILE *file_in; char buf[513]; @@ -220,16 +205,15 @@ ExtFunc void ReadConf(char *filename) } //ReadConf -ExtFunc int StartNewPiece(int scr, Shape *shape) +int StartNewPiece(int scr, char shape) { - if (Players[scr].nextShape) { + Players[scr].score.pieces++; + { Players[scr].curShape = Players[scr].nextShape; Players[scr].nextShape = shape; } - else - Players[scr].curShape = shape; Players[scr].curY = Players[scr].boardVisible + 4; - Players[scr].curX = Players[scr].boardWidth / 2; + Players[scr].curX = Players[scr].boardWidth / 2 - 2; while (!ShapeVisible(Players[scr].curShape, scr, Players[scr].curY, Players[scr].curX)) Players[scr].curY--; @@ -237,11 +221,11 @@ ExtFunc int StartNewPiece(int scr, Shape *shape) Players[scr].curY, Players[scr].curX)) return 0; PlotShape(Players[scr].curShape, scr, - Players[scr].curY, Players[scr].curX, 1, 1); + Players[scr].curY, Players[scr].curX, scr == me); return 1; } -ExtFunc void checkPaused(void) +void checkPaused(void) { //check whether anyone paused the game int i; @@ -251,11 +235,11 @@ ExtFunc void checkPaused(void) if (paused) paused = 1; } //checkPaused -ExtFunc void StartGame(void) +void StartGame(void) { //init new game int i; - maxPlayer = lastadd = me; + lastadd = me; SRandom(Game.seed); Game.speed = Game.initspeed; for (i = 1; i < Players[me].score.level; i++) @@ -263,64 +247,384 @@ ExtFunc void StartGame(void) 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; + for (i = 1; i <= maxPlayer; i++) { + Players[i].score.score = Players[i].score.lines + = Players[i].score.adds = 0; + Players[i].score.pieces = -1; ClearField(i); - DrawField(i); } //reset all players + InitFields(); } //StartGame -ExtFunc void OneGame(void) +void CheckClears(int scr) +{ //check for full lines + int linesCleared; + int linevalues[] = { 40, 100, 400, 1200, }; //= 50*lines! - 10*(lines==1) +// int linevaluesq[] = { 25, 50, 100, 200, 500, 720, 980, 1280, 1620, 2000, +// 2420, 2880, 3380, 3920, 4500, 5120, 5780, 6480 }; + int linevaluesq[] = { 20, 50, 100, 200, 500, 750, 1000, 1250, 1500, 2000, + 2500, 3000, 3500, 4000, 4500, 5000, 6000, 7500 }; + + if ((linesCleared = ClearFullLines(scr)) > 0) { + if (game == GT_onePlayer) + if ((Players[scr].score.lines / 10) < + ((Players[scr].score.lines+linesCleared)/10)) { + if ((Game.speed /= SPEEDINC) < SPEEDMINIMUM) + Game.speed = SPEEDMINIMUM; + SetITimer(Game.speed, SetITimer(0, 0)); + Players[scr].score.level++; + } //level up + Players[scr].score.score += Game.gravity + ? linevaluesq[linesCleared - 1] : linevalues[linesCleared - 1]; + Players[scr].score.lines += linesCleared; + Players[scr].score.adds += linesCleared - (linesCleared < 4); + if (scr == me) { + if (game == GT_classicTwo) { + SendPacket(scr, NP_clear, 0, NULL); + if (linesCleared > 1) { + short junkLines; + netint4 data[1]; + + if (Game.gravity) junkLines = linesCleared - 1; + else junkLines = linesCleared - (linesCleared < 4); + data[0] = junkLines; + SendPacket(me, NP_giveJunk, sizeof(data), data); + Message("\\%dYou send %d lines", + Players[me].team > 7 ? 7 : Players[me].team, junkLines); + } //send junk to others + } //multiplayer + else { + Message("\\%dYou cleared %d lines", + Players[me].team > 7 ? 7 : Players[me].team, linesCleared); + } //singleplayer + } //IT'S YOU + } //lines cleared +} //CheckClears + +void OneGame(void) { - MyEvent event; - int linesCleared, changed = 0; + int changed = 0; + short gameStatus = 2; //2=loop; 1=new piece; 0=quit int dropMode = 0; + int chatMode = 0; + char chatText[MSG_WIDTH] = "\0"; + + void GameKey(char key) + { + char *p; + + if (key == 13) { + if (!(chatMode = !chatMode)) { + if (chatText[0]) { + Message("<\\%d%s\\7> %s", + Players[me].team > 7 ? 7 : Players[me].team, + Players[me].name, chatText); + if (game==GT_classicTwo) + SendPacket(me, NP_msg, strlen(chatText) + 1, chatText); + memset(chatText, 0, sizeof(chatText)); + } //say it + else Messagetype(27, -1, NULL); //escape + return; + } //leave chat mode + } //enter pressed (start/stop chat mode) + if (chatMode) { + if (key == 27) //escape + chatMode = 0; + else if (key == 127 && chatText) //backspace + chatText[strlen(chatText) - 1] = 0; + else if (key != 13 && strlen(chatText) < MSG_WIDTH-1) //text + chatText[strlen(chatText)] = key; + Messagetype(key, strlen(chatText) - 1, chatText); + return; + } //key in chat mode + if (!(p = strchr(keyTable, tolower(key)))) return; + key = p - keyTable; + if (Players[me].alive <= 0 && key != KT_quit) return; + if (paused && key < KT_pause) return; + switch (key) { + case KT_left: + if (MovePiece(me, 0, -1) && spied) SendPacket(me, NP_left, 0, NULL); + break; + case KT_right: + if (MovePiece(me, 0, 1) && spied) SendPacket(me, NP_right, 0, NULL); + break; + case KT_rotleft: + if (RotatePiece(me, -1) && spied) SendPacket(me, NP_rotleft, 0, NULL); + break; + case KT_rotright: + if (RotatePiece(me, 1) && spied) SendPacket(me, NP_rotright, 0, NULL); + break; + case KT_down: + SetITimer(Game.speed, Game.speed); + if (MovePiece(me, -1, 0)) { + if (spied) SendPacket(me, NP_down, 0, NULL); + } //move one down + else + gameStatus = 1; //completely dropped + break; + case KT_drop: + SetITimer(Game.speed, Game.speed); + if (DropPiece(me)) { + if (spied) SendPacket(me, NP_drop, 0, NULL); + if (!Sets.dropmode) gameStatus = 1; //instadrop + } + else gameStatus = 1; //dropped + dropMode = Sets.dropmode>1; + break; + case KT_faster: + if (game != GT_onePlayer) break; + if ((Game.speed /= SPEEDINC) < SPEEDMINIMUM) + Game.speed = SPEEDMINIMUM; + SetITimer(Game.speed, SetITimer(0, 0)); + Players[me].score.level++; + ShowScore(me, Players[me].score); + changed = 1; + break; + case KT_pause: + Players[me].flags ^= SCF_paused; + if (Game.started > 1) + Message(Players[me].flags & SCF_paused + ? "You paused the game" : "You unpaused the game"); + else + Message(Players[me].flags & SCF_paused + ? "You are not ready" : "You are ready"); + checkPaused(); + if (game == GT_classicTwo) + SendPacket(me, NP_pause, 0, NULL); + ShowPause(me); + changed = 1; + break; + case KT_redraw: + clear(); + InitFields(); +// ScheduleFullRedraw(); + refresh(); + break; + case KT_quit: + ShowPause(me); + refresh(); + gameStatus = 0; + break; + } //E_key + if (dropMode && DropPiece(me) > 0) { + SetITimer(Game.speed, Game.speed); + if (spied) SendPacket(me, NP_drop, 0, NULL); + } + return; + } //GameKey + int oldPaused = 0; + + void GameNet(_netEvent net) + { + switch(net.type) { + case NP_newPiece: + { + FreezePiece(net.uid); + memcpy(&Players[net.uid].nextShape, net.data, + sizeof(Players[0].nextShape)); + StartNewPiece(net.uid, Players[net.uid].curShape); + break; + } + case NP_down: + MovePiece(net.uid, -1, 0); + break; + case NP_left: + MovePiece(net.uid, 0, -1); + break; + case NP_right: + MovePiece(net.uid, 0, 1); + break; + case NP_rotleft: + RotatePiece(net.uid, -1); + break; + case NP_rotright: + RotatePiece(net.uid, 1); + break; + case NP_drop: + DropPiece(net.uid); + break; + case NP_clear: + CheckClears(net.uid); + break; + case NP_insertJunk: + { + netint4 data[3]; + + memcpy(data, net.data, sizeof(data)); + InsertJunk(net.uid, Players[data[2]].team, data[0], data[1]); + break; + } //player added junklines + case NP_giveJunk: + { + netint4 data[3]; + short column; + + if (Players[me].alive<=0) break; + memcpy(data, net.data, sizeof(data[0])); + column = Random(0, Players[me].boardWidth); + Message("\\%d%s sends %d lines", + Players[net.uid].team>7 ? 7 : Players[net.uid].team, + Players[net.uid].name, data[0]); + lastadd = net.uid; + InsertJunk(me, Players[net.uid].team, data[0], column); + if (spied) { + data[1] = column; + data[2] = net.uid; + SendPacket(me, NP_insertJunk, sizeof(data), data); + } //show changes to others + break; + } //receive junklines + case NP_msg: + { + Message("<\\%d%s\\7> %s", + Players[net.uid].team>7 ? 7 : Players[net.uid].team, + Players[net.uid].name, net.data, net.type); + break; + } //chat + case NP_start: + { + int i; + + Game.started = 2; + paused = 0; + Message("The game has started"); + for (i = 1; i0) + ShowPause(i); + break; + } //start game + case NP_stop: + { + if (Game.started>1) { + int winner; + float timer; + int i; + + Message("The game has ended"); + timer = CurTimeval()/1e6; + if (timer>5) { + for (i = MAX_SCREENS-1; i>0; i--) if (Players[i].alive>=0) { + Message("\\%d%10s%6.1fp%5.1fa", + Players[i].team>7 ? 7 : Players[i].team, Players[i].name, + Players[i].score.pieces/timer*60, + Players[i].score.adds/timer*60); + if (Players[i].alive>0) winner = i; + } //show player stats + if (winner) + Message("%s won after %0.0f'%02d\"", + Players[winner].name, timer/60, (int)timer%60); + } //show game stats + Message(NULL); + } //game was playing + Game.started = 0; + memcpy(&Game.seed, net.data, net.size); + { + int i; + + for (i = 1; i=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; + gameStatus = 1; + break; + } //stop game + case NP_newPlayer: + { + char teams[10][7] = { "", "Green", "Cyan", "Blue", "Purple", + "Red", "Grey", "White", "*Orange" }; + + if (net.uid>maxPlayer) maxPlayer = net.uid; + memcpy(&Players[net.uid], net.data, net.size); + ClearField(net.uid); + InitFields(); + if (Players[net.uid].team>7) + Message("%s joined the game", Players[net.uid].name); + else + Message("%s joined %s team", Players[net.uid].name, + teams[Players[net.uid].team]); + if (Players[net.uid].flags&SCF_paused) { + checkPaused(); + } //player has paused +// DrawField(net.uid); +// ShowPause(net.uid); + changed = 1; + break; + } //player joined + case NP_pause: + { + char s[20]; + + Players[net.uid].flags ^= SCF_paused; + if (Game.started>1) + strcpy(s, Players[net.uid].flags&SCF_paused + ? "paused the game" : "unpaused the game"); + else + strcpy(s, Players[net.uid].flags&SCF_paused + ? "is not ready" : "is ready"); + Message("%s %s", Players[net.uid].name, s); + checkPaused(); + ShowPause(net.uid); + changed = 1; + break; + } //(un)pause + case NP_part: + checkPaused(); + oldPaused = 0; + { + Players[net.uid].alive = -1; + Message("%s left", Players[net.uid].name); + checkPaused(); + ShowPause(net.uid); + changed = 1; + break; + } //player left + case NP_argghhh: + { + char i; + memcpy(&i, net.data, sizeof(i)); + Players[net.uid].alive = 0; + if (i == me) Message("\\%dYou fragged %s", + Players[me].team>7 ? 7 : Players[me].team, Players[net.uid].name); + else if (i==net.uid) + Message("\\%d%s died", + Players[i].team>7 ? 7 : Players[i].team, Players[i].name); + else + Message("\\%d%s fragged %s", + Players[i].team>7 ? 7 : Players[i].team, Players[i].name, + Players[net.uid].name); + checkPaused(); + ShowPause(net.uid); + changed = 1; + break; + } //G/O + default: + break; + } //E_net + } //GameNet + + MyEvent event; long pauseTimeLeft; - int pieceCount = 0; - int key; - char *p, *cmd; - int playercount; - 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; 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 >= 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(); - } - while (1) { + while (gameStatus) { GameLoop: + gameStatus = 2; if (Players[me].alive > 0) { if (!StartNewPiece(me, ChooseOption(stdOptions))) { netint4 data[4]; Players[me].alive = 0; - if (lastadd == me) Messagef("\\%dYou died", + if (lastadd == me) Message("\\%dYou died", Players[me].team > 7 ? 7 : Players[me].team); - else Messagef("\\%d%s fragged you", + else Message("\\%d%s fragged you", Players[lastadd].team > 7 ? 7 : Players[lastadd].team, Players[lastadd].name); if (game == GT_classicTwo) @@ -330,332 +634,42 @@ GameLoop: } //die else { ShowScore(me, Players[me].score); - if (robotEnable && !fairRobot) - RobotCmd(1, "NewPiece %d\n", ++pieceCount); if (spied) { - short shapeNum; - netint2 data[1]; - - shapeNum = ShapeToNetNum(Players[me].curShape); - data[0] = hton2(shapeNum); - SendPacket(me, NP_newPiece, sizeof(data), data); + SendPacket(me, NP_newPiece, sizeof(Players[me].curShape), &Players[me].curShape); } //send new piece } } //new piece - while (1) { + while (gameStatus == 2) { for (i = 1; i < MAX_SCREENS; i++) - if (Players[i].alive > 0 && Players[i].spy) + if (Players[i].alive > 0 && PlayerDisp[i]) changed |= RefreshBoard(i); if (changed) { if (!paused) ShowTime(); refresh(); changed = 0; } //screen update - playercount = 0; + { + short playercount = 0; for (i = 1; i < MAX_SCREENS; i++) if (Players[i].alive >= 0) playercount++; - if (playercount < 1) goto gameOver; - CheckNetConn(); + if (playercount < 1) gameStatus = 0; + } switch (WaitMyEvent(&event, EM_any)) { case E_alarm: if (!paused && Players[me].alive > 0) - if (!MovePiece(me, -1, 0)) - goto nextPiece; - else if (spied) - SendPacket(me, NP_down, 0, NULL); + if (!MovePiece(me, -1, 0)) //move down + gameStatus = 1; //new piece + 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) { - RobotCmd(1, "UserKey %d %s\n", - (int)(unsigned char)event.u.key, - p ? keyNames[key] : "?"); - break; - } //let robot handle keypress - if (!p) break; - keyEvent: - if (Players[me].alive <= 0 && key != KT_quit) break; - if (paused && key < KT_pause) break; - switch(key) { - case KT_left: - if (MovePiece(me, 0, -1) && spied) - SendPacket(me, NP_left, 0, NULL); - break; - case KT_right: - if (MovePiece(me, 0, 1) && spied) - SendPacket(me, NP_right, 0, NULL); - break; - case KT_rotleft: - if (RotatePiece(me, 0) && spied) - SendPacket(me, NP_rotleft, 0, NULL); - break; - case KT_rotright: - if (RotatePiece(me, 1) && spied) - SendPacket(me, NP_rotright, 0, NULL); - break; - case KT_down: - SetITimer(Game.speed, Game.speed); - if (MovePiece(me, -1, 0)) { - if (spied) SendPacket(me, NP_down, 0, NULL); - } - else goto nextPiece; - break; - case KT_drop: - SetITimer(Game.speed, Game.speed); - if (DropPiece(me)) { - if (spied) SendPacket(me, NP_drop, 0, NULL); - if (Players[me].dropmode == 2) goto nextPiece; - } - else goto nextPiece; - dropMode = Players[me].dropmode; - break; - case KT_faster: - if (game != GT_onePlayer) - break; - if ((Game.speed /= SPEEDINC) < SPEEDMINIMUM) - Game.speed = SPEEDMINIMUM; - SetITimer(Game.speed, SetITimer(0, 0)); - Players[me].score.level++; - ShowScore(me, Players[me].score); - changed = 1; - break; - case KT_pause: - Players[me].flags ^= SCF_paused; - if (Game.started > 1) - Messagef(Players[me].flags & SCF_paused - ? "You paused the game" - : "You unpaused the game"); - else - Messagef(Players[me].flags & SCF_paused - ? "You are not ready" : "You are ready"); - checkPaused(); - if (game == GT_classicTwo) - SendPacket(me, NP_pause, 0, NULL); - if (robotEnable) RobotCmd(1, "Pause %d\n", paused); - ShowPause(me); - changed = 1; - break; - case KT_redraw: - DrawTitle(); - InitFields(); -// ScheduleFullRedraw(); - for (i = 1; i < MAX_SCREENS; i++) - if (Players[i].spy && Players[i].alive > 0) - RefreshBoard(i); - refresh(); - break; - case KT_quit: - ShowPause(me); - refresh(); - goto gameOver; - } //E_key - if (dropMode && DropPiece(me) > 0) { - SetITimer(Game.speed, Game.speed); - if (spied) - SendPacket(me, NP_drop, 0, NULL); - } + GameKey(event.u.key); break; - case E_robot: - { - int num; - - cmd = event.u.robot.data; - if ((p = strchr(cmd, ' '))) - *p++ = 0; - else - p = cmd + strlen(cmd); - for (key = 0; keyNames[key]; ++key) - if (!strcmp(keyNames[key], cmd) && - (fairRobot || (1 == sscanf(p, "%d", &num) && - num == pieceCount))) - goto keyEvent; - if (!strcmp(cmd, "Message")) { - Messagef(p); - changed = 1; - } - break; - } //E_robot case E_net: - switch(event.u.net.type) { - case NP_newPiece: - { - short shapeNum; - netint2 data[1]; - - FreezePiece(event.u.net.uid); - memcpy(data, event.u.net.data, sizeof(data)); - shapeNum = ntoh2(data[0]); - StartNewPiece(event.u.net.uid, - NetNumToShape(shapeNum)); - break; - } //new piece - case NP_down: - MovePiece(event.u.net.uid, -1, 0); - break; - case NP_left: - MovePiece(event.u.net.uid, 0, -1); - break; - case NP_right: - MovePiece(event.u.net.uid, 0, 1); - break; - case NP_rotleft: - RotatePiece(event.u.net.uid, 0); - break; - case NP_rotright: - RotatePiece(event.u.net.uid, 1); - break; - case NP_drop: - DropPiece(event.u.net.uid); - break; - case NP_clear: - ClearFullLines(event.u.net.uid); - break; - case NP_insertJunk: - { - netint2 data[2]; - - memcpy(data, event.u.net.data, sizeof(data)); - InsertJunk(event.u.net.uid, ntoh2(data[0]), - ntoh2(data[1])); - break; - } //player added junklines - case NP_giveJunk: - { - netint2 data[2]; - short column; - - 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); - Messagef("\\%d%s sends %d lines", - Players[event.u.net.uid].team > 7 ? 7 - : Players[event.u.net.uid].team, - Players[event.u.net.uid].name, ntoh2(data[0])); - lastadd = event.u.net.uid; - InsertJunk(me, ntoh2(data[0]), column); - if (spied) - SendPacket(me, NP_insertJunk, sizeof(data), - data); - break; - } //receive junklines - case NP_start: - { - 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) - maxPlayer = event.u.net.uid; - memcpy(&Players[event.u.net.uid], - event.u.net.data, event.u.net.size); - ClearField(event.u.net.uid); - 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) - RobotCmd(1, "Pause %d\n", paused); - } //player has paused - DrawField(event.u.net.uid); -// ShowPause(event.u.net.uid); - changed = 1; - break; - } //player joined - case NP_pause: - { - char s[20]; - - Players[event.u.net.uid].flags ^= SCF_paused; - if (Game.started > 1) - strcpy(s, - Players[event.u.net.uid].flags & SCF_paused - ? "paused the game" : "unpaused the game"); - else - strcpy(s, - Players[event.u.net.uid].flags & SCF_paused - ? "is not ready" : "is ready"); - Messagef("%s %s", - Players[event.u.net.uid].name, s); - checkPaused(); - if (robotEnable) RobotCmd(1, "Pause %d\n", paused); - ShowPause(event.u.net.uid); - 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("\\%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", - Players[i].team > 7 ? 7 : Players[i].team, - Players[i].name); - else Messagef("\\%d%s fragged %s", - Players[i].team > 7 ? 7 : Players[i].team, - Players[i].name, - Players[event.u.net.uid].name); - checkPaused(); - ShowPause(event.u.net.uid); - changed = 1; - break; - } //G/O - default: - break; - } //E_net + GameNet(event.u.net); break; - case E_lostRobot: case E_lostConn: goto gameOver; - default: - break; } //handle event if (paused != oldPaused) { if (paused) { @@ -669,53 +683,23 @@ GameLoop: oldPaused = paused; } //(un)pause } //game loop - nextPiece: dropMode = 0; - FreezePiece(me); - Players[me].score.drops++; Players[me].score.score++; - if ((linesCleared = ClearFullLines(me)) > 0) { - if (game == GT_onePlayer) - if ((Players[me].score.lines / 10) < - ((Players[me].score.lines + linesCleared) / 10)) { - if ((Game.speed /= SPEEDINC) < SPEEDMINIMUM) - Game.speed = SPEEDMINIMUM; - SetITimer(Game.speed, SetITimer(0, 0)); - Players[me].score.level++; - } //level up - Players[me].score.score += linevalues[linesCleared - 1]; - Players[me].score.lines += linesCleared; - Players[me].score.adds += linesCleared - (linesCleared < 4); - if (spied) - SendPacket(me, NP_clear, 0, NULL); - } - if (game == GT_classicTwo && linesCleared > 1) { - short junkLines; - netint2 data[1]; - - junkLines = linesCleared - (linesCleared < 4); - data[0] = hton2(junkLines); - SendPacket(me, NP_giveJunk, sizeof(data), data); - Messagef("\\%dYou sent %d lines", - Players[me].team > 7 ? 7 : Players[me].team, junkLines); - } //send junk to others + CheckClears(me); } //new piece loop gameOver: SetITimer(0, 0); } -ExtFunc void CatchInt(int sig) -{ - siglongjmp(close_env, 1); -} - -ExtFunc int main(int argc, char **argv) +int main(int argc, char **argv) { char ch; + game = GT_onePlayer; port = DEFAULT_PORT; - Game.standout = Game.color = 1; + maxPlayer = 1; Game.initspeed = DEFAULT_INTERVAL; + Game.gravity = 0; MapKeys(DEFAULT_KEYS); { int i; @@ -723,7 +707,7 @@ ExtFunc int main(int argc, char **argv) for (i = 0; i < MAX_SCREENS; i++) { Players[i].alive = -1; - Players[i].score.level = Players[i].spy = 1; + Players[i].score.level = 1; Players[i].boardWidth = 10; Players[i].boardHeight = MAX_BOARD_HEIGHT; Players[i].boardVisible = 20; @@ -736,6 +720,7 @@ ExtFunc int main(int argc, char **argv) strncpy(Players[0].name, userName, 16); //sizeof(Player.name) Players[0].name[16] = 0; Players[0].alive = 1; + Players[0].dropmode = 0; } //set defaults // if (getopt(argc, argv, "f:") == 'f') @@ -743,36 +728,29 @@ ExtFunc int main(int argc, char **argv) // else ReadConf(CONFIG_FILE); while ((ch = getopt_long(argc, argv, - "hHRr:Fk:c:odDSCap:i:l:t:", options, NULL)) != -1) + "hHRk:c:n:odDSCap:i:l:t:", options, NULL)) != -1) HandleOption(ch, optarg); if (optind < argc) { Usage(); exit(1); } - if (fairRobot && !robotEnable) - fatal("You can't use the -F option without the -r option"); // WriteConf(); - if (sigsetjmp(close_env, 1)) - exit(0); - signal(SIGINT, CatchInt); //handle exit (^C) InitScreens(); //setup screen - DrawTitle(); - if (initConn) { - game = GT_classicTwo; + if (game == GT_classicTwo) { spied = 1; InitiateConnection(hostStr, port); HandShake(); + maxPlayer = me; checkPaused(); OneGame(); } //client else { - game = GT_onePlayer; Game.seed = time(0); Game.started = 2; - Game.maxplayers = 1; me = 1; - memcpy(&Players[me], &Players[0], sizeof(Player)); + memcpy(&Players[me], &Players[0], sizeof(_Player)); + Players[me].team = 7; OneGame(); } //singleplay return 0;