home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-01-26 | 54.4 KB | 2,480 lines |
- Path: uunet!news.tek.com!master!saab!billr
- From: billr@saab.CNA.TEK.COM (Bill Randle)
- Newsgroups: comp.sources.games
- Subject: v15i033: robot_hunt - original hunt with a robot, Part02/04
- Message-ID: <4189@master.CNA.TEK.COM>
- Date: 14 Jan 93 03:13:41 GMT
- Sender: news@master.CNA.TEK.COM
- Lines: 2468
- Approved: billr@saab.CNA.TEK.COM
- Xref: uunet comp.sources.games:1532
-
- Submitted-by: whatis@ucsd.edu (Steve Boswell)
- Posting-number: Volume 15, Issue 33
- Archive-name: robot_hunt/Part02
- Environment: Curses, Sockets
-
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 2 (of 4)."
- # Contents: driver.c extern.c hunt.c shots.c
- # Wrapped by billr@saab on Wed Jan 13 19:04:32 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'driver.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'driver.c'\"
- else
- echo shar: Extracting \"'driver.c'\" \(15418 characters\)
- sed "s/^X//" >'driver.c' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1985 Regents of the University of California.
- X * All rights reserved.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that the above copyright notice and this paragraph are
- X * duplicated in all such forms and that any documentation,
- X * advertising materials, and other materials related to such
- X * distribution and use acknowledge that the software was developed
- X * by the University of California, Berkeley. The name of the
- X * University may not be used to endorse or promote products derived
- X * from this software without specific prior written permission.
- X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X */
- X
- X#ifndef lint
- Xchar copyright[] =
- X"@(#) Copyright (c) 1985 Regents of the University of California.\n\
- X All rights reserved.\n";
- X#endif /* not lint */
- X
- X#ifndef lint
- Xstatic char sccsid[] = "@(#)driver.c 5.3 (Berkeley) 6/27/88";
- X#endif /* not lint */
- X
- X/*
- X * Hunt
- X * Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
- X * San Francisco, California
- X */
- X
- X# include "hunt.h"
- X# include <signal.h>
- X# include <errno.h>
- X# include <sys/ioctl.h>
- X# include <sys/time.h>
- Xextern int Seed;
- X
- X# ifdef CONSTANT_MOVE
- Xstatic struct itimerval Timing;
- X# endif CONSTANT_MOVE
- X
- XSOCKET Daemon;
- X# ifdef INTERNET
- Xint Test_socket; /* test socket to answer datagrams */
- X# define DAEMON_SIZE (sizeof Daemon)
- X# else INTERNET
- X# define DAEMON_SIZE (sizeof Daemon - 1)
- X# endif INTERNET
- X
- X/*
- X * main:
- X * The main program.
- X */
- Xmain()
- X{
- X register PLAYER *pp;
- X register int had_char;
- X# ifdef INTERNET
- X register long test_mask;
- X int msg;
- X int namelen;
- X SOCKET test;
- X# endif INTERNET
- X# ifdef CONSTANT_MOVE
- X register int enable_alarm, disable_alarm;
- X# endif CONSTANT_MOVE
- X static long read_fds;
- X
- X init();
- X Sock_mask = (1 << Socket);
- X# ifdef INTERNET
- X test_mask = (1 << Test_socket);
- X# endif INTERNET
- X
- X# ifdef CONSTANT_MOVE
- X enable_alarm = sigblock(0);
- X disable_alarm = enable_alarm | (1 << (SIGALRM - 1));
- X (void) sigsetmask(disable_alarm);
- X (void) signal(SIGALRM, moveshots);
- X# endif CONSTANT_MOVE
- X
- X while (Nplayer > 0) {
- X# ifdef CONSTANT_MOVE
- X (void) sigsetmask(enable_alarm);
- X# endif CONSTANT_MOVE
- X read_fds = Fds_mask;
- X errno = 0;
- X# ifndef OLDIPC
- X while (select(Num_fds, &read_fds, (int *) NULL,
- X (int *) NULL, (struct timeval *) NULL) < 0)
- X# else OLDIPC
- X while (select(20, &read_fds, NULL, 32767) < 0)
- X# endif OLDIPC
- X {
- X if (errno != EINTR)
- X perror("select");
- X if (Nplayer == 0)
- X goto out;
- X errno = 0;
- X }
- X Have_inp = read_fds;
- X# ifdef CONSTANT_MOVE
- X (void) sigsetmask(disable_alarm);
- X# endif CONSTANT_MOVE
- X# ifdef INTERNET
- X if (read_fds & test_mask) {
- X namelen = DAEMON_SIZE;
- X# ifndef OLDIPC
- X (void) recvfrom(Test_socket, (char *) &msg, sizeof msg,
- X 0, (struct sockaddr *) &test, &namelen);
- X (void) sendto(Test_socket, (char *) &msg, sizeof msg,
- X 0, (struct sockaddr *) &test, DAEMON_SIZE);
- X# else OLDIPC
- X (void) receive(Test_socket, (struct sockaddr *) &test,
- X (char *) &msg, sizeof msg);
- X (void) send(Test_socket, (struct sockaddr *) &test,
- X (char *) &msg, sizeof msg);
- X# endif OLDIPC
- X }
- X# endif INTERNET
- X for (;;) {
- X had_char = FALSE;
- X for (pp = Player; pp < End_player; pp++)
- X if (havechar(pp)) {
- X execute(pp);
- X pp->p_nexec++;
- X had_char++;
- X }
- X# ifdef MONITOR
- X for (pp = Monitor; pp < End_monitor; pp++)
- X if (havechar(pp)) {
- X mon_execute(pp);
- X pp->p_nexec++;
- X had_char++;
- X }
- X# endif MONITOR
- X if (!had_char)
- X break;
- X# ifdef CONSTANT_MOVE
- X for (pp = Player; pp < End_player; pp++) {
- X look(pp);
- X sendcom(pp, REFRESH);
- X }
- X# ifdef MONITOR
- X for (pp = Monitor; pp < End_monitor; pp++)
- X sendcom(pp, REFRESH);
- X# endif MONITOR
- X# else CONSTANT_MOVE
- X moveshots();
- X# endif CONSTANT_MOVE
- X for (pp = Player; pp < End_player; )
- X if (pp->p_death[0] != '\0')
- X zap(pp, TRUE);
- X else
- X pp++;
- X# ifdef MONITOR
- X for (pp = Monitor; pp < End_monitor; )
- X if (pp->p_death[0] != '\0')
- X zap(pp, FALSE);
- X else
- X pp++;
- X# endif MONITOR
- X }
- X if (read_fds & Sock_mask)
- X answer();
- X for (pp = Player; pp < End_player; pp++) {
- X if (read_fds & pp->p_mask)
- X sendcom(pp, READY, pp->p_nexec);
- X pp->p_nexec = 0;
- X (void) fflush(pp->p_output);
- X }
- X# ifdef MONITOR
- X for (pp = Monitor; pp < End_monitor; pp++) {
- X if (read_fds & pp->p_mask)
- X sendcom(pp, READY, pp->p_nexec);
- X pp->p_nexec = 0;
- X (void) fflush(pp->p_output);
- X }
- X# endif MONITOR
- X }
- Xout:
- X# ifdef CONSTANT_MOVE
- X bul_alarm(0);
- X# endif CONSTANT_MOVE
- X
- X# ifdef MONITOR
- X for (pp = Monitor; pp < End_monitor; )
- X zap(pp, FALSE);
- X# endif MONITOR
- X cleanup(0);
- X}
- X
- X/*
- X * init:
- X * Initialize the global parameters.
- X */
- Xinit()
- X{
- X register int i;
- X# ifdef INTERNET
- X SOCKET test_port;
- X auto int msg;
- X# endif INTERNET
- X int cleanup();
- X
- X# ifndef DEBUG
- X (void) ioctl(fileno(stdout), TIOCNOTTY, NULL);
- X (void) setpgrp(getpid(), getpid());
- X (void) signal(SIGHUP, SIG_IGN);
- X (void) signal(SIGINT, SIG_IGN);
- X (void) signal(SIGQUIT, SIG_IGN);
- X (void) signal(SIGTERM, cleanup);
- X# endif DEBUG
- X
- X# ifndef pdp11
- X /* Seed the random number generator. */
- X srandom (getpid());
- X# endif pdp11
- X
- X (void) chdir("/usr/tmp"); /* just in case it core dumps */
- X (void) signal(SIGPIPE, SIG_IGN);
- X
- X# ifdef INTERNET
- X Daemon.sin_family = SOCK_FAMILY;
- X# ifdef OLD
- X if (gethostname(local_name, sizeof local_name) < 0) {
- X perror("gethostname");
- X exit(1);
- X }
- X if ((hp = gethostbyname(local_name)) == NULL) {
- X fprintf(stderr, "Unknown host %s\n", local_name);
- X exit(1);
- X }
- X bcopy(hp->h_addr, &(Daemon.sin_addr.s_addr), hp->h_length);
- X# else
- X Daemon.sin_addr.s_addr = INADDR_ANY;
- X# endif OLD
- X Daemon.sin_port = htons(Sock_port);
- X# else INTERNET
- X Daemon.sun_family = SOCK_FAMILY;
- X (void) strcpy(Daemon.sun_path, Sock_name);
- X# endif INTERNET
- X
- X# ifndef OLDIPC
- X Socket = socket(SOCK_FAMILY, SOCK_STREAM, 0);
- X# else OLDIPC
- X Socket = socket(SOCK_STREAM, 0, (struct sockaddr *) &Daemon,
- X SO_ACCEPTCONN);
- X# endif OLDIPC
- X# if defined(INTERNET) && !defined(OLDIPC)
- X msg = 1;
- X if (setsockopt(Socket, SOL_SOCKET, SO_REUSEADDR, &msg, sizeof msg)<0)
- X perror("setsockopt loopback");
- X# endif INTERNET
- X# ifndef OLDIPC
- X if (bind(Socket, (struct sockaddr *) &Daemon, DAEMON_SIZE) < 0) {
- X if (errno == EADDRINUSE)
- X exit(0);
- X else {
- X perror("bind");
- X cleanup(1);
- X }
- X }
- X (void) listen(Socket, 5);
- X# endif OLDIPC
- X Fds_mask = (1 << Socket);
- X Num_fds = Socket + 1;
- X
- X# ifdef INTERNET
- X test_port = Daemon;
- X test_port.sin_port = htons(Test_port);
- X
- X# ifndef OLDIPC
- X Test_socket = socket(SOCK_FAMILY, SOCK_DGRAM, 0);
- X if (bind(Test_socket, (struct sockaddr *) &test_port,
- X DAEMON_SIZE) < 0) {
- X perror("bind");
- X exit(1);
- X }
- X (void) listen(Test_socket, 5);
- X# else OLDIPC
- X Test_socket = socket(SOCK_DGRAM, 0, (struct sockaddr *) &test_port, 0);
- X# endif OLDIPC
- X Fds_mask |= (1 << Test_socket);
- X if (Test_socket > Socket)
- X Num_fds = Test_socket + 1;
- X# endif INTERNET
- X
- X Seed = getpid() + time((time_t *) NULL);
- X makemaze();
- X
- X for (i = 0; i < NASCII; i++)
- X See_over[i] = TRUE;
- X See_over[DOOR] = FALSE;
- X See_over[WALL1] = FALSE;
- X See_over[WALL2] = FALSE;
- X See_over[WALL3] = FALSE;
- X# ifdef REFLECT
- X See_over[WALL4] = FALSE;
- X See_over[WALL5] = FALSE;
- X# endif REFLECT
- X
- X# ifdef CONSTANT_MOVE
- X getitimer(ITIMER_REAL, &Timing);
- X Timing.it_interval.tv_sec = 0;
- X Timing.it_interval.tv_usec = 500;
- X Timing.it_value.tv_sec = 0;
- X Timing.it_value.tv_usec = 0;
- X setitimer(ITIMER_REAL, &Timing, NULL);
- X# endif CONSTANT_MOVE
- X
- X answer();
- X}
- X
- X# ifdef CONSTANT_MOVE
- X/*
- X * bul_alarm:
- X * Set up the alarm for the bullets
- X */
- Xbul_alarm(val)
- Xint val;
- X{
- X Timing.it_value.tv_usec = val * Timing.it_interval.tv_usec;
- X setitimer(ITIMER_REAL, &Timing, NULL);
- X}
- X# endif CONSTANT_MOVE
- X
- X/*
- X * checkdam:
- X * Check the damage to the given player, and see if s/he is killed
- X */
- Xcheckdam(ouch, gotcha, credit, amt, shot_type)
- Xregister PLAYER *ouch, *gotcha;
- Xregister IDENT *credit;
- Xint amt;
- Xchar shot_type;
- X{
- X register char *cp;
- X
- X if (ouch->p_death[0] != '\0')
- X return;
- X if (rand_num(100) < 5) {
- X message(ouch, "Missed you by a hair");
- X if (gotcha != NULL)
- X message(gotcha, "Missed him");
- X return;
- X }
- X ouch->p_damage += amt;
- X if (ouch->p_damage <= ouch->p_damcap) {
- X (void) sprintf(Buf, "%2d", ouch->p_damage);
- X cgoto(ouch, STAT_DAM_ROW, STAT_VALUE_COL);
- X outstr(ouch, Buf, 2);
- X return;
- X }
- X
- X /* Someone DIED */
- X switch (shot_type) {
- X default:
- X cp = "Killed";
- X break;
- X# ifdef FLY
- X case FALL:
- X cp = "Killed on impact";
- X break;
- X# endif FLY
- X case KNIFE:
- X cp = "Stabbed to death";
- X break;
- X case SHOT:
- X cp = "Shot to death";
- X break;
- X case GRENADE:
- X case SATCHEL:
- X case BOMB:
- X cp = "Bombed";
- X break;
- X case MINE:
- X case GMINE:
- X cp = "Blown apart";
- X break;
- X# ifdef OOZE
- X case SLIME:
- X cp = "Slimed";
- X break;
- X# endif OOZE
- X# ifdef VOLCANO
- X case LAVA:
- X cp = "Baked";
- X break;
- X# endif VOLCANO
- X }
- X if (credit == NULL) {
- X (void) sprintf(ouch->p_death, "| %s by %s |", cp,
- X (shot_type == MINE || shot_type == GMINE) ?
- X "a mine" : "act of God");
- X return;
- X }
- X
- X (void) sprintf(ouch->p_death, "| %s by %s |", cp, credit->i_name);
- X
- X credit->i_kills++;
- X credit->i_score = credit->i_kills / (double) credit->i_entries;
- X if (gotcha == NULL)
- X return;
- X gotcha->p_damcap += STABDAM;
- X gotcha->p_damage -= STABDAM;
- X if (gotcha->p_damage < 0)
- X gotcha->p_damage = 0;
- X (void) sprintf(Buf, "%2d/%2d", gotcha->p_damage, gotcha->p_damcap);
- X cgoto(gotcha, STAT_DAM_ROW, STAT_VALUE_COL);
- X outstr(gotcha, Buf, 5);
- X (void) sprintf(Buf, "%3d", (gotcha->p_damcap - MAXDAM) / 2);
- X cgoto(gotcha, STAT_KILL_ROW, STAT_VALUE_COL);
- X outstr(gotcha, Buf, 3);
- X (void) sprintf(Buf, "%5.2f", gotcha->p_ident->i_score);
- X for (ouch = Player; ouch < End_player; ouch++) {
- X cgoto(ouch, STAT_PLAY_ROW + 1 + (gotcha - Player),
- X STAT_NAME_COL);
- X outstr(ouch, Buf, 5);
- X }
- X}
- X
- X/*
- X * zap:
- X * Kill off a player and take him out of the game.
- X */
- Xzap(pp, was_player)
- Xregister PLAYER *pp;
- XFLAG was_player;
- X{
- X register int i, len;
- X register BULLET *bp;
- X register PLAYER *np;
- X register int x, y;
- X int savefd, savemask;
- X
- X if (was_player) {
- X drawplayer(pp, FALSE);
- X Nplayer--;
- X }
- X
- X len = strlen(pp->p_death); /* Display the cause of death */
- X x = (WIDTH - len) / 2;
- X cgoto(pp, HEIGHT / 2, x);
- X outstr(pp, pp->p_death, len);
- X for (i = 1; i < len; i++)
- X pp->p_death[i] = '-';
- X pp->p_death[0] = '+';
- X pp->p_death[len - 1] = '+';
- X cgoto(pp, HEIGHT / 2 - 1, x);
- X outstr(pp, pp->p_death, len);
- X cgoto(pp, HEIGHT / 2 + 1, x);
- X outstr(pp, pp->p_death, len);
- X cgoto(pp, HEIGHT, 0);
- X
- X if (Nplayer == 0) {
- X# ifdef CONSTANT_MOVE
- X bul_alarm(0);
- X# endif CONSTANT_MOVE
- X cleanup(0);
- X /* NOTREACHED */
- X }
- X
- X savefd = pp->p_fd;
- X savemask = pp->p_mask;
- X
- X# ifdef MONITOR
- X if (was_player) {
- X# endif MONITOR
- X for (bp = Bullets; bp != NULL; bp = bp->b_next) {
- X if (bp->b_owner == pp)
- X bp->b_owner = NULL;
- X if (bp->b_x == pp->p_x && bp->b_y == pp->p_y)
- X bp->b_over = SPACE;
- X }
- X
- X i = rand_num(pp->p_ammo);
- X if (i == pp->p_ammo - 1) {
- X x = pp->p_ammo;
- X len = SLIME;
- X }
- X else if (i >= BOMBREQ) {
- X x = BOMBREQ;
- X len = BOMB;
- X }
- X else if (i >= SSLIMEREQ) {
- X x = SSLIMEREQ;
- X len = SLIME;
- X }
- X else if (i >= SATREQ) {
- X x = SATREQ;
- X len = SATCHEL;
- X }
- X else if (i >= SLIMEREQ) {
- X x = SLIMEREQ;
- X len = SLIME;
- X }
- X else if (i >= GRENREQ) {
- X x = GRENREQ;
- X len = GRENADE;
- X }
- X else
- X x = 0;
- X if (x > 0) {
- X add_shot(len, pp->p_y, pp->p_x, pp->p_face, x,
- X (PLAYER *) NULL, TRUE, SPACE);
- X (void) sprintf(Buf, "%s detonated.",
- X pp->p_ident->i_name);
- X for (np = Player; np < End_player; np++)
- X message(np, Buf);
- X# ifdef MONITOR
- X for (np = Monitor; np < End_monitor; np++)
- X message(np, Buf);
- X# endif MONITOR
- X }
- X
- X# ifdef VOLCANO
- X volcano += pp->p_ammo - x;
- X if (rand_num(100) < volcano / 50) {
- X do {
- X x = rand_num(WIDTH / 2) + WIDTH / 4;
- X y = rand_num(HEIGHT / 2) + HEIGHT / 4;
- X } while (Maze[y][x] != SPACE);
- X add_shot(LAVA, y, x, LEFTS, volcano,
- X (PLAYER *) NULL, TRUE, SPACE);
- X for (np = Player; np < End_player; np++)
- X message(np, "Volcano eruption.");
- X volcano = 0;
- X }
- X# endif VOLCANO
- X
- X sendcom(pp, ENDWIN);
- X (void) fclose(pp->p_output);
- X
- X End_player--;
- X if (pp != End_player) {
- X bcopy((char *) End_player, (char *) pp,
- X sizeof (PLAYER));
- X (void) sprintf(Buf, "%5.2f%c%-10.10s",
- X pp->p_ident->i_score, stat_char(pp),
- X pp->p_ident->i_name);
- X i = STAT_PLAY_ROW + 1 + (pp - Player);
- X for (np = Player; np < End_player; np++) {
- X cgoto(np, i, STAT_NAME_COL);
- X outstr(np, Buf, STAT_NAME_LEN);
- X }
- X# ifdef MONITOR
- X for (np = Monitor; np < End_monitor; np++) {
- X cgoto(np, i, STAT_NAME_COL);
- X outstr(np, Buf, STAT_NAME_LEN);
- X }
- X# endif MONITOR
- X }
- X
- X /* Erase the last player */
- X i = STAT_PLAY_ROW + 1 + Nplayer;
- X for (np = Player; np < End_player; np++) {
- X cgoto(np, i, STAT_NAME_COL);
- X ce(np);
- X }
- X# ifdef MONITOR
- X for (np = Monitor; np < End_monitor; np++) {
- X cgoto(np, i, STAT_NAME_COL);
- X ce(np);
- X }
- X }
- X else {
- X sendcom(pp, ENDWIN);
- X (void) putc(LAST_PLAYER, pp->p_output);
- X (void) fclose(pp->p_output);
- X
- X End_monitor--;
- X if (pp != End_monitor) {
- X bcopy((char *) End_monitor, (char *) pp,
- X sizeof (PLAYER));
- X (void) sprintf(Buf, "%5.5s %-10.10s", " ",
- X pp->p_ident->i_name);
- X i = STAT_MON_ROW + 1 + (pp - Player);
- X for (np = Player; np < End_player; np++) {
- X cgoto(np, i, STAT_NAME_COL);
- X outstr(np, Buf, STAT_NAME_LEN);
- X }
- X for (np = Monitor; np < End_monitor; np++) {
- X cgoto(np, i, STAT_NAME_COL);
- X outstr(np, Buf, STAT_NAME_LEN);
- X }
- X }
- X
- X /* Erase the last monitor */
- X i = STAT_MON_ROW + 1 + (End_monitor - Monitor);
- X for (np = Player; np < End_player; np++) {
- X cgoto(np, i, STAT_NAME_COL);
- X ce(np);
- X }
- X for (np = Monitor; np < End_monitor; np++) {
- X cgoto(np, i, STAT_NAME_COL);
- X ce(np);
- X }
- X
- X }
- X# endif MONITOR
- X
- X Fds_mask &= ~savemask;
- X if (Num_fds == savefd + 1) {
- X Num_fds = Socket;
- X# ifdef INTERNET
- X if (Test_socket > Socket)
- X Num_fds = Test_socket;
- X# endif INTERNET
- X for (np = Player; np < End_player; np++)
- X if (np->p_fd > Num_fds)
- X Num_fds = np->p_fd;
- X# ifdef MONITOR
- X for (np = Monitor; np < End_monitor; np++)
- X if (np->p_fd > Num_fds)
- X Num_fds = np->p_fd;
- X# endif MONITOR
- X Num_fds++;
- X }
- X}
- X
- X/*
- X * havechar:
- X * Check to see if we have any characters in the input queue; if
- X * we do, read them, stash them away, and return TRUE; else return
- X * FALSE.
- X */
- Xhavechar(pp)
- Xregister PLAYER *pp;
- X{
- X extern int errno;
- X
- X if (pp->p_ncount < pp->p_nchar)
- X return TRUE;
- X if (!(Have_inp & pp->p_mask))
- X return FALSE;
- X Have_inp &= ~pp->p_mask;
- Xcheck_again:
- X errno = 0;
- X if ((pp->p_nchar = read(pp->p_fd, pp->p_cbuf, sizeof pp->p_cbuf)) <= 0)
- X {
- X if (errno == EINTR)
- X goto check_again;
- X pp->p_cbuf[0] = 'q';
- X }
- X pp->p_ncount = 0;
- X return TRUE;
- X}
- X
- X/*
- X * cleanup:
- X * Exit with the given value, cleaning up any droppings lying around
- X */
- Xcleanup(eval)
- Xint eval;
- X{
- X register PLAYER *pp;
- X
- X for (pp = Player; pp < End_player; pp++) {
- X cgoto(pp, HEIGHT, 0);
- X sendcom(pp, ENDWIN);
- X (void) putc(LAST_PLAYER, pp->p_output);
- X (void) fclose(pp->p_output);
- X }
- X# ifdef MONITOR
- X for (pp = Monitor; pp < End_monitor; pp++) {
- X cgoto(pp, HEIGHT, 0);
- X sendcom(pp, ENDWIN);
- X (void) putc(LAST_PLAYER, pp->p_output);
- X (void) fclose(pp->p_output);
- X }
- X# endif MONITOR
- X (void) close(Socket);
- X# ifdef AF_UNIX_HACK
- X (void) unlink(Sock_name);
- X# endif AF_UNIX_HACK
- X exit(eval);
- X}
- END_OF_FILE
- if test 15418 -ne `wc -c <'driver.c'`; then
- echo shar: \"'driver.c'\" unpacked with wrong size!
- fi
- # end of 'driver.c'
- fi
- if test -f 'extern.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'extern.c'\"
- else
- echo shar: Extracting \"'extern.c'\" \(2185 characters\)
- sed "s/^X//" >'extern.c' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1985 Regents of the University of California.
- X * All rights reserved.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that the above copyright notice and this paragraph are
- X * duplicated in all such forms and that any documentation,
- X * advertising materials, and other materials related to such
- X * distribution and use acknowledge that the software was developed
- X * by the University of California, Berkeley. The name of the
- X * University may not be used to endorse or promote products derived
- X * from this software without specific prior written permission.
- X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X */
- X
- X#ifndef lint
- Xstatic char sccsid[] = "@(#)extern.c 5.2 (Berkeley) 6/27/88";
- X#endif /* not lint */
- X
- X/*
- X * Hunt
- X * Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
- X * San Francisco, California
- X */
- X
- X# include "hunt.h"
- X
- X# ifdef MONITOR
- XFLAG Am_monitor = FALSE; /* current process is a monitor */
- X# endif MONITOR
- X
- Xchar Buf[BUFSIZ]; /* general scribbling buffer */
- Xchar Maze[HEIGHT][WIDTH2]; /* the maze */
- Xchar Orig_maze[HEIGHT][WIDTH2]; /* the original maze */
- X
- Xlong Fds_mask; /* mask for the file descriptors */
- Xint Have_inp; /* which file descriptors have input */
- Xint Nplayer = 0; /* number of players */
- Xint Num_fds; /* number of maximum file descriptor */
- Xint Socket; /* main socket */
- Xlong Sock_mask; /* select mask for main socket */
- Xint See_over[NASCII]; /* lookup table for determining whether
- X * character represents "transparent"
- X * item */
- X
- XBULLET *Bullets = NULL; /* linked list of bullets */
- X
- XEXPL *Expl[EXPLEN]; /* explosion lists */
- X
- XPLAYER Player[MAXPL]; /* all the players */
- XPLAYER *End_player = Player; /* last active player slot */
- XIDENT *Scores; /* score cache */
- X# ifdef MONITOR
- XPLAYER Monitor[MAXMON]; /* all the monitors */
- XPLAYER *End_monitor = Monitor; /* last active monitor slot */
- X# endif MONITOR
- X
- X# ifdef VOLCANO
- Xint volcano = 0; /* Explosion size */
- X# endif VOLCANO
- END_OF_FILE
- if test 2185 -ne `wc -c <'extern.c'`; then
- echo shar: \"'extern.c'\" unpacked with wrong size!
- fi
- # end of 'extern.c'
- fi
- if test -f 'hunt.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'hunt.c'\"
- else
- echo shar: Extracting \"'hunt.c'\" \(16374 characters\)
- sed "s/^X//" >'hunt.c' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1985 Regents of the University of California.
- X * All rights reserved.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that the above copyright notice and this paragraph are
- X * duplicated in all such forms and that any documentation,
- X * advertising materials, and other materials related to such
- X * distribution and use acknowledge that the software was developed
- X * by the University of California, Berkeley. The name of the
- X * University may not be used to endorse or promote products derived
- X * from this software without specific prior written permission.
- X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X */
- X
- X#ifndef lint
- Xstatic char sccsid[] = "@(#)hunt.c 5.3 (Berkeley) 6/27/88";
- X#endif /* not lint */
- X
- X/*
- X * Hunt
- X * Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
- X * San Francisco, California
- X */
- X
- X# include <errno.h>
- X# include <curses.h>
- X# include "hunt.h"
- X# include <signal.h>
- X# include <ctype.h>
- X# include <sys/stat.h>
- X
- XFLAG Last_player = FALSE;
- X# ifdef MONITOR
- XFLAG Am_monitor = FALSE;
- X# endif MONITOR
- XFLAG Query_driver = FALSE;
- X
- Xchar Buf[BUFSIZ];
- X
- Xint Master_pid;
- Xint Socket;
- X# ifdef INTERNET
- Xchar *Sock_host;
- X# endif INTERNET
- X
- XSOCKET Daemon;
- X# ifdef INTERNET
- X# define DAEMON_SIZE (sizeof Daemon)
- X# else INTERNET
- X# define DAEMON_SIZE (sizeof Daemon - 1)
- X# endif INTERNET
- X
- Xchar map_key[256]; /* what to map keys to */
- X
- Xstatic char name[NAMELEN];
- X
- Xextern int cur_row, cur_col, _putchar();
- Xextern char *tgoto();
- X
- X# ifdef ROBOT
- Xextern int robot_player, daemon_player;
- X# endif ROBOT
- X
- X/*
- X * main:
- X * Main program for local process
- X */
- Xmain(ac, av)
- Xint ac;
- Xchar **av;
- X{
- X char *term;
- X extern int errno;
- X extern int Otto_mode;
- X int dumpit(), intr(), sigterm(), sigemt(), tstp();
- X int should_quit;
- X
- X for (ac--, av++; ac > 0 && av[0][0] == '-'; ac--, av++) {
- X switch (av[0][1]) {
- X
- X case 'l': /* rsh compatibility */
- X case 'n':
- X if (ac <= 1)
- X goto usage;
- X ac--, av++;
- X (void) strcpy(name, av[0]);
- X break;
- X case 'o':
- X# ifndef OTTO
- X fputs("The -o flag is reserved for future use.\n",
- X stderr);
- X goto usage;
- X# else OTTO
- X Otto_mode = TRUE;
- X break;
- X# endif OTTO
- X# ifdef MONITOR
- X case 'm':
- X Am_monitor = TRUE;
- X break;
- X# endif MONITOR
- X# ifdef ROBOT
- X case 'r':
- X robot_player = TRUE;
- X break;
- X case 'd':
- X daemon_player = TRUE;
- X break;
- X# endif ROBOT
- X# ifdef INTERNET
- X case 'q': /* query whether hunt is running */
- X Query_driver = TRUE;
- X break;
- X case 'h':
- X if (ac <= 1)
- X goto usage;
- X ac--, av++;
- X Sock_host = av[0];
- X break;
- X# endif INTERNET
- X default:
- X usage:
- X# ifdef ROBOT
- X# ifdef INTERNET
- X# ifdef MONITOR
- X# define USAGE "usage: hunt [-q] [-n name] [-h host] [-m] [-r [-d] ]\n"
- X# else MONITOR
- X# define USAGE "usage: hunt [-q] [-n name] [-h host] [-r [-d] ]\n"
- X# endif MONITOR
- X# else INTERNET
- X# ifdef MONITOR
- X# define USAGE "usage: hunt [-n name] [-m] [-r [-d] ]\n"
- X# else MONITOR
- X# define USAGE "usage: hunt [-n name] [-r [-d] ]\n"
- X# endif MONITOR
- X# endif INTERNET
- X# else ROBOT
- X# ifdef INTERNET
- X# ifdef MONITOR
- X# define USAGE "usage: hunt [-q] [-n name] [-h host] [-m]\n"
- X# else MONITOR
- X# define USAGE "usage: hunt [-q] [-n name] [-h host]\n"
- X# endif MONITOR
- X# else INTERNET
- X# ifdef MONITOR
- X# define USAGE "usage: hunt [-n name] [-m]\n"
- X# else MONITOR
- X# define USAGE "usage: hunt [-n name]\n"
- X# endif MONITOR
- X# endif INTERNET
- X# endif ROBOT
- X fputs(USAGE, stderr);
- X# undef USAGE
- X exit(1);
- X }
- X }
- X# ifdef INTERNET
- X if (ac > 1)
- X goto usage;
- X else if (ac > 0)
- X Sock_host = av[0];
- X# else INTERNET
- X if (ac > 0)
- X goto usage;
- X# endif INTERNET
- X
- X# ifdef INTERNET
- X if (Query_driver) {
- X find_driver(FALSE);
- X if (Daemon.sin_port != 0) {
- X struct hostent *hp;
- X
- X hp = gethostbyaddr(&Daemon.sin_addr,
- X sizeof Daemon.sin_addr, AF_INET);
- X fprintf(stderr, "HUNT!! found on %s\n", hp != NULL
- X ? hp->h_name : inet_ntoa(Daemon.sin_addr));
- X }
- X exit(Daemon.sin_port == 0);
- X }
- X# endif INTERNET
- X# ifdef OTTO
- X if (Otto_mode)
- X (void) strcpy(name, "otto");
- X else
- X# endif OTTO
- X env_init();
- X
- X (void) fflush(stdout);
- X if (!isatty(0) || (term = getenv("TERM")) == NULL) {
- X fprintf(stderr, "no terminal type\n");
- X exit(1);
- X }
- X if (!daemon_player)
- X {
- X _tty_ch = 0;
- X gettmode();
- X setterm(term);
- X noecho();
- X cbreak();
- X _puts(TI);
- X _puts(VS);
- X }
- X clear_screen();
- X (void) signal(SIGINT, intr);
- X (void) signal(SIGTERM, sigterm);
- X (void) signal(SIGEMT, sigemt);
- X (void) signal(SIGQUIT, dumpit);
- X (void) signal(SIGPIPE, SIG_IGN);
- X (void) signal(SIGTSTP, tstp);
- X
- X do {
- X# ifdef INTERNET
- X find_driver(TRUE);
- X
- X do {
- X int msg;
- X
- X# ifndef OLDIPC
- X Socket = socket(SOCK_FAMILY, SOCK_STREAM, 0);
- X# else OLDIPC
- X Socket = socket(SOCK_STREAM, 0, 0, 0);
- X# endif OLDIPC
- X if (Socket < 0) {
- X perror("socket");
- X exit(1);
- X }
- X# ifndef OLDIPC
- X msg = 1;
- X if (setsockopt(Socket, SOL_SOCKET, SO_USELOOPBACK,
- X &msg, sizeof msg) < 0)
- X perror("setsockopt loopback");
- X# endif OLDIPC
- X errno = 0;
- X if (connect(Socket, (struct sockaddr *) &Daemon,
- X DAEMON_SIZE) < 0) {
- X if (errno != ECONNREFUSED) {
- X perror("connect");
- X leave(1, "connect");
- X }
- X }
- X else
- X break;
- X sleep(1);
- X } while (close(Socket) == 0);
- X# else INTERNET
- X /*
- X * set up a socket
- X */
- X
- X if ((Socket = socket(SOCK_FAMILY, SOCK_STREAM, 0)) < 0) {
- X perror("socket");
- X exit(1);
- X }
- X
- X /*
- X * attempt to connect the socket to a name; if it fails that
- X * usually means that the driver isn't running, so we start
- X * up the driver.
- X */
- X
- X Daemon.sun_family = SOCK_FAMILY;
- X (void) strcpy(Daemon.sun_path, Sock_name);
- X if (connect(Socket, &Daemon, DAEMON_SIZE) < 0) {
- X if (errno != ENOENT) {
- X perror("connect");
- X leave(1, "connect2");
- X }
- X start_driver();
- X
- X do {
- X (void) close(Socket);
- X if ((Socket = socket(SOCK_FAMILY, SOCK_STREAM, 0)) < 0) {
- X perror("socket");
- X exit(1);
- X }
- X sleep(2);
- X } while (connect(Socket, &Daemon, DAEMON_SIZE) < 0);
- X }
- X# endif INTERNET
- X
- X do_connect(name);
- X setup_to_play();
- X
- X# ifdef ROBOT
- X if (robot_player)
- X {
- X do_robot();
- X should_quit = FALSE;
- X }
- X else
- X# endif ROBOT
- X {
- X playit();
- X should_quit = quit();
- X }
- X } while (!should_quit);
- X leave(0, NULL);
- X /* NOTREACHED */
- X}
- X
- X# ifdef INTERNET
- X# ifdef BROADCAST
- Xbroadcast_vec(s, vector)
- X int s; /* socket */
- X struct sockaddr **vector;
- X{
- X char if_buf[BUFSIZ];
- X struct ifconf ifc;
- X struct ifreq *ifr;
- X int n;
- X int vec_cnt;
- X
- X *vector = NULL;
- X ifc.ifc_len = sizeof if_buf;
- X ifc.ifc_buf = if_buf;
- X if (ioctl(s, SIOCGIFCONF, (char *) &ifc) < 0)
- X return 0;
- X vec_cnt = 0;
- X n = ifc.ifc_len / sizeof (struct ifreq);
- X *vector = (struct sockaddr *) malloc(n * sizeof (struct sockaddr));
- X for (ifr = ifc.ifc_req; n > 0; n--, ifr++)
- X if (ioctl(s, SIOCGIFBRDADDR, ifr) >= 0)
- X bcopy(&ifr->ifr_addr, &(*vector)[vec_cnt++],
- X sizeof (struct sockaddr));
- X return vec_cnt;
- X}
- X# endif BROADCAST
- X
- Xfind_driver(do_startup)
- XFLAG do_startup;
- X{
- X int msg;
- X static SOCKET test;
- X int test_socket;
- X int namelen;
- X char local_name[80];
- X static initial = TRUE;
- X static struct in_addr local_address;
- X register struct hostent *hp;
- X int sigalrm();
- X struct sigvec vec, ovec;
- X extern int errno;
- X# ifdef BROADCAST
- X static int brdc;
- X static SOCKET *brdv;
- X int i;
- X# endif BROADCAST
- X
- X if (Sock_host != NULL) {
- X if (!initial)
- X return; /* Daemon address already valid */
- X initial = FALSE;
- X if ((hp = gethostbyname(Sock_host)) == NULL) {
- X leave(1, "Unknown host");
- X /* NOTREACHED */
- X }
- X Daemon.sin_family = SOCK_FAMILY;
- X Daemon.sin_port = htons(Sock_port);
- X Daemon.sin_addr = *((struct in_addr *) hp->h_addr);
- X if (!Query_driver)
- X return;
- X }
- X
- X
- X if (initial) { /* do one time initialization */
- X# ifndef BROADCAST
- X sethostent(1); /* don't bother to close host file */
- X# endif BROADCAST
- X if (gethostname(local_name, sizeof local_name) < 0) {
- X leave(1, "Sorry, I have no name.");
- X /* NOTREACHED */
- X }
- X if ((hp = gethostbyname(local_name)) == NULL) {
- X leave(1, "Can't find myself.");
- X /* NOTREACHED */
- X }
- X local_address = * ((struct in_addr *) hp->h_addr);
- X
- X test.sin_family = SOCK_FAMILY;
- X test.sin_addr = local_address;
- X test.sin_port = htons(Test_port);
- X }
- X
- X# ifndef OLDIPC
- X test_socket = socket(SOCK_FAMILY, SOCK_DGRAM, 0);
- X# else OLDIPC
- X test_socket = socket(SOCK_DGRAM, 0, 0, 0);
- X# endif OLCIPC
- X if (test_socket < 0) {
- X perror("socket");
- X leave(1, "socket system call failed");
- X /* NOTREACHED */
- X }
- X
- X msg = 1;
- X if (Query_driver && Sock_host != NULL) {
- X test.sin_family = SOCK_FAMILY;
- X test.sin_addr = Daemon.sin_addr;
- X test.sin_port = htons(Test_port);
- X# ifndef OLDIPC
- X (void) sendto(test_socket, (char *) &msg, sizeof msg, 0,
- X (struct sockaddr *) &test, DAEMON_SIZE);
- X# else OLDIPC
- X (void) send(test_socket, (struct sockaddr *) &test,
- X (char *) &msg, sizeof msg);
- X# endif OLDIPC
- X goto get_response;
- X }
- X
- X if (!initial) {
- X /* favor host of previous session by broadcasting to it first */
- X test.sin_addr = Daemon.sin_addr;
- X test.sin_port = htons(Test_port);
- X (void) sendto(test_socket, (char *) &msg, sizeof msg, 0,
- X (struct sockaddr *) &test, DAEMON_SIZE);
- X }
- X
- X
- X# ifdef BROADCAST
- X if (initial)
- X brdc = broadcast_vec(test_socket, &brdv);
- X
- X if (brdc <= 0) {
- X Daemon.sin_family = SOCK_FAMILY;
- X Daemon.sin_addr = local_address;
- X Daemon.sin_port = htons(Sock_port);
- X initial = FALSE;
- X return;
- X }
- X
- X if (setsockopt(test_socket, SOL_SOCKET, SO_BROADCAST,
- X (int) &msg, sizeof msg) < 0) {
- X perror("setsockopt broadcast");
- X leave(1, "setsockopt broadcast");
- X /* NOTREACHED */
- X }
- X
- X /* send broadcast packets on all interfaces */
- X for (i = 0; i < brdc; i++) {
- X bcopy(&brdv[i], &test, sizeof (SOCKET));
- X test.sin_port = htons(Test_port);
- X if (sendto(test_socket, (char *) &msg, sizeof msg, 0,
- X (struct sockaddr *) &test, DAEMON_SIZE) < 0) {
- X perror("sendto");
- X leave(1, "sendto");
- X /* NOTREACHED */
- X }
- X }
- X# else BROADCAST
- X /* loop thru all hosts on local net and send msg to them. */
- X sethostent(0); /* rewind host file */
- X while (hp = gethostent()) {
- X if (inet_netof(test.sin_addr)
- X == inet_netof(* ((struct in_addr *) hp->h_addr))) {
- X test.sin_addr = * ((struct in_addr *) hp->h_addr);
- X# ifndef OLDIPC
- X (void) sendto(test_socket, (char *) &msg, sizeof msg, 0,
- X (struct sockaddr *) &test, DAEMON_SIZE);
- X# else OLDIPC
- X (void) send(test_socket, (struct sockaddr *) &test,
- X (char *) &msg, sizeof msg);
- X# endif OLDIPC
- X }
- X }
- X# endif BROADCAST
- X
- Xget_response:
- X namelen = DAEMON_SIZE;
- X vec.sv_handler = sigalrm;
- X vec.sv_mask = 0;
- X vec.sv_flags = SV_INTERRUPT;
- X (void) sigvec(SIGALRM, &vec, &ovec);
- X errno = 0;
- X (void) alarm(1);
- X# ifndef OLDIPC
- X if (recvfrom(test_socket, (char *) &msg, sizeof msg, 0,
- X (struct sockaddr *) &Daemon, &namelen) < 0)
- X# else OLDIPC
- X if (receive(test_socket, (struct sockaddr *) &Daemon, &msg,
- X sizeof msg) < 0)
- X# endif OLDIPC
- X {
- X if (errno != EINTR) {
- X perror("recvfrom");
- X leave(1, "recvfrom");
- X /* NOTREACHED */
- X }
- X (void) alarm(0);
- X (void) sigvec (SIGALRM, &ovec, NULL);
- X Daemon.sin_family = SOCK_FAMILY;
- X Daemon.sin_port = htons(Sock_port);
- X Daemon.sin_addr = local_address;
- X if (!do_startup)
- X Daemon.sin_port = 0;
- X else
- X start_driver();
- X }
- X else {
- X (void) alarm(0);
- X (void) sigvec (SIGALRM, &ovec, NULL);
- X Daemon.sin_port = htons(Sock_port);
- X }
- X (void) close(test_socket);
- X initial = FALSE;
- X}
- X# endif INTERNET
- X
- Xstart_driver()
- X{
- X register int procid;
- X
- X# ifdef MONITOR
- X if (Am_monitor) {
- X leave(1, "No one playing.");
- X /* NOTREACHED */
- X }
- X# endif MONITOR
- X
- X# ifdef INTERNET
- X if (Sock_host != NULL) {
- X sleep(3);
- X return 0;
- X }
- X# endif INTERNET
- X
- X if (!daemon_player)
- X {
- X mvcur(cur_row, cur_col, 23, 0);
- X put_str("Starting...");
- X fflush(stdout);
- X }
- X cur_row = 23;
- X cur_col = 0;
- X procid = vfork();
- X if (procid == -1) {
- X perror("fork");
- X leave(1, "fork failed.");
- X }
- X if (procid == 0) {
- X (void) signal(SIGINT, SIG_IGN);
- X (void) close(Socket);
- X execl(Driver, "HUNT", NULL);
- X /* only get here if exec failed */
- X kill(getppid(), SIGEMT); /* tell mom */
- X _exit(1);
- X }
- X if (!daemon_player)
- X {
- X mvcur(cur_row, cur_col, 23, 0);
- X put_str("Connecting...");
- X fflush(stdout);
- X }
- X cur_row = 23;
- X cur_col = 0;
- X return 0;
- X}
- X
- X/*
- X * bad_con:
- X * We had a bad connection. For the moment we assume that this
- X * means the game is full.
- X */
- Xbad_con()
- X{
- X leave(1, "The game is full. Sorry.");
- X /* NOTREACHED */
- X}
- X
- X/*
- X * dumpit:
- X * Handle a core dump signal by not dumping core, just leaving,
- X * so we end up with a core dump from the driver
- X */
- Xdumpit()
- X{
- X (void) kill(Master_pid, SIGQUIT);
- X (void) chdir("coredump");
- X abort();
- X}
- X
- X/*
- X * sigterm:
- X * Handle a terminate signal
- X */
- Xsigterm()
- X{
- X leave(0, NULL);
- X /* NOTREACHED */
- X}
- X
- X
- X/*
- X * sigemt:
- X * Handle a emt signal - shouldn't happen on vaxes(?)
- X */
- Xsigemt()
- X{
- X leave(1, "Unable to start driver. Try again.");
- X /* NOTREACHED */
- X}
- X
- X# ifdef INTERNET
- X/*
- X * sigalrm:
- X * Handle an alarm signal
- X */
- Xsigalrm()
- X{
- X return;
- X}
- X# endif INTERNET
- X
- X/*
- X * rmnl:
- X * Remove a '\n' at the end of a string if there is one
- X */
- Xrmnl(s)
- Xchar *s;
- X{
- X register char *cp;
- X char *rindex();
- X
- X cp = rindex(s, '\n');
- X if (cp != NULL)
- X *cp = '\0';
- X}
- X
- X/*
- X * intr:
- X * Handle a interrupt signal
- X */
- Xintr()
- X{
- X if (!daemon_player)
- X {
- X register int ch;
- X register int explained;
- X register int y, x;
- X
- X (void) signal(SIGINT, SIG_IGN);
- X y = cur_row;
- X x = cur_col;
- X mvcur(cur_row, cur_col, 23, 0);
- X cur_row = 23;
- X cur_col = 0;
- X put_str("Really quit? ");
- X clear_eol();
- X fflush(stdout);
- X explained = FALSE;
- X for (;;) {
- X ch = getchar();
- X if (isupper(ch))
- X ch = tolower(ch);
- X if (ch == 'y') {
- X (void) write(Socket, "q", 1);
- X (void) close(Socket);
- X leave(0, NULL);
- X }
- X else if (ch == 'n') {
- X (void) signal(SIGINT, intr);
- X mvcur(cur_row, cur_col, y, x);
- X cur_row = y;
- X cur_col = x;
- X fflush(stdout);
- X return;
- X }
- X if (!explained) {
- X put_str("(Y or N) ");
- X fflush(stdout);
- X explained = TRUE;
- X }
- X (void) putchar(CTRL(G));
- X (void) fflush(stdout);
- X }
- X }
- X else
- X {
- X leave (0, NULL);
- X }
- X}
- X
- X/*
- X * leave:
- X * Leave the game somewhat gracefully, restoring all current
- X * tty stats.
- X */
- Xleave(eval, mesg)
- Xint eval;
- Xchar *mesg;
- X{
- X if (!daemon_player)
- X {
- X mvcur(cur_row, cur_col, 23, 0);
- X if (mesg == NULL)
- X clear_eol();
- X else {
- X put_str(mesg);
- X clear_eol();
- X putchar('\n');
- X fflush(stdout); /* flush in case VE changes pages */
- X }
- X resetty();
- X _puts(VE);
- X _puts(TE);
- X }
- X if (eval == -1)
- X /* abort(); */ return;
- X exit(eval);
- X}
- X
- X/*
- X * tstp:
- X * Handle stop and start signals
- X */
- Xtstp()
- X{
- X static struct sgttyb tty;
- X int y, x;
- X
- X if (!daemon_player)
- X {
- X
- X tty = _tty;
- X y = cur_row;
- X x = cur_col;
- X mvcur(cur_row, cur_col, 23, 0);
- X cur_row = 23;
- X cur_col = 0;
- X _puts(VE);
- X _puts(TE);
- X (void) fflush(stdout);
- X resetty();
- X }
- X (void) kill(getpid(), SIGSTOP);
- X (void) signal(SIGTSTP, tstp);
- X if (!daemon_player)
- X {
- X _tty = tty;
- X (void) stty(_tty_ch, &_tty);
- X _puts(TI);
- X _puts(VS);
- X cur_row = y;
- X cur_col = x;
- X _puts(tgoto(CM, cur_row, cur_col));
- X redraw_screen();
- X fflush(stdout);
- X }
- X}
- X
- Xenv_init()
- X{
- X register int i;
- X char *envp, *envname, *s, *index();
- X
- X for (i = 0; i < 256; i++)
- X map_key[i] = (char) i;
- X
- X envname = NULL;
- X if ((envp = getenv("HUNT")) != NULL) {
- X while ((s = index(envp, '=')) != NULL) {
- X if (strncmp(envp, "name=", s - envp + 1) == 0) {
- X envname = s + 1;
- X if ((s = index(envp, ',')) == NULL) {
- X *envp = '\0';
- X break;
- X }
- X *s = '\0';
- X envp = s + 1;
- X } /* must be last option */
- X else if (strncmp(envp, "mapkey=", s - envp + 1) == 0) {
- X for (s = s + 1; *s != '\0'; s += 2) {
- X map_key[(unsigned int) *s] = *(s + 1);
- X if (*(s + 1) == '\0') {
- X break;
- X }
- X }
- X *envp = '\0';
- X break;
- X } else {
- X *s = '\0';
- X printf("unknown option %s\n", envp);
- X if ((s = index(envp, ',')) == NULL) {
- X *envp = '\0';
- X break;
- X }
- X envp = s + 1;
- X }
- X }
- X if (*envp != '\0')
- X if (envname == NULL)
- X envname = envp;
- X else
- X printf("unknown option %s\n", envp);
- X }
- X if (envname != NULL) {
- X (void) strcpy(name, envname);
- X printf("Entering as '%s'\n", envname);
- X }
- X else if (name[0] == '\0') {
- X printf("Enter your code name: ");
- X if (fgets(name, sizeof name, stdin) == NULL)
- X exit(1);
- X }
- X rmnl(name);
- X}
- END_OF_FILE
- if test 16374 -ne `wc -c <'hunt.c'`; then
- echo shar: \"'hunt.c'\" unpacked with wrong size!
- fi
- # end of 'hunt.c'
- fi
- if test -f 'shots.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'shots.c'\"
- else
- echo shar: Extracting \"'shots.c'\" \(16569 characters\)
- sed "s/^X//" >'shots.c' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1985 Regents of the University of California.
- X * All rights reserved.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that the above copyright notice and this paragraph are
- X * duplicated in all such forms and that any documentation,
- X * advertising materials, and other materials related to such
- X * distribution and use acknowledge that the software was developed
- X * by the University of California, Berkeley. The name of the
- X * University may not be used to endorse or promote products derived
- X * from this software without specific prior written permission.
- X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X */
- X
- X#ifndef lint
- Xstatic char sccsid[] = "@(#)shots.c 5.2 (Berkeley) 6/27/88";
- X#endif /* not lint */
- X
- X/*
- X * Hunt
- X * Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
- X * San Francisco, California
- X */
- X
- X# include "hunt.h"
- X# include <signal.h>
- X
- X# define PLUS_DELTA(x, max) if (x < max) x++; else x--
- X# define MINUS_DELTA(x, min) if (x > min) x--; else x++
- X
- X/*
- X * moveshots:
- X * Move the shots already in the air, taking explosions into account
- X */
- Xmoveshots()
- X{
- X register BULLET *bp, *next;
- X register PLAYER *pp;
- X register int x, y;
- X register BULLET *blist;
- X register int i;
- X
- X rollexpl();
- X if (Bullets == NULL)
- X goto ret;
- X
- X /*
- X * First we move through the bullet list BULSPD times, looking
- X * for things we may have run into. If we do run into
- X * something, we set up the explosion and disappear, checking
- X * for damage to any player who got in the way.
- X */
- X
- X blist = Bullets;
- X Bullets = NULL;
- X for (bp = blist; bp != NULL; bp = next) {
- X next = bp->b_next;
- X x = bp->b_x;
- X y = bp->b_y;
- X Maze[y][x] = bp->b_over;
- X for (pp = Player; pp < End_player; pp++)
- X check(pp, y, x);
- X# ifdef MONITOR
- X for (pp = Monitor; pp < End_monitor; pp++)
- X check(pp, y, x);
- X# endif MONITOR
- X
- X for (i = 0; i < BULSPD; i++) {
- X if (bp->b_expl)
- X break;
- X
- X x = bp->b_x;
- X y = bp->b_y;
- X
- X switch (bp->b_face) {
- X case LEFTS:
- X x--;
- X break;
- X case RIGHT:
- X x++;
- X break;
- X case ABOVE:
- X y--;
- X break;
- X case BELOW:
- X y++;
- X break;
- X }
- X
- X switch (Maze[y][x]) {
- X case SHOT:
- X if (rand_num(100) < 5) {
- X zapshot(Bullets, bp);
- X zapshot(next, bp);
- X }
- X break;
- X case GRENADE:
- X if (rand_num(100) < 10) {
- X zapshot(Bullets, bp);
- X zapshot(next, bp);
- X }
- X break;
- X# ifdef REFLECT
- X case WALL4: /* reflecting walls */
- X switch (bp->b_face) {
- X case LEFTS:
- X bp->b_face = BELOW;
- X break;
- X case RIGHT:
- X bp->b_face = ABOVE;
- X break;
- X case ABOVE:
- X bp->b_face = RIGHT;
- X break;
- X case BELOW:
- X bp->b_face = LEFTS;
- X break;
- X }
- X Maze[y][x] = WALL5;
- X# ifdef MONITOR
- X for (pp = Monitor; pp < End_monitor; pp++)
- X check(pp, y, x);
- X# endif MONITOR
- X break;
- X case WALL5:
- X switch (bp->b_face) {
- X case LEFTS:
- X bp->b_face = ABOVE;
- X break;
- X case RIGHT:
- X bp->b_face = BELOW;
- X break;
- X case ABOVE:
- X bp->b_face = LEFTS;
- X break;
- X case BELOW:
- X bp->b_face = RIGHT;
- X break;
- X }
- X Maze[y][x] = WALL4;
- X# ifdef MONITOR
- X for (pp = Monitor; pp < End_monitor; pp++)
- X check(pp, y, x);
- X# endif MONITOR
- X break;
- X# endif REFLECT
- X# ifdef RANDOM
- X case DOOR:
- X switch (rand_num(4)) {
- X case 0:
- X bp->b_face = ABOVE;
- X break;
- X case 1:
- X bp->b_face = BELOW;
- X break;
- X case 2:
- X bp->b_face = LEFTS;
- X break;
- X case 3:
- X bp->b_face = RIGHT;
- X break;
- X }
- X break;
- X# endif RANDOM
- X case LEFTS:
- X case RIGHT:
- X case BELOW:
- X case ABOVE:
- X# ifdef FLY
- X case FLYER:
- X# endif FLY
- X /*
- X * give the person a chance to catch a
- X * grenade if s/he is facing it
- X */
- X if (rand_num(100) < 10
- X && opposite(bp->b_face, Maze[y][x])) {
- X if (bp->b_owner != NULL)
- X message(bp->b_owner,
- X "Your charge was absorbed!");
- X pp = play_at(y, x);
- X pp->p_ammo += bp->b_charge;
- X (void) sprintf(Buf,
- X "Absorbed charge (good shield!)");
- X message(pp, Buf);
- X free((char *) bp);
- X (void) sprintf(Buf, "%3d", pp->p_ammo);
- X cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
- X outstr(pp, Buf, 3);
- X goto next_bullet;
- X }
- X /* FALLTHROUGH */
- X# ifndef RANDOM
- X case DOOR:
- X# endif RANDOM
- X case WALL1:
- X case WALL2:
- X case WALL3:
- X bp->b_expl = TRUE;
- X break;
- X }
- X
- X bp->b_x = x;
- X bp->b_y = y;
- X }
- X
- X bp->b_next = Bullets;
- X Bullets = bp;
- Xnext_bullet:
- X ;
- X }
- X
- X blist = Bullets;
- X Bullets = NULL;
- X for (bp = blist; bp != NULL; bp = next) {
- X next = bp->b_next;
- X if (!bp->b_expl) {
- X save_bullet(bp);
- X# ifdef MONITOR
- X for (pp = Monitor; pp < End_monitor; pp++)
- X check(pp, bp->b_y, bp->b_x);
- X# endif MONITOR
- X continue;
- X }
- X
- X chkshot(bp);
- X free((char *) bp);
- X }
- X for (pp = Player; pp < End_player; pp++)
- X Maze[pp->p_y][pp->p_x] = pp->p_face;
- Xret:
- X for (pp = Player; pp < End_player; pp++) {
- X# ifdef FLY
- X if (pp->p_flying >= 0) {
- X Maze[pp->p_y][pp->p_x] = pp->p_over;
- X x = pp->p_x + pp->p_flyx;
- X y = pp->p_y + pp->p_flyy;
- X if (x < 1) {
- X x = 1 - x;
- X pp->p_flyx = -pp->p_flyx;
- X }
- X else if (x > WIDTH - 2) {
- X x = (WIDTH - 2) - (x - (WIDTH - 2));
- X pp->p_flyx = -pp->p_flyx;
- X }
- X if (y < 1) {
- X y = 1 - y;
- X pp->p_flyy = -pp->p_flyy;
- X }
- X else if (y > HEIGHT - 2) {
- X y = (HEIGHT - 2) - (y - (HEIGHT - 2));
- X pp->p_flyy = -pp->p_flyy;
- X }
- Xagain: switch (Maze[y][x]) {
- X case LEFTS:
- X case RIGHT:
- X case ABOVE:
- X case BELOW:
- X case FLYER:
- X switch (rand_num(4)) {
- X case 0:
- X PLUS_DELTA(x, WIDTH - 2);
- X break;
- X case 1:
- X MINUS_DELTA(x, 1);
- X break;
- X case 2:
- X PLUS_DELTA(y, HEIGHT - 2);
- X break;
- X case 3:
- X MINUS_DELTA(y, 1);
- X break;
- X }
- X goto again;
- X case WALL1:
- X case WALL2:
- X case WALL3:
- X# ifdef REFLECT
- X case WALL4:
- X case WALL5:
- X# endif REFLECT
- X# ifdef RANDOM
- X case DOOR:
- X# endif RANDOM
- X if (pp->p_flying == 0)
- X pp->p_flying++;
- X break;
- X case MINE:
- X checkdam(pp, NULL, NULL, MINDAM, MINE);
- X Maze[y][x] = SPACE;
- X break;
- X case GMINE:
- X checkdam(pp, NULL, NULL, MINDAM, GMINE);
- X checkdam(pp, NULL, NULL, MINDAM, GMINE);
- X Maze[y][x] = SPACE;
- X break;
- X }
- X pp->p_y = y;
- X pp->p_x = x;
- X pp->p_over = Maze[y][x];
- X if (pp->p_flying-- == 0) {
- X checkdam(pp, NULL, NULL,
- X rand_num(pp->p_damage / 5), FALL);
- X rand_face(pp);
- X showstat(pp);
- X }
- X Maze[y][x] = pp->p_face;
- X showexpl(y, x, pp->p_face);
- X }
- X# endif FLY
- X sendcom(pp, REFRESH); /* Flush out the explosions */
- X look(pp);
- X sendcom(pp, REFRESH);
- X }
- X# ifdef MONITOR
- X for (pp = Monitor; pp < End_monitor; pp++)
- X sendcom(pp, REFRESH);
- X# endif MONITOR
- X
- X# ifdef CONSTANT_MOVE
- X if (Bullets != NULL) {
- X bul_alarm(1);
- X return;
- X }
- X for (i = 0; i < EXPLEN; i++)
- X if (Expl[i] != NULL) {
- X bul_alarm(1);
- X return;
- X }
- X bul_alarm(0);
- X# endif CONSTANT_MOVE
- X
- X return;
- X}
- X
- Xsave_bullet(bp)
- Xregister BULLET *bp;
- X{
- X bp->b_over = Maze[bp->b_y][bp->b_x];
- X switch (bp->b_over) {
- X case SHOT:
- X case GRENADE:
- X case SATCHEL:
- X case BOMB:
- X# ifdef OOZE
- X case SLIME:
- X# ifdef VOLCANO
- X case LAVA:
- X# endif VOLCANO
- X# endif OOZE
- X find_under(Bullets, bp);
- X break;
- X }
- X
- X switch (bp->b_over) {
- X case LEFTS:
- X case RIGHT:
- X case ABOVE:
- X case BELOW:
- X# ifdef FLY
- X case FLYER:
- X# endif FLY
- X mark_player(bp);
- X break;
- X
- X default:
- X Maze[bp->b_y][bp->b_x] = bp->b_type;
- X break;
- X }
- X
- X bp->b_next = Bullets;
- X Bullets = bp;
- X}
- X
- X/*
- X * chkshot
- X * Handle explosions
- X */
- Xchkshot(bp)
- Xregister BULLET *bp;
- X{
- X register int y, x;
- X register int dy, dx, absdy;
- X register int delta, damage;
- X register char expl;
- X register PLAYER *pp;
- X
- X switch (bp->b_type) {
- X case SHOT:
- X case MINE:
- X delta = 0;
- X break;
- X case GRENADE:
- X case GMINE:
- X delta = 1;
- X break;
- X case SATCHEL:
- X delta = 2;
- X break;
- X case BOMB:
- X delta = 3;
- X break;
- X# ifdef OOZE
- X case SLIME:
- X# ifdef VOLCANO
- X case LAVA:
- X# endif VOLCANO
- X chkslime(bp);
- X return;
- X# endif OOZE
- X }
- X for (y = bp->b_y - delta; y <= bp->b_y + delta; y++) {
- X if (y < 0 || y >= HEIGHT)
- X continue;
- X dy = y - bp->b_y;
- X absdy = (dy < 0) ? -dy : dy;
- X for (x = bp->b_x - delta; x <= bp->b_x + delta; x++) {
- X if (x < 0 || x >= WIDTH)
- X continue;
- X dx = x - bp->b_x;
- X if (dx == 0)
- X expl = (dy == 0) ? '*' : '|';
- X else if (dy == 0)
- X expl = '-';
- X else if (dx == dy)
- X expl = '\\';
- X else if (dx == -dy)
- X expl = '/';
- X else
- X expl = '*';
- X showexpl(y, x, expl);
- X switch (Maze[y][x]) {
- X case LEFTS:
- X case RIGHT:
- X case ABOVE:
- X case BELOW:
- X# ifdef FLY
- X case FLYER:
- X# endif FLY
- X if (dx < 0)
- X dx = -dx;
- X if (absdy > dx)
- X damage = delta - absdy + 1;
- X else
- X damage = delta - dx + 1;
- X pp = play_at(y, x);
- X while (damage-- > 0)
- X checkdam(pp, bp->b_owner, bp->b_score,
- X MINDAM, bp->b_type);
- X break;
- X case GMINE:
- X case MINE:
- X add_shot((Maze[y][x] == GMINE) ?
- X GRENADE : SHOT,
- X y, x, LEFTS,
- X (Maze[y][x] == GMINE) ?
- X GRENREQ : BULREQ,
- X (PLAYER *) NULL, TRUE, SPACE);
- X Maze[y][x] = SPACE;
- X break;
- X }
- X }
- X }
- X}
- X
- X# ifdef OOZE
- X/*
- X * chkslime:
- X * handle slime shot exploding
- X */
- Xchkslime(bp)
- Xregister BULLET *bp;
- X{
- X register BULLET *nbp;
- X
- X switch (Maze[bp->b_y][bp->b_x]) {
- X case WALL1:
- X case WALL2:
- X case WALL3:
- X# ifdef REFLECT
- X case WALL4:
- X case WALL5:
- X# endif REFLECT
- X# ifdef RANDOM
- X case DOOR:
- X# endif RANDOM
- X switch (bp->b_face) {
- X case LEFTS:
- X bp->b_x++;
- X break;
- X case RIGHT:
- X bp->b_x--;
- X break;
- X case ABOVE:
- X bp->b_y++;
- X break;
- X case BELOW:
- X bp->b_y--;
- X break;
- X }
- X break;
- X }
- X nbp = (BULLET *) malloc(sizeof (BULLET));
- X *nbp = *bp;
- X# ifdef VOLCANO
- X moveslime(nbp, nbp->b_type == SLIME ? SLIMESPEED : LAVASPEED);
- X# else VOLCANO
- X moveslime(nbp, SLIMESPEED);
- X# endif VOLCANO
- X}
- X
- X/*
- X * moveslime:
- X * move the given slime shot speed times and add it back if
- X * it hasn't fizzled yet
- X */
- Xmoveslime(bp, speed)
- Xregister BULLET *bp;
- Xregister int speed;
- X{
- X register int i, j, dirmask, count;
- X register PLAYER *pp;
- X register BULLET *nbp;
- X
- X if (speed == 0) {
- X if (bp->b_charge <= 0)
- X free((char *) bp);
- X else
- X save_bullet(bp);
- X return;
- X }
- X
- X# ifdef VOLCANO
- X showexpl(bp->b_y, bp->b_x, bp->b_type == LAVA ? LAVA : '*');
- X# else VOLCANO
- X showexpl(bp->b_y, bp->b_x, '*');
- X# endif VOLCANO
- X switch (Maze[bp->b_y][bp->b_x]) {
- X case LEFTS:
- X case RIGHT:
- X case ABOVE:
- X case BELOW:
- X# ifdef FLY
- X case FLYER:
- X# endif FLY
- X pp = play_at(bp->b_y, bp->b_x);
- X message(pp, "You've been slimed.");
- X checkdam(pp, bp->b_owner, bp->b_score, MINDAM, bp->b_type);
- X break;
- X }
- X
- X if (--bp->b_charge <= 0) {
- X free((char *) bp);
- X return;
- X }
- X
- X dirmask = 0;
- X count = 0;
- X switch (bp->b_face) {
- X case LEFTS:
- X if (!iswall(bp->b_y, bp->b_x - 1))
- X dirmask |= WEST, count++;
- X if (!iswall(bp->b_y - 1, bp->b_x))
- X dirmask |= NORTH, count++;
- X if (!iswall(bp->b_y + 1, bp->b_x))
- X dirmask |= SOUTH, count++;
- X if (dirmask == 0)
- X if (!iswall(bp->b_y, bp->b_x + 1))
- X dirmask |= EAST, count++;
- X break;
- X case RIGHT:
- X if (!iswall(bp->b_y, bp->b_x + 1))
- X dirmask |= EAST, count++;
- X if (!iswall(bp->b_y - 1, bp->b_x))
- X dirmask |= NORTH, count++;
- X if (!iswall(bp->b_y + 1, bp->b_x))
- X dirmask |= SOUTH, count++;
- X if (dirmask == 0)
- X if (!iswall(bp->b_y, bp->b_x - 1))
- X dirmask |= WEST, count++;
- X break;
- X case ABOVE:
- X if (!iswall(bp->b_y - 1, bp->b_x))
- X dirmask |= NORTH, count++;
- X if (!iswall(bp->b_y, bp->b_x - 1))
- X dirmask |= WEST, count++;
- X if (!iswall(bp->b_y, bp->b_x + 1))
- X dirmask |= EAST, count++;
- X if (dirmask == 0)
- X if (!iswall(bp->b_y + 1, bp->b_x))
- X dirmask |= SOUTH, count++;
- X break;
- X case BELOW:
- X if (!iswall(bp->b_y + 1, bp->b_x))
- X dirmask |= SOUTH, count++;
- X if (!iswall(bp->b_y, bp->b_x - 1))
- X dirmask |= WEST, count++;
- X if (!iswall(bp->b_y, bp->b_x + 1))
- X dirmask |= EAST, count++;
- X if (dirmask == 0)
- X if (!iswall(bp->b_y - 1, bp->b_x))
- X dirmask |= NORTH, count++;
- X break;
- X }
- X if (count == 0) {
- X /*
- X * No place to go. Just sit here for a while and wait
- X * for adjacent squares to clear out.
- X */
- X save_bullet(bp);
- X return;
- X }
- X if (bp->b_charge < count) {
- X /* Only bp->b_charge paths may be taken */
- X while (count > bp->b_charge) {
- X if (dirmask & WEST)
- X dirmask &= ~WEST;
- X else if (dirmask & EAST)
- X dirmask &= ~EAST;
- X else if (dirmask & NORTH)
- X dirmask &= ~NORTH;
- X else if (dirmask & SOUTH)
- X dirmask &= ~SOUTH;
- X count--;
- X }
- X }
- X
- X i = bp->b_charge / count;
- X j = bp->b_charge % count;
- X if (dirmask & WEST) {
- X count--;
- X nbp = create_shot(bp->b_type, bp->b_y, bp->b_x - 1, LEFTS,
- X i, bp->b_owner, bp->b_score, TRUE, SPACE);
- X moveslime(nbp, speed - 1);
- X }
- X if (dirmask & EAST) {
- X count--;
- X nbp = create_shot(bp->b_type, bp->b_y, bp->b_x + 1, RIGHT,
- X (count < j) ? i + 1 : i, bp->b_owner, bp->b_score,
- X TRUE, SPACE);
- X moveslime(nbp, speed - 1);
- X }
- X if (dirmask & NORTH) {
- X count--;
- X nbp = create_shot(bp->b_type, bp->b_y - 1, bp->b_x, ABOVE,
- X (count < j) ? i + 1 : i, bp->b_owner, bp->b_score,
- X TRUE, SPACE);
- X moveslime(nbp, speed - 1);
- X }
- X if (dirmask & SOUTH) {
- X count--;
- X nbp = create_shot(bp->b_type, bp->b_y + 1, bp->b_x, BELOW,
- X (count < j) ? i + 1 : i, bp->b_owner, bp->b_score,
- X TRUE, SPACE);
- X moveslime(nbp, speed - 1);
- X }
- X
- X free((char *) bp);
- X}
- X
- X/*
- X * iswall:
- X * returns whether the given location is a wall
- X */
- Xiswall(y, x)
- Xregister int y, x;
- X{
- X if (y < 0 || x < 0 || y >= HEIGHT || x >= WIDTH)
- X return TRUE;
- X switch (Maze[y][x]) {
- X case WALL1:
- X case WALL2:
- X case WALL3:
- X# ifdef REFLECT
- X case WALL4:
- X case WALL5:
- X# endif REFLECT
- X# ifdef RANDOM
- X case DOOR:
- X# endif RANDOM
- X# ifdef VOLCANO
- X case LAVA:
- X# endif VOLCANO
- X return TRUE;
- X }
- X return FALSE;
- X}
- X# endif OOZE
- X
- X/*
- X * zapshot:
- X * Take a shot out of the air.
- X */
- Xzapshot(blist, obp)
- Xregister BULLET *blist, *obp;
- X{
- X register BULLET *bp;
- X register FLAG explode;
- X
- X explode = FALSE;
- X for (bp = blist; bp != NULL; bp = bp->b_next) {
- X if (bp->b_x != obp->b_x || bp->b_y != obp->b_y)
- X continue;
- X if (bp->b_face == obp->b_face)
- X continue;
- X explode = TRUE;
- X break;
- X }
- X if (!explode)
- X return;
- X explshot(blist, obp->b_y, obp->b_x);
- X}
- X
- X/*
- X * explshot -
- X * Make all shots at this location blow up
- X */
- Xexplshot(blist, y, x)
- Xregister BULLET *blist;
- Xregister int y, x;
- X{
- X register BULLET *bp;
- X
- X for (bp = blist; bp != NULL; bp = bp->b_next)
- X if (bp->b_x == x && bp->b_y == y) {
- X bp->b_expl = TRUE;
- X if (bp->b_owner != NULL)
- X message(bp->b_owner, "Shot intercepted");
- X }
- X}
- X
- X/*
- X * play_at:
- X * Return a pointer to the player at the given location
- X */
- XPLAYER *
- Xplay_at(y, x)
- Xregister int y, x;
- X{
- X register PLAYER *pp;
- X
- X for (pp = Player; pp < End_player; pp++)
- X if (pp->p_x == x && pp->p_y == y)
- X return pp;
- X fprintf(stderr, "driver: couldn't find player at (%d,%d)\n", x, y);
- X abort();
- X /* NOTREACHED */
- X}
- X
- X/*
- X * opposite:
- X * Return TRUE if the bullet direction faces the opposite direction
- X * of the player in the maze
- X */
- Xopposite(face, dir)
- Xint face;
- Xchar dir;
- X{
- X switch (face) {
- X case LEFTS:
- X return (dir == RIGHT);
- X case RIGHT:
- X return (dir == LEFTS);
- X case ABOVE:
- X return (dir == BELOW);
- X case BELOW:
- X return (dir == ABOVE);
- X default:
- X return FALSE;
- X }
- X}
- X
- X/*
- X * is_bullet:
- X * Is there a bullet at the given coordinates? If so, return
- X * a pointer to the bullet, otherwise return NULL
- X */
- XBULLET *
- Xis_bullet(y, x)
- Xregister int y, x;
- X{
- X register BULLET *bp;
- X
- X for (bp = Bullets; bp != NULL; bp = bp->b_next)
- X if (bp->b_y == y && bp->b_x == x)
- X return bp;
- X return NULL;
- X}
- X
- X/*
- X * fixshots:
- X * change the underlying character of the shots at a location
- X * to the given character.
- X */
- Xfixshots(y, x, over)
- Xregister int y, x;
- Xchar over;
- X{
- X register BULLET *bp;
- X
- X for (bp = Bullets; bp != NULL; bp = bp->b_next)
- X if (bp->b_y == y && bp->b_x == x)
- X bp->b_over = over;
- X}
- X
- X/*
- X * find_under:
- X * find the underlying character for a bullet when it lands
- X * on another bullet.
- X */
- Xfind_under(blist, bp)
- Xregister BULLET *blist, *bp;
- X{
- X register BULLET *nbp;
- X
- X for (nbp = blist; nbp != NULL; nbp = nbp->b_next)
- X if (bp->b_y == nbp->b_y && bp->b_x == nbp->b_x) {
- X bp->b_over = nbp->b_over;
- X break;
- X }
- X}
- X
- X/*
- X * mark_player:
- X * mark a player as under a shot
- X */
- Xmark_player(bp)
- Xregister BULLET *bp;
- X{
- X register PLAYER *pp;
- X
- X for (pp = Player; pp < End_player; pp++)
- X if (pp->p_y == bp->b_y && pp->p_x == bp->b_x) {
- X pp->p_undershot = TRUE;
- X break;
- X }
- X}
- END_OF_FILE
- if test 16569 -ne `wc -c <'shots.c'`; then
- echo shar: \"'shots.c'\" unpacked with wrong size!
- fi
- # end of 'shots.c'
- fi
- echo shar: End of archive 2 \(of 4\).
- cp /dev/null ark2isdone
- MISSING=""
- for I in 1 2 3 4 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 4 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-