home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1996 May / PCOnline_05_1996.bin / linux / source / y / bsdgames / bsd-game.000 / bsd-game / games / hunt / answer.c next >
Encoding:
C/C++ Source or Header  |  1993-09-21  |  8.2 KB  |  396 lines

  1. /*
  2.  *  Hunt
  3.  *  Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
  4.  *  San Francisco, California
  5.  */
  6.  
  7. # include    "hunt.h"
  8. # include    <ctype.h>
  9. # include    <errno.h>
  10. # include    <fcntl.h>
  11.  
  12. # define    SCOREDECAY    15
  13.  
  14. static char    Ttyname[NAMELEN];
  15.  
  16. # ifdef linux
  17.   int gethostid() {
  18.     return 1;    /* a unique host number :) */
  19.   }
  20. # endif
  21.  
  22. answer()
  23. {
  24.     register PLAYER        *pp;
  25.     register int        newsock;
  26.     static u_long        mode;
  27.     static char        name[NAMELEN];
  28.     static char        team;
  29.     static int        enter_status;
  30.     static int        socklen;
  31.     static u_long        machine;
  32.     static u_long        uid;
  33.     static SOCKET        sockstruct;
  34.     register char    *cp1, *cp2;
  35.     int            flags;
  36.     long            version;
  37.  
  38. # ifdef INTERNET
  39.     socklen = sizeof sockstruct;
  40. # else
  41.     socklen = sizeof sockstruct - 1;
  42. # endif
  43.     errno = 0;
  44.     newsock = accept(Socket, (struct sockaddr *) &sockstruct, &socklen);
  45.     if (newsock < 0)
  46.     {
  47.         if (errno == EINTR)
  48.             return FALSE;
  49. # ifdef LOG
  50.         syslog(LOG_ERR, "accept: %m");
  51. # else
  52.         perror("accept");
  53. # endif
  54.         cleanup(1);
  55.     }
  56.  
  57. # ifdef INTERNET
  58.     machine = ntohl(((struct sockaddr_in *) &sockstruct)->sin_addr.s_addr);
  59. # else
  60.     if (machine == 0)
  61.         machine = gethostid();
  62. # endif
  63.     version = htonl((unsigned long) HUNT_VERSION);
  64.     (void) write(newsock, (char *) &version, LONGLEN);
  65.     (void) read(newsock, (char *) &uid, LONGLEN);
  66.     uid = ntohl((unsigned long) uid);
  67.     (void) read(newsock, name, NAMELEN);
  68.     (void) read(newsock, &team, 1);
  69.     (void) read(newsock, (char *) &enter_status, LONGLEN);
  70.     enter_status = ntohl((unsigned long) enter_status);
  71.     (void) read(newsock, Ttyname, NAMELEN);
  72.     (void) read(newsock, (char *) &mode, sizeof mode);
  73.     mode = ntohl(mode);
  74.  
  75.     /*
  76.      * Turn off blocking I/O, so a slow or dead terminal won't stop
  77.      * the game.  All subsequent reads check how many bytes they read.
  78.      */
  79.     flags = fcntl(newsock, F_GETFL, 0);
  80.     flags |= O_NDELAY;
  81.     (void) fcntl(newsock, F_SETFL, flags);
  82.  
  83.     /*
  84.      * Make sure the name contains only printable characters
  85.      * since we use control characters for cursor control
  86.      * between driver and player processes
  87.      */
  88.     for (cp1 = cp2 = name; *cp1 != '\0'; cp1++)
  89.         if (isprint(*cp1) || *cp1 == ' ')
  90.             *cp2++ = *cp1;
  91.     *cp2 = '\0';
  92.  
  93. # ifdef INTERNET
  94.     if (mode == C_MESSAGE) {
  95.         char    buf[BUFSIZ + 1];
  96.         int    n;
  97.  
  98.         if (team == ' ')
  99.             (void) sprintf(buf, "%s: ", name);
  100.         else
  101.             (void) sprintf(buf, "%s[%c]: ", name, team);
  102.         n = strlen(buf);
  103.         for (pp = Player; pp < End_player; pp++) {
  104.             cgoto(pp, HEIGHT, 0);
  105.             outstr(pp, buf, n);
  106.         }
  107.         while ((n = read(newsock, buf, BUFSIZ)) > 0)
  108.             for (pp = Player; pp < End_player; pp++)
  109.                 outstr(pp, buf, n);
  110.         for (pp = Player; pp < End_player; pp++) {
  111.             ce(pp);
  112.             sendcom(pp, REFRESH);
  113.             sendcom(pp, READY, 0);
  114.             (void) fflush(pp->p_output);
  115.         }
  116.         (void) close(newsock);
  117.         return FALSE;
  118.     }
  119.     else
  120. # endif
  121. # ifdef MONITOR
  122.     if (mode == C_MONITOR)
  123.         if (End_monitor < &Monitor[MAXMON])
  124.             pp = End_monitor++;
  125.         else {
  126.             socklen = 0;
  127.             (void) write(newsock, (char *) &socklen,
  128.                 sizeof socklen);
  129.             (void) close(newsock);
  130.             return FALSE;
  131.         }
  132.     else
  133. # endif
  134.         if (End_player < &Player[MAXPL])
  135.             pp = End_player++;
  136.         else {
  137.             socklen = 0;
  138.             (void) write(newsock, (char *) &socklen,
  139.                 sizeof socklen);
  140.             (void) close(newsock);
  141.             return FALSE;
  142.         }
  143.  
  144. #ifdef MONITOR
  145.     if (mode == C_MONITOR && team == ' ')
  146.         team = '*';
  147. #endif
  148.     pp->p_ident = get_ident(machine, uid, name, team);
  149.     pp->p_output = fdopen(newsock, "w");
  150.     pp->p_death[0] = '\0';
  151.     pp->p_fd = newsock;
  152.     pp->p_mask = (1 << pp->p_fd);
  153.     Fds_mask |= pp->p_mask;
  154.     if (pp->p_fd >= Num_fds)
  155.         Num_fds = pp->p_fd + 1;
  156.  
  157.     pp->p_y = 0;
  158.     pp->p_x = 0;
  159.  
  160. # ifdef MONITOR
  161.     if (mode == C_MONITOR)
  162.         stmonitor(pp);
  163.     else
  164. # endif
  165.         stplayer(pp, enter_status);
  166.     return TRUE;
  167. }
  168.  
  169. # ifdef MONITOR
  170. stmonitor(pp)
  171. register PLAYER    *pp;
  172. {
  173.     register int    line;
  174.     register PLAYER    *npp;
  175.  
  176.     memcpy(pp->p_maze, Maze, sizeof Maze);
  177.  
  178.     drawmaze(pp);
  179.  
  180.     (void) sprintf(Buf, "%5.5s%c%-10.10s %c", " ", stat_char(pp),
  181.         pp->p_ident->i_name, pp->p_ident->i_team);
  182.     line = STAT_MON_ROW + 1 + (pp - Monitor);
  183.     for (npp = Player; npp < End_player; npp++) {
  184.         cgoto(npp, line, STAT_NAME_COL);
  185.         outstr(npp, Buf, STAT_NAME_LEN);
  186.     }
  187.     for (npp = Monitor; npp < End_monitor; npp++) {
  188.         cgoto(npp, line, STAT_NAME_COL);
  189.         outstr(npp, Buf, STAT_NAME_LEN);
  190.     }
  191.  
  192.     sendcom(pp, REFRESH);
  193.     sendcom(pp, READY, 0);
  194.     (void) fflush(pp->p_output);
  195. }
  196. # endif
  197.  
  198. stplayer(newpp, enter_status)
  199. register PLAYER    *newpp;
  200. int        enter_status;
  201. {
  202.     register int    x, y;
  203.     register PLAYER    *pp;
  204.  
  205.     Nplayer++;
  206.  
  207.     for (y = 0; y < UBOUND; y++)
  208.         for (x = 0; x < WIDTH; x++)
  209.             newpp->p_maze[y][x] = Maze[y][x];
  210.     for (     ; y < DBOUND; y++) {
  211.         for (x = 0; x < LBOUND; x++)
  212.             newpp->p_maze[y][x] = Maze[y][x];
  213.         for (     ; x < RBOUND; x++)
  214.             newpp->p_maze[y][x] = SPACE;
  215.         for (     ; x < WIDTH;  x++)
  216.             newpp->p_maze[y][x] = Maze[y][x];
  217.     }
  218.     for (     ; y < HEIGHT; y++)
  219.         for (x = 0; x < WIDTH; x++)
  220.             newpp->p_maze[y][x] = Maze[y][x];
  221.  
  222.     do {
  223.         x = rand_num(WIDTH - 1) + 1;
  224.         y = rand_num(HEIGHT - 1) + 1;
  225.     } while (Maze[y][x] != SPACE);
  226.     newpp->p_over = SPACE;
  227.     newpp->p_x = x;
  228.     newpp->p_y = y;
  229.     newpp->p_undershot = FALSE;
  230.  
  231. # ifdef FLY
  232.     if (enter_status == Q_FLY) {
  233.         newpp->p_flying = rand_num(20);
  234.         newpp->p_flyx = 2 * rand_num(6) - 5;
  235.         newpp->p_flyy = 2 * rand_num(6) - 5;
  236.         newpp->p_face = FLYER;
  237.     }
  238.     else
  239. # endif
  240.     {
  241.         newpp->p_flying = -1;
  242.         newpp->p_face = rand_dir();
  243.     }
  244.     newpp->p_damage = 0;
  245.     newpp->p_damcap = MAXDAM;
  246.     newpp->p_nchar = 0;
  247.     newpp->p_ncount = 0;
  248.     newpp->p_nexec = 0;
  249.     newpp->p_ammo = ISHOTS;
  250. # ifdef BOOTS
  251.     newpp->p_nboots = 0;
  252. # endif
  253.     if (enter_status == Q_SCAN) {
  254.         newpp->p_scan = SCANLEN;
  255.         newpp->p_cloak = 0;
  256.     }
  257.     else {
  258.         newpp->p_scan = 0;
  259.         newpp->p_cloak = CLOAKLEN;
  260.     }
  261.     newpp->p_ncshot = 0;
  262.  
  263.     do {
  264.         x = rand_num(WIDTH - 1) + 1;
  265.         y = rand_num(HEIGHT - 1) + 1;
  266.     } while (Maze[y][x] != SPACE);
  267.     Maze[y][x] = GMINE;
  268. # ifdef MONITOR
  269.     for (pp = Monitor; pp < End_monitor; pp++)
  270.         check(pp, y, x);
  271. # endif
  272.  
  273.     do {
  274.         x = rand_num(WIDTH - 1) + 1;
  275.         y = rand_num(HEIGHT - 1) + 1;
  276.     } while (Maze[y][x] != SPACE);
  277.     Maze[y][x] = MINE;
  278. # ifdef MONITOR
  279.     for (pp = Monitor; pp < End_monitor; pp++)
  280.         check(pp, y, x);
  281. # endif
  282.  
  283.     (void) sprintf(Buf, "%5.2f%c%-10.10s %c", newpp->p_ident->i_score,
  284.         stat_char(newpp), newpp->p_ident->i_name,
  285.         newpp->p_ident->i_team);
  286.     y = STAT_PLAY_ROW + 1 + (newpp - Player);
  287.     for (pp = Player; pp < End_player; pp++) {
  288.         if (pp != newpp) {
  289.             char    smallbuf[10];
  290.  
  291.             pp->p_ammo += NSHOTS;
  292.             newpp->p_ammo += NSHOTS;
  293.             cgoto(pp, y, STAT_NAME_COL);
  294.             outstr(pp, Buf, STAT_NAME_LEN);
  295.             (void) sprintf(smallbuf, "%3d", pp->p_ammo);
  296.             cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
  297.             outstr(pp, smallbuf, 3);
  298.         }
  299.     }
  300. # ifdef MONITOR
  301.     for (pp = Monitor; pp < End_monitor; pp++) {
  302.         cgoto(pp, y, STAT_NAME_COL);
  303.         outstr(pp, Buf, STAT_NAME_LEN);
  304.     }
  305. # endif
  306.  
  307.     drawmaze(newpp);
  308.     drawplayer(newpp, TRUE);
  309.     look(newpp);
  310. # ifdef    FLY
  311.     if (enter_status == Q_FLY)
  312.         /* Make sure that the position you enter in will be erased */
  313.         showexpl(newpp->p_y, newpp->p_x, FLYER);
  314. # endif
  315.     sendcom(newpp, REFRESH);
  316.     sendcom(newpp, READY, 0);
  317.     (void) fflush(newpp->p_output);
  318. }
  319.  
  320. /*
  321.  * rand_dir:
  322.  *    Return a random direction
  323.  */
  324. rand_dir()
  325. {
  326.     switch (rand_num(4)) {
  327.       case 0:
  328.         return LEFTS;
  329.       case 1:
  330.         return RIGHT;
  331.       case 2:
  332.         return BELOW;
  333.       case 3:
  334.         return ABOVE;
  335.     }
  336.     /* NOTREACHED */
  337. }
  338.  
  339. /*
  340.  * get_ident:
  341.  *    Get the score structure of a player
  342.  */
  343. IDENT *
  344. get_ident(machine, uid, name, team)
  345. u_long    machine;
  346. u_long    uid;
  347. char    *name;
  348. char    team;
  349. {
  350.     register IDENT    *ip;
  351.     static IDENT    punt;
  352.  
  353.     for (ip = Scores; ip != NULL; ip = ip->i_next)
  354.         if (ip->i_machine == machine
  355.         &&  ip->i_uid == uid
  356.         &&  ip->i_team == team
  357.         &&  strncmp(ip->i_name, name, NAMELEN) == 0)
  358.             break;
  359.  
  360.     if (ip != NULL) {
  361.         if (ip->i_entries < SCOREDECAY)
  362.             ip->i_entries++;
  363.         else
  364.             ip->i_kills = (ip->i_kills * (SCOREDECAY - 1))
  365.                 / SCOREDECAY;
  366.         ip->i_score = ip->i_kills / (double) ip->i_entries;
  367.     }
  368.     else {
  369.         ip = (IDENT *) malloc(sizeof (IDENT));
  370.         if (ip == NULL) {
  371.             /* Fourth down, time to punt */
  372.             ip = &punt;
  373.         }
  374.         ip->i_machine = machine;
  375.         ip->i_team = team;
  376.         ip->i_uid = uid;
  377.         strncpy(ip->i_name, name, NAMELEN);
  378.         ip->i_kills = 0;
  379.         ip->i_entries = 1;
  380.         ip->i_score = 0;
  381.         ip->i_absorbed = 0;
  382.         ip->i_faced = 0;
  383.         ip->i_shot = 0;
  384.         ip->i_robbed = 0;
  385.         ip->i_slime = 0;
  386.         ip->i_missed = 0;
  387.         ip->i_ducked = 0;
  388.         ip->i_gkills = ip->i_bkills = ip->i_deaths = 0;
  389.         ip->i_stillb = ip->i_saved = 0;
  390.         ip->i_next = Scores;
  391.         Scores = ip;
  392.     }
  393.  
  394.     return ip;
  395. }
  396.