mirror of
https://github.com/vattam/BSDGames.git
synced 2025-12-20 19:04:49 +00:00
Initial revision
git-svn-id: file:///srv/svn/joey/bsdgames-trunk@5086 a4a2c43b-8ac3-0310-8836-e0e880c912e2
This commit is contained in:
8
hunt/huntd/Makefile.bsd
Normal file
8
hunt/huntd/Makefile.bsd
Normal file
@@ -0,0 +1,8 @@
|
||||
# $NetBSD: Makefile,v 1.1 1997/10/04 09:11:21 mrg Exp $
|
||||
|
||||
PROG= huntd
|
||||
SRCS= answer.c ctl.c ctl_transact.c draw.c driver.c execute.c expl.c \
|
||||
extern.c faketalk.c get_names.c makemaze.c pathname.c shots.c terminal.c
|
||||
MAN= huntd.6
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
12
hunt/huntd/Makefrag
Normal file
12
hunt/huntd/Makefrag
Normal file
@@ -0,0 +1,12 @@
|
||||
# Makefrag - makefile fragment for hunt/huntd
|
||||
|
||||
include hunt/Makeconfig
|
||||
|
||||
hunt_huntd_DEFS := $(hunt_DEFS)
|
||||
hunt_huntd_DIRS := $(SBINDIR) $(MAN6DIR)
|
||||
|
||||
hunt_huntd_all: hunt/huntd/huntd hunt/huntd/huntd.6
|
||||
|
||||
hunt_huntd_install: hunt_huntd_all
|
||||
$(INSTALL_DAEMON) hunt/huntd/huntd $(INSTALL_PREFIX)$(SBINDIR)/huntd
|
||||
$(INSTALL_MANUAL) hunt/huntd/huntd.6
|
||||
402
hunt/huntd/answer.c
Normal file
402
hunt/huntd/answer.c
Normal file
@@ -0,0 +1,402 @@
|
||||
/* $NetBSD: answer.c,v 1.3 1997/10/10 16:32:50 lukem Exp $ */
|
||||
/*
|
||||
* Hunt
|
||||
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
* San Francisco, California
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: answer.c,v 1.3 1997/10/10 16:32:50 lukem Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
# include <ctype.h>
|
||||
# include <errno.h>
|
||||
# include <fcntl.h>
|
||||
# include <stdlib.h>
|
||||
# include <unistd.h>
|
||||
# include <sys/time.h>
|
||||
# include "hunt.h"
|
||||
|
||||
# define SCOREDECAY 15
|
||||
|
||||
static char Ttyname[NAMELEN];
|
||||
|
||||
int
|
||||
answer()
|
||||
{
|
||||
PLAYER *pp;
|
||||
int newsock;
|
||||
static u_long mode;
|
||||
static char name[NAMELEN];
|
||||
static char team;
|
||||
static int enter_status;
|
||||
static int socklen;
|
||||
static u_long machine;
|
||||
static u_long uid;
|
||||
static SOCKET sockstruct;
|
||||
char *cp1, *cp2;
|
||||
int flags;
|
||||
long version;
|
||||
|
||||
# ifdef INTERNET
|
||||
socklen = sizeof sockstruct;
|
||||
# else
|
||||
socklen = sizeof sockstruct - 1;
|
||||
# endif
|
||||
errno = 0;
|
||||
newsock = accept(Socket, (struct sockaddr *) &sockstruct, &socklen);
|
||||
if (newsock < 0)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
return FALSE;
|
||||
# ifdef LOG
|
||||
syslog(LOG_ERR, "accept: %m");
|
||||
# else
|
||||
perror("accept");
|
||||
# endif
|
||||
cleanup(1);
|
||||
}
|
||||
|
||||
# ifdef INTERNET
|
||||
machine = ntohl(((struct sockaddr_in *) &sockstruct)->sin_addr.s_addr);
|
||||
# else
|
||||
if (machine == 0)
|
||||
machine = gethostid();
|
||||
# endif
|
||||
version = htonl((u_int32_t) HUNT_VERSION);
|
||||
(void) write(newsock, (char *) &version, LONGLEN);
|
||||
(void) read(newsock, (char *) &uid, LONGLEN);
|
||||
uid = ntohl((unsigned long) uid);
|
||||
(void) read(newsock, name, NAMELEN);
|
||||
(void) read(newsock, &team, 1);
|
||||
(void) read(newsock, (char *) &enter_status, LONGLEN);
|
||||
enter_status = ntohl((unsigned long) enter_status);
|
||||
(void) read(newsock, Ttyname, NAMELEN);
|
||||
(void) read(newsock, (char *) &mode, sizeof mode);
|
||||
mode = ntohl(mode);
|
||||
|
||||
/*
|
||||
* Turn off blocking I/O, so a slow or dead terminal won't stop
|
||||
* the game. All subsequent reads check how many bytes they read.
|
||||
*/
|
||||
flags = fcntl(newsock, F_GETFL, 0);
|
||||
flags |= O_NDELAY;
|
||||
(void) fcntl(newsock, F_SETFL, flags);
|
||||
|
||||
/*
|
||||
* Make sure the name contains only printable characters
|
||||
* since we use control characters for cursor control
|
||||
* between driver and player processes
|
||||
*/
|
||||
for (cp1 = cp2 = name; *cp1 != '\0'; cp1++)
|
||||
if (isprint(*cp1) || *cp1 == ' ')
|
||||
*cp2++ = *cp1;
|
||||
*cp2 = '\0';
|
||||
|
||||
# ifdef INTERNET
|
||||
if (mode == C_MESSAGE) {
|
||||
char buf[BUFSIZ + 1];
|
||||
int n;
|
||||
|
||||
if (team == ' ')
|
||||
(void) sprintf(buf, "%s: ", name);
|
||||
else
|
||||
(void) sprintf(buf, "%s[%c]: ", name, team);
|
||||
n = strlen(buf);
|
||||
for (pp = Player; pp < End_player; pp++) {
|
||||
cgoto(pp, HEIGHT, 0);
|
||||
outstr(pp, buf, n);
|
||||
}
|
||||
while ((n = read(newsock, buf, BUFSIZ)) > 0)
|
||||
for (pp = Player; pp < End_player; pp++)
|
||||
outstr(pp, buf, n);
|
||||
for (pp = Player; pp < End_player; pp++) {
|
||||
ce(pp);
|
||||
sendcom(pp, REFRESH);
|
||||
sendcom(pp, READY, 0);
|
||||
(void) fflush(pp->p_output);
|
||||
}
|
||||
(void) close(newsock);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
# endif
|
||||
# ifdef MONITOR
|
||||
if (mode == C_MONITOR)
|
||||
if (End_monitor < &Monitor[MAXMON])
|
||||
pp = End_monitor++;
|
||||
else {
|
||||
socklen = 0;
|
||||
(void) write(newsock, (char *) &socklen,
|
||||
sizeof socklen);
|
||||
(void) close(newsock);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
# endif
|
||||
if (End_player < &Player[MAXPL])
|
||||
pp = End_player++;
|
||||
else {
|
||||
socklen = 0;
|
||||
(void) write(newsock, (char *) &socklen,
|
||||
sizeof socklen);
|
||||
(void) close(newsock);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef MONITOR
|
||||
if (mode == C_MONITOR && team == ' ')
|
||||
team = '*';
|
||||
#endif
|
||||
pp->p_ident = get_ident(machine, uid, name, team);
|
||||
pp->p_output = fdopen(newsock, "w");
|
||||
pp->p_death[0] = '\0';
|
||||
pp->p_fd = newsock;
|
||||
FD_SET(pp->p_fd, &Fds_mask);
|
||||
if (pp->p_fd >= Num_fds)
|
||||
Num_fds = pp->p_fd + 1;
|
||||
|
||||
pp->p_y = 0;
|
||||
pp->p_x = 0;
|
||||
|
||||
# ifdef MONITOR
|
||||
if (mode == C_MONITOR)
|
||||
stmonitor(pp);
|
||||
else
|
||||
# endif
|
||||
stplayer(pp, enter_status);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
# ifdef MONITOR
|
||||
void
|
||||
stmonitor(pp)
|
||||
PLAYER *pp;
|
||||
{
|
||||
int line;
|
||||
PLAYER *npp;
|
||||
|
||||
memcpy(pp->p_maze, Maze, sizeof Maze);
|
||||
|
||||
drawmaze(pp);
|
||||
|
||||
(void) sprintf(Buf, "%5.5s%c%-10.10s %c", " ", stat_char(pp),
|
||||
pp->p_ident->i_name, pp->p_ident->i_team);
|
||||
line = STAT_MON_ROW + 1 + (pp - Monitor);
|
||||
for (npp = Player; npp < End_player; npp++) {
|
||||
cgoto(npp, line, STAT_NAME_COL);
|
||||
outstr(npp, Buf, STAT_NAME_LEN);
|
||||
}
|
||||
for (npp = Monitor; npp < End_monitor; npp++) {
|
||||
cgoto(npp, line, STAT_NAME_COL);
|
||||
outstr(npp, Buf, STAT_NAME_LEN);
|
||||
}
|
||||
|
||||
sendcom(pp, REFRESH);
|
||||
sendcom(pp, READY, 0);
|
||||
(void) fflush(pp->p_output);
|
||||
}
|
||||
# endif
|
||||
|
||||
void
|
||||
stplayer(newpp, enter_status)
|
||||
PLAYER *newpp;
|
||||
int enter_status;
|
||||
{
|
||||
int x, y;
|
||||
PLAYER *pp;
|
||||
|
||||
Nplayer++;
|
||||
|
||||
for (y = 0; y < UBOUND; y++)
|
||||
for (x = 0; x < WIDTH; x++)
|
||||
newpp->p_maze[y][x] = Maze[y][x];
|
||||
for ( ; y < DBOUND; y++) {
|
||||
for (x = 0; x < LBOUND; x++)
|
||||
newpp->p_maze[y][x] = Maze[y][x];
|
||||
for ( ; x < RBOUND; x++)
|
||||
newpp->p_maze[y][x] = SPACE;
|
||||
for ( ; x < WIDTH; x++)
|
||||
newpp->p_maze[y][x] = Maze[y][x];
|
||||
}
|
||||
for ( ; y < HEIGHT; y++)
|
||||
for (x = 0; x < WIDTH; x++)
|
||||
newpp->p_maze[y][x] = Maze[y][x];
|
||||
|
||||
do {
|
||||
x = rand_num(WIDTH - 1) + 1;
|
||||
y = rand_num(HEIGHT - 1) + 1;
|
||||
} while (Maze[y][x] != SPACE);
|
||||
newpp->p_over = SPACE;
|
||||
newpp->p_x = x;
|
||||
newpp->p_y = y;
|
||||
newpp->p_undershot = FALSE;
|
||||
|
||||
# ifdef FLY
|
||||
if (enter_status == Q_FLY) {
|
||||
newpp->p_flying = rand_num(20);
|
||||
newpp->p_flyx = 2 * rand_num(6) - 5;
|
||||
newpp->p_flyy = 2 * rand_num(6) - 5;
|
||||
newpp->p_face = FLYER;
|
||||
}
|
||||
else
|
||||
# endif
|
||||
{
|
||||
newpp->p_flying = -1;
|
||||
newpp->p_face = rand_dir();
|
||||
}
|
||||
newpp->p_damage = 0;
|
||||
newpp->p_damcap = MAXDAM;
|
||||
newpp->p_nchar = 0;
|
||||
newpp->p_ncount = 0;
|
||||
newpp->p_nexec = 0;
|
||||
newpp->p_ammo = ISHOTS;
|
||||
# ifdef BOOTS
|
||||
newpp->p_nboots = 0;
|
||||
# endif
|
||||
if (enter_status == Q_SCAN) {
|
||||
newpp->p_scan = SCANLEN;
|
||||
newpp->p_cloak = 0;
|
||||
}
|
||||
else {
|
||||
newpp->p_scan = 0;
|
||||
newpp->p_cloak = CLOAKLEN;
|
||||
}
|
||||
newpp->p_ncshot = 0;
|
||||
|
||||
do {
|
||||
x = rand_num(WIDTH - 1) + 1;
|
||||
y = rand_num(HEIGHT - 1) + 1;
|
||||
} while (Maze[y][x] != SPACE);
|
||||
Maze[y][x] = GMINE;
|
||||
# ifdef MONITOR
|
||||
for (pp = Monitor; pp < End_monitor; pp++)
|
||||
check(pp, y, x);
|
||||
# endif
|
||||
|
||||
do {
|
||||
x = rand_num(WIDTH - 1) + 1;
|
||||
y = rand_num(HEIGHT - 1) + 1;
|
||||
} while (Maze[y][x] != SPACE);
|
||||
Maze[y][x] = MINE;
|
||||
# ifdef MONITOR
|
||||
for (pp = Monitor; pp < End_monitor; pp++)
|
||||
check(pp, y, x);
|
||||
# endif
|
||||
|
||||
(void) sprintf(Buf, "%5.2f%c%-10.10s %c", newpp->p_ident->i_score,
|
||||
stat_char(newpp), newpp->p_ident->i_name,
|
||||
newpp->p_ident->i_team);
|
||||
y = STAT_PLAY_ROW + 1 + (newpp - Player);
|
||||
for (pp = Player; pp < End_player; pp++) {
|
||||
if (pp != newpp) {
|
||||
char smallbuf[10];
|
||||
|
||||
pp->p_ammo += NSHOTS;
|
||||
newpp->p_ammo += NSHOTS;
|
||||
cgoto(pp, y, STAT_NAME_COL);
|
||||
outstr(pp, Buf, STAT_NAME_LEN);
|
||||
(void) sprintf(smallbuf, "%3d", pp->p_ammo);
|
||||
cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
|
||||
outstr(pp, smallbuf, 3);
|
||||
}
|
||||
}
|
||||
# ifdef MONITOR
|
||||
for (pp = Monitor; pp < End_monitor; pp++) {
|
||||
cgoto(pp, y, STAT_NAME_COL);
|
||||
outstr(pp, Buf, STAT_NAME_LEN);
|
||||
}
|
||||
# endif
|
||||
|
||||
drawmaze(newpp);
|
||||
drawplayer(newpp, TRUE);
|
||||
look(newpp);
|
||||
# ifdef FLY
|
||||
if (enter_status == Q_FLY)
|
||||
/* Make sure that the position you enter in will be erased */
|
||||
showexpl(newpp->p_y, newpp->p_x, FLYER);
|
||||
# endif
|
||||
sendcom(newpp, REFRESH);
|
||||
sendcom(newpp, READY, 0);
|
||||
(void) fflush(newpp->p_output);
|
||||
}
|
||||
|
||||
/*
|
||||
* rand_dir:
|
||||
* Return a random direction
|
||||
*/
|
||||
int
|
||||
rand_dir()
|
||||
{
|
||||
switch (rand_num(4)) {
|
||||
case 0:
|
||||
return LEFTS;
|
||||
case 1:
|
||||
return RIGHT;
|
||||
case 2:
|
||||
return BELOW;
|
||||
case 3:
|
||||
return ABOVE;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* get_ident:
|
||||
* Get the score structure of a player
|
||||
*/
|
||||
IDENT *
|
||||
get_ident(machine, uid, name, team)
|
||||
u_long machine;
|
||||
u_long uid;
|
||||
const char *name;
|
||||
char team;
|
||||
{
|
||||
IDENT *ip;
|
||||
static IDENT punt;
|
||||
|
||||
for (ip = Scores; ip != NULL; ip = ip->i_next)
|
||||
if ((unsigned long)ip->i_machine == machine
|
||||
&& (unsigned long)ip->i_uid == uid
|
||||
&& ip->i_team == team
|
||||
&& strncmp(ip->i_name, name, NAMELEN) == 0)
|
||||
break;
|
||||
|
||||
if (ip != NULL) {
|
||||
if (ip->i_entries < SCOREDECAY)
|
||||
ip->i_entries++;
|
||||
else
|
||||
ip->i_kills = (ip->i_kills * (SCOREDECAY - 1))
|
||||
/ SCOREDECAY;
|
||||
ip->i_score = ip->i_kills / (double) ip->i_entries;
|
||||
}
|
||||
else {
|
||||
ip = (IDENT *) malloc(sizeof (IDENT));
|
||||
if (ip == NULL) {
|
||||
/* Fourth down, time to punt */
|
||||
ip = &punt;
|
||||
}
|
||||
ip->i_machine = machine;
|
||||
ip->i_team = team;
|
||||
ip->i_uid = uid;
|
||||
strncpy(ip->i_name, name, NAMELEN);
|
||||
ip->i_kills = 0;
|
||||
ip->i_entries = 1;
|
||||
ip->i_score = 0;
|
||||
ip->i_absorbed = 0;
|
||||
ip->i_faced = 0;
|
||||
ip->i_shot = 0;
|
||||
ip->i_robbed = 0;
|
||||
ip->i_slime = 0;
|
||||
ip->i_missed = 0;
|
||||
ip->i_ducked = 0;
|
||||
ip->i_gkills = ip->i_bkills = ip->i_deaths = 0;
|
||||
ip->i_stillb = ip->i_saved = 0;
|
||||
ip->i_next = Scores;
|
||||
Scores = ip;
|
||||
}
|
||||
|
||||
return ip;
|
||||
}
|
||||
21
hunt/huntd/bsd.h
Normal file
21
hunt/huntd/bsd.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/* $NetBSD: bsd.h,v 1.2 1998/01/09 08:03:40 perry Exp $ */
|
||||
|
||||
/*
|
||||
* Hunt
|
||||
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
* San Francisco, California
|
||||
*/
|
||||
|
||||
# if defined(BSD_RELEASE) && BSD_RELEASE >= 43
|
||||
# define BROADCAST
|
||||
# define SYSLOG_43
|
||||
#ifdef __linux__
|
||||
#define TALK_42 /* Kludge around broken <protocols/talkd.h> */
|
||||
#else
|
||||
# define TALK_43
|
||||
#endif
|
||||
# endif
|
||||
# if defined(BSD_RELEASE) && BSD_RELEASE == 42
|
||||
# define SYSLOG_42
|
||||
# define TALK_42
|
||||
# endif
|
||||
60
hunt/huntd/ctl.c
Normal file
60
hunt/huntd/ctl.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/* $NetBSD: ctl.c,v 1.2 1997/10/10 16:32:54 lukem Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1983 Regents of the University of California.
|
||||
* All rights reserved. The Berkeley software License Agreement
|
||||
* specifies the terms and conditions for redistribution.
|
||||
*/
|
||||
|
||||
#include "bsd.h"
|
||||
|
||||
#if defined(TALK_43) || defined(TALK_42)
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)ctl.c 5.2 (Berkeley) 3/13/86";
|
||||
#else
|
||||
__RCSID("$NetBSD: ctl.c,v 1.2 1997/10/10 16:32:54 lukem Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
* This file handles haggling with the various talk daemons to
|
||||
* get a socket to talk to. sockt is opened and connected in
|
||||
* the progress
|
||||
*/
|
||||
|
||||
#include "hunt.h"
|
||||
#include "talk_ctl.h"
|
||||
|
||||
struct sockaddr_in daemon_addr = { AF_INET };
|
||||
struct sockaddr_in ctl_addr = { AF_INET };
|
||||
|
||||
/* inet addresses of the two machines */
|
||||
struct in_addr my_machine_addr;
|
||||
struct in_addr his_machine_addr;
|
||||
|
||||
u_short daemon_port; /* port number of the talk daemon */
|
||||
|
||||
int ctl_sockt;
|
||||
|
||||
CTL_MSG msg;
|
||||
|
||||
/* open the ctl socket */
|
||||
void
|
||||
open_ctl()
|
||||
{
|
||||
int length;
|
||||
|
||||
ctl_addr.sin_port = 0;
|
||||
ctl_addr.sin_addr = my_machine_addr;
|
||||
ctl_sockt = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (ctl_sockt <= 0)
|
||||
p_error("Bad socket");
|
||||
if (bind(ctl_sockt, (struct sockaddr *)&ctl_addr, sizeof(ctl_addr)) != 0)
|
||||
p_error("Couldn't bind to control socket");
|
||||
length = sizeof(ctl_addr);
|
||||
if (getsockname(ctl_sockt, (struct sockaddr *) &ctl_addr, &length) < 0)
|
||||
p_error("Bad address for ctl socket");
|
||||
}
|
||||
#endif
|
||||
113
hunt/huntd/ctl_transact.c
Normal file
113
hunt/huntd/ctl_transact.c
Normal file
@@ -0,0 +1,113 @@
|
||||
/* $NetBSD: ctl_transact.c,v 1.3 1997/10/20 00:37:16 lukem Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1983 Regents of the University of California.
|
||||
* All rights reserved. The Berkeley software License Agreement
|
||||
* specifies the terms and conditions for redistribution.
|
||||
*/
|
||||
|
||||
#include "bsd.h"
|
||||
|
||||
#if defined(TALK_43) || defined(TALK_42)
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)ctl_transact.c 5.2 (Berkeley) 3/13/86";
|
||||
#else
|
||||
__RCSID("$NetBSD: ctl_transact.c,v 1.3 1997/10/20 00:37:16 lukem Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include "hunt.h"
|
||||
#include "talk_ctl.h"
|
||||
|
||||
#define CTL_WAIT 2 /* time to wait for a response, in seconds */
|
||||
#define MAX_RETRY 5
|
||||
|
||||
/*
|
||||
* SOCKDGRAM is unreliable, so we must repeat messages if we have
|
||||
* not recieved an acknowledgement within a reasonable amount
|
||||
* of time
|
||||
*/
|
||||
void
|
||||
ctl_transact(target, msg, type, rp)
|
||||
struct in_addr target;
|
||||
CTL_MSG msg;
|
||||
int type;
|
||||
CTL_RESPONSE *rp;
|
||||
{
|
||||
fd_set read_mask, ctl_mask;
|
||||
int nready, cc, retries;
|
||||
struct timeval wait;
|
||||
|
||||
nready = 0;
|
||||
msg.type = type;
|
||||
daemon_addr.sin_addr = target;
|
||||
daemon_addr.sin_port = daemon_port;
|
||||
FD_ZERO(&ctl_mask);
|
||||
FD_SET(ctl_sockt, &ctl_mask);
|
||||
|
||||
/*
|
||||
* Keep sending the message until a response of
|
||||
* the proper type is obtained.
|
||||
*/
|
||||
do {
|
||||
wait.tv_sec = CTL_WAIT;
|
||||
wait.tv_usec = 0;
|
||||
/* resend message until a response is obtained */
|
||||
for (retries = MAX_RETRY; retries > 0; retries -= 1) {
|
||||
cc = sendto(ctl_sockt, (char *)&msg, sizeof (msg), 0,
|
||||
(struct sockaddr *)&daemon_addr, sizeof (daemon_addr));
|
||||
if (cc != sizeof (msg)) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
p_error("Error on write to talk daemon");
|
||||
}
|
||||
read_mask = ctl_mask;
|
||||
nready = select(32, &read_mask, 0, 0, &wait);
|
||||
if (nready < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
p_error("Error waiting for daemon response");
|
||||
}
|
||||
if (nready != 0)
|
||||
break;
|
||||
}
|
||||
if (retries <= 0)
|
||||
break;
|
||||
/*
|
||||
* Keep reading while there are queued messages
|
||||
* (this is not necessary, it just saves extra
|
||||
* request/acknowledgements being sent)
|
||||
*/
|
||||
do {
|
||||
cc = recv(ctl_sockt, (char *)rp, sizeof (*rp), 0);
|
||||
if (cc < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
p_error("Error on read from talk daemon");
|
||||
}
|
||||
read_mask = ctl_mask;
|
||||
/* an immediate poll */
|
||||
timerclear(&wait);
|
||||
nready = select(32, &read_mask, 0, 0, &wait);
|
||||
} while (nready > 0 && (
|
||||
#ifdef TALK_43
|
||||
rp->vers != TALK_VERSION ||
|
||||
#endif
|
||||
rp->type != type));
|
||||
} while (
|
||||
#ifdef TALK_43
|
||||
rp->vers != TALK_VERSION ||
|
||||
#endif
|
||||
rp->type != type);
|
||||
rp->id_num = ntohl(rp->id_num);
|
||||
#ifdef TALK_43
|
||||
rp->addr.sa_family = ntohs(rp->addr.sa_family);
|
||||
# else
|
||||
rp->addr.sin_family = ntohs(rp->addr.sin_family);
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
381
hunt/huntd/draw.c
Normal file
381
hunt/huntd/draw.c
Normal file
@@ -0,0 +1,381 @@
|
||||
/* $NetBSD: draw.c,v 1.2 1997/10/10 16:33:04 lukem Exp $ */
|
||||
/*
|
||||
* Hunt
|
||||
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
* San Francisco, California
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: draw.c,v 1.2 1997/10/10 16:33:04 lukem Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
# include "hunt.h"
|
||||
|
||||
void
|
||||
drawmaze(pp)
|
||||
PLAYER *pp;
|
||||
{
|
||||
int x;
|
||||
char *sp;
|
||||
int y;
|
||||
char *endp;
|
||||
|
||||
clrscr(pp);
|
||||
outstr(pp, pp->p_maze[0], WIDTH);
|
||||
for (y = 1; y < HEIGHT - 1; y++) {
|
||||
endp = &pp->p_maze[y][WIDTH];
|
||||
for (x = 0, sp = pp->p_maze[y]; sp < endp; x++, sp++)
|
||||
if (*sp != SPACE) {
|
||||
cgoto(pp, y, x);
|
||||
if (pp->p_x == x && pp->p_y == y)
|
||||
outch(pp, translate(*sp));
|
||||
else if (is_player(*sp))
|
||||
outch(pp, player_sym(pp, y, x));
|
||||
else
|
||||
outch(pp, *sp);
|
||||
}
|
||||
}
|
||||
cgoto(pp, HEIGHT - 1, 0);
|
||||
outstr(pp, pp->p_maze[HEIGHT - 1], WIDTH);
|
||||
drawstatus(pp);
|
||||
}
|
||||
|
||||
/*
|
||||
* drawstatus - put up the status lines (this assumes the screen
|
||||
* size is 80x24 with the maze being 64x24)
|
||||
*/
|
||||
void
|
||||
drawstatus(pp)
|
||||
PLAYER *pp;
|
||||
{
|
||||
int i;
|
||||
PLAYER *np;
|
||||
|
||||
cgoto(pp, STAT_AMMO_ROW, STAT_LABEL_COL);
|
||||
outstr(pp, "Ammo:", 5);
|
||||
(void) sprintf(Buf, "%3d", pp->p_ammo);
|
||||
cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
|
||||
outstr(pp, Buf, 3);
|
||||
|
||||
cgoto(pp, STAT_GUN_ROW, STAT_LABEL_COL);
|
||||
outstr(pp, "Gun:", 4);
|
||||
cgoto(pp, STAT_GUN_ROW, STAT_VALUE_COL);
|
||||
outstr(pp, (pp->p_ncshot < MAXNCSHOT) ? " ok" : " ", 3);
|
||||
|
||||
cgoto(pp, STAT_DAM_ROW, STAT_LABEL_COL);
|
||||
outstr(pp, "Damage:", 7);
|
||||
(void) sprintf(Buf, "%2d/%2d", pp->p_damage, pp->p_damcap);
|
||||
cgoto(pp, STAT_DAM_ROW, STAT_VALUE_COL);
|
||||
outstr(pp, Buf, 5);
|
||||
|
||||
cgoto(pp, STAT_KILL_ROW, STAT_LABEL_COL);
|
||||
outstr(pp, "Kills:", 6);
|
||||
(void) sprintf(Buf, "%3d", (pp->p_damcap - MAXDAM) / 2);
|
||||
cgoto(pp, STAT_KILL_ROW, STAT_VALUE_COL);
|
||||
outstr(pp, Buf, 3);
|
||||
|
||||
cgoto(pp, STAT_PLAY_ROW, STAT_LABEL_COL);
|
||||
outstr(pp, "Player:", 7);
|
||||
for (i = STAT_PLAY_ROW + 1, np = Player; np < End_player; np++) {
|
||||
(void) sprintf(Buf, "%5.2f%c%-10.10s %c", np->p_ident->i_score,
|
||||
stat_char(np), np->p_ident->i_name,
|
||||
np->p_ident->i_team);
|
||||
cgoto(pp, i++, STAT_NAME_COL);
|
||||
outstr(pp, Buf, STAT_NAME_LEN);
|
||||
}
|
||||
|
||||
# ifdef MONITOR
|
||||
cgoto(pp, STAT_MON_ROW, STAT_LABEL_COL);
|
||||
outstr(pp, "Monitor:", 8);
|
||||
for (i = STAT_MON_ROW + 1, np = Monitor; np < End_monitor; np++) {
|
||||
(void) sprintf(Buf, "%5.5s %-10.10s %c", " ",
|
||||
np->p_ident->i_name, np->p_ident->i_team);
|
||||
cgoto(pp, i++, STAT_NAME_COL);
|
||||
outstr(pp, Buf, STAT_NAME_LEN);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
void
|
||||
look(pp)
|
||||
PLAYER *pp;
|
||||
{
|
||||
int x, y;
|
||||
|
||||
x = pp->p_x;
|
||||
y = pp->p_y;
|
||||
|
||||
check(pp, y - 1, x - 1);
|
||||
check(pp, y - 1, x );
|
||||
check(pp, y - 1, x + 1);
|
||||
check(pp, y , x - 1);
|
||||
check(pp, y , x );
|
||||
check(pp, y , x + 1);
|
||||
check(pp, y + 1, x - 1);
|
||||
check(pp, y + 1, x );
|
||||
check(pp, y + 1, x + 1);
|
||||
|
||||
switch (pp->p_face) {
|
||||
case LEFTS:
|
||||
see(pp, LEFTS);
|
||||
see(pp, ABOVE);
|
||||
see(pp, BELOW);
|
||||
break;
|
||||
case RIGHT:
|
||||
see(pp, RIGHT);
|
||||
see(pp, ABOVE);
|
||||
see(pp, BELOW);
|
||||
break;
|
||||
case ABOVE:
|
||||
see(pp, ABOVE);
|
||||
see(pp, LEFTS);
|
||||
see(pp, RIGHT);
|
||||
break;
|
||||
case BELOW:
|
||||
see(pp, BELOW);
|
||||
see(pp, LEFTS);
|
||||
see(pp, RIGHT);
|
||||
break;
|
||||
# ifdef FLY
|
||||
case FLYER:
|
||||
break;
|
||||
# endif
|
||||
}
|
||||
cgoto(pp, y, x);
|
||||
}
|
||||
|
||||
void
|
||||
see(pp, face)
|
||||
PLAYER *pp;
|
||||
int face;
|
||||
{
|
||||
char *sp;
|
||||
int y, x, i, cnt;
|
||||
|
||||
x = pp->p_x;
|
||||
y = pp->p_y;
|
||||
|
||||
switch (face) {
|
||||
case LEFTS:
|
||||
sp = &Maze[y][x];
|
||||
for (i = 0; See_over[(int)*--sp]; i++)
|
||||
continue;
|
||||
|
||||
if (i == 0)
|
||||
break;
|
||||
|
||||
cnt = i;
|
||||
x = pp->p_x - 1;
|
||||
--y;
|
||||
while (i--)
|
||||
check(pp, y, --x);
|
||||
i = cnt;
|
||||
x = pp->p_x - 1;
|
||||
++y;
|
||||
while (i--)
|
||||
check(pp, y, --x);
|
||||
i = cnt;
|
||||
x = pp->p_x - 1;
|
||||
++y;
|
||||
while (i--)
|
||||
check(pp, y, --x);
|
||||
break;
|
||||
case RIGHT:
|
||||
sp = &Maze[y][++x];
|
||||
for (i = 0; See_over[(int)*sp++]; i++)
|
||||
continue;
|
||||
|
||||
if (i == 0)
|
||||
break;
|
||||
|
||||
cnt = i;
|
||||
x = pp->p_x + 1;
|
||||
--y;
|
||||
while (i--)
|
||||
check(pp, y, ++x);
|
||||
i = cnt;
|
||||
x = pp->p_x + 1;
|
||||
++y;
|
||||
while (i--)
|
||||
check(pp, y, ++x);
|
||||
i = cnt;
|
||||
x = pp->p_x + 1;
|
||||
++y;
|
||||
while (i--)
|
||||
check(pp, y, ++x);
|
||||
break;
|
||||
case ABOVE:
|
||||
sp = &Maze[--y][x];
|
||||
if (!See_over[(int)*sp])
|
||||
break;
|
||||
do {
|
||||
--y;
|
||||
sp -= sizeof Maze[0];
|
||||
check(pp, y, x - 1);
|
||||
check(pp, y, x );
|
||||
check(pp, y, x + 1);
|
||||
} while (See_over[(int)*sp]);
|
||||
break;
|
||||
case BELOW:
|
||||
sp = &Maze[++y][x];
|
||||
if (!See_over[(int)*sp])
|
||||
break;
|
||||
do {
|
||||
y++;
|
||||
sp += sizeof Maze[0];
|
||||
check(pp, y, x - 1);
|
||||
check(pp, y, x );
|
||||
check(pp, y, x + 1);
|
||||
} while (See_over[(int)*sp]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
check(pp, y, x)
|
||||
PLAYER *pp;
|
||||
int y, x;
|
||||
{
|
||||
int index;
|
||||
int ch;
|
||||
PLAYER *rpp;
|
||||
|
||||
index = y * sizeof Maze[0] + x;
|
||||
ch = ((char *) Maze)[index];
|
||||
if (ch != ((char *) pp->p_maze)[index]) {
|
||||
rpp = pp;
|
||||
cgoto(rpp, y, x);
|
||||
if (x == rpp->p_x && y == rpp->p_y)
|
||||
outch(rpp, translate(ch));
|
||||
else if (is_player(ch))
|
||||
outch(rpp, player_sym(rpp, y, x));
|
||||
else
|
||||
outch(rpp, ch);
|
||||
((char *) rpp->p_maze)[index] = ch;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* showstat
|
||||
* Update the status of players
|
||||
*/
|
||||
void
|
||||
showstat(pp)
|
||||
PLAYER *pp;
|
||||
{
|
||||
PLAYER *np;
|
||||
int y;
|
||||
char c;
|
||||
|
||||
y = STAT_PLAY_ROW + 1 + (pp - Player);
|
||||
c = stat_char(pp);
|
||||
# ifdef MONITOR
|
||||
for (np = Monitor; np < End_monitor; np++) {
|
||||
cgoto(np, y, STAT_SCAN_COL);
|
||||
outch(np, c);
|
||||
}
|
||||
# endif
|
||||
for (np = Player; np < End_player; np++) {
|
||||
cgoto(np, y, STAT_SCAN_COL);
|
||||
outch(np, c);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* drawplayer:
|
||||
* Draw the player on the screen and show him to everyone who's scanning
|
||||
* unless he is cloaked.
|
||||
*/
|
||||
void
|
||||
drawplayer(pp, draw)
|
||||
PLAYER *pp;
|
||||
FLAG draw;
|
||||
{
|
||||
PLAYER *newp;
|
||||
int x, y;
|
||||
|
||||
x = pp->p_x;
|
||||
y = pp->p_y;
|
||||
Maze[y][x] = draw ? pp->p_face : pp->p_over;
|
||||
|
||||
# ifdef MONITOR
|
||||
for (newp = Monitor; newp < End_monitor; newp++)
|
||||
check(newp, y, x);
|
||||
# endif
|
||||
|
||||
for (newp = Player; newp < End_player; newp++) {
|
||||
if (!draw || newp == pp) {
|
||||
check(newp, y, x);
|
||||
continue;
|
||||
}
|
||||
if (newp->p_scan == 0) {
|
||||
newp->p_scan--;
|
||||
showstat(newp);
|
||||
}
|
||||
else if (newp->p_scan > 0) {
|
||||
if (pp->p_cloak < 0)
|
||||
check(newp, y, x);
|
||||
newp->p_scan--;
|
||||
}
|
||||
}
|
||||
if (!draw || pp->p_cloak < 0)
|
||||
return;
|
||||
if (pp->p_cloak-- == 0)
|
||||
showstat(pp);
|
||||
}
|
||||
|
||||
void
|
||||
message(pp, s)
|
||||
PLAYER *pp;
|
||||
const char *s;
|
||||
{
|
||||
cgoto(pp, HEIGHT, 0);
|
||||
outstr(pp, s, strlen(s));
|
||||
ce(pp);
|
||||
}
|
||||
|
||||
/*
|
||||
* translate:
|
||||
* Turn a character into the right direction character if we are
|
||||
* looking at the current player.
|
||||
*/
|
||||
char
|
||||
translate(ch)
|
||||
char ch;
|
||||
{
|
||||
switch (ch) {
|
||||
case LEFTS:
|
||||
return '<';
|
||||
case RIGHT:
|
||||
return '>';
|
||||
case ABOVE:
|
||||
return '^';
|
||||
case BELOW:
|
||||
return 'v';
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
|
||||
/*
|
||||
* player_sym:
|
||||
* Return the player symbol
|
||||
*/
|
||||
int
|
||||
player_sym(pp, y, x)
|
||||
const PLAYER *pp;
|
||||
int y, x;
|
||||
{
|
||||
PLAYER *npp;
|
||||
|
||||
npp = play_at(y, x);
|
||||
if (npp->p_ident->i_team == ' ')
|
||||
return Maze[y][x];
|
||||
#ifdef MONITOR
|
||||
if (pp->p_ident->i_team == '*')
|
||||
return npp->p_ident->i_team;
|
||||
#endif
|
||||
if (pp->p_ident->i_team != npp->p_ident->i_team)
|
||||
return Maze[y][x];
|
||||
return pp->p_ident->i_team;
|
||||
}
|
||||
976
hunt/huntd/driver.c
Normal file
976
hunt/huntd/driver.c
Normal file
@@ -0,0 +1,976 @@
|
||||
/* $NetBSD: driver.c,v 1.5 1997/10/20 00:37:16 lukem Exp $ */
|
||||
/*
|
||||
* Hunt
|
||||
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
* San Francisco, California
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: driver.c,v 1.5 1997/10/20 00:37:16 lukem Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
# include <sys/ioctl.h>
|
||||
# include <sys/stat.h>
|
||||
# include <sys/time.h>
|
||||
# include <err.h>
|
||||
# include <errno.h>
|
||||
# include <signal.h>
|
||||
# include <stdlib.h>
|
||||
# include <unistd.h>
|
||||
# include "hunt.h"
|
||||
|
||||
# ifndef pdp11
|
||||
# define RN (((Seed = Seed * 11109 + 13849) >> 16) & 0xffff)
|
||||
# else
|
||||
# define RN ((Seed = Seed * 11109 + 13849) & 0x7fff)
|
||||
# endif
|
||||
|
||||
int Seed = 0;
|
||||
|
||||
|
||||
SOCKET Daemon;
|
||||
char *First_arg; /* pointer to argv[0] */
|
||||
char *Last_arg; /* pointer to end of argv/environ */
|
||||
# ifdef INTERNET
|
||||
int Test_socket; /* test socket to answer datagrams */
|
||||
FLAG inetd_spawned; /* invoked via inetd */
|
||||
FLAG standard_port = TRUE; /* true if listening on standard port */
|
||||
u_short sock_port; /* port # of tcp listen socket */
|
||||
u_short stat_port; /* port # of statistics tcp socket */
|
||||
# define DAEMON_SIZE (sizeof Daemon)
|
||||
# else
|
||||
# define DAEMON_SIZE (sizeof Daemon - 1)
|
||||
# endif
|
||||
|
||||
static void clear_scores __P((void));
|
||||
static int havechar __P((PLAYER *));
|
||||
static void init __P((void));
|
||||
int main __P((int, char *[], char *[]));
|
||||
static void makeboots __P((void));
|
||||
static void send_stats __P((void));
|
||||
static void zap __P((PLAYER *, FLAG));
|
||||
|
||||
|
||||
/*
|
||||
* main:
|
||||
* The main program.
|
||||
*/
|
||||
int
|
||||
main(ac, av, ep)
|
||||
int ac;
|
||||
char **av, **ep;
|
||||
{
|
||||
PLAYER *pp;
|
||||
int had_char;
|
||||
# ifdef INTERNET
|
||||
u_short msg;
|
||||
short port_num, reply;
|
||||
int namelen;
|
||||
SOCKET test;
|
||||
# endif
|
||||
static fd_set read_fds;
|
||||
static FLAG first = TRUE;
|
||||
static FLAG server = FALSE;
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
int c;
|
||||
static struct timeval linger = { 90, 0 };
|
||||
|
||||
First_arg = av[0];
|
||||
if (ep == NULL || *ep == NULL)
|
||||
ep = av + ac;
|
||||
while (*ep)
|
||||
ep++;
|
||||
Last_arg = ep[-1] + strlen(ep[-1]);
|
||||
|
||||
while ((c = getopt(ac, av, "sp:")) != -1) {
|
||||
switch (c) {
|
||||
case 's':
|
||||
server = TRUE;
|
||||
break;
|
||||
# ifdef INTERNET
|
||||
case 'p':
|
||||
standard_port = FALSE;
|
||||
Test_port = atoi(optarg);
|
||||
break;
|
||||
# endif
|
||||
default:
|
||||
erred:
|
||||
fprintf(stderr, "Usage: %s [-s] [-p port]\n", av[0]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (optind < ac)
|
||||
goto erred;
|
||||
|
||||
init();
|
||||
|
||||
|
||||
again:
|
||||
do {
|
||||
read_fds = Fds_mask;
|
||||
errno = 0;
|
||||
while (select(Num_fds, &read_fds, NULL, NULL, NULL) < 0)
|
||||
{
|
||||
if (errno != EINTR)
|
||||
# ifdef LOG
|
||||
syslog(LOG_WARNING, "select: %m");
|
||||
# else
|
||||
warn("select");
|
||||
# endif
|
||||
errno = 0;
|
||||
}
|
||||
Have_inp = read_fds;
|
||||
# ifdef INTERNET
|
||||
if (FD_ISSET(Test_socket, &read_fds)) {
|
||||
namelen = DAEMON_SIZE;
|
||||
port_num = htons(sock_port);
|
||||
(void) recvfrom(Test_socket, (char *) &msg, sizeof msg,
|
||||
0, (struct sockaddr *) &test, &namelen);
|
||||
switch (ntohs(msg)) {
|
||||
case C_MESSAGE:
|
||||
if (Nplayer <= 0)
|
||||
break;
|
||||
reply = htons((u_short) Nplayer);
|
||||
(void) sendto(Test_socket, (char *) &reply,
|
||||
sizeof reply, 0,
|
||||
(struct sockaddr *) &test, DAEMON_SIZE);
|
||||
break;
|
||||
case C_SCORES:
|
||||
reply = htons(stat_port);
|
||||
(void) sendto(Test_socket, (char *) &reply,
|
||||
sizeof reply, 0,
|
||||
(struct sockaddr *) &test, DAEMON_SIZE);
|
||||
break;
|
||||
case C_PLAYER:
|
||||
case C_MONITOR:
|
||||
if (msg == C_MONITOR && Nplayer <= 0)
|
||||
break;
|
||||
reply = htons(sock_port);
|
||||
(void) sendto(Test_socket, (char *) &reply,
|
||||
sizeof reply, 0,
|
||||
(struct sockaddr *) &test, DAEMON_SIZE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
for (;;) {
|
||||
had_char = FALSE;
|
||||
for (pp = Player; pp < End_player; pp++)
|
||||
if (havechar(pp)) {
|
||||
execute(pp);
|
||||
pp->p_nexec++;
|
||||
had_char++;
|
||||
}
|
||||
# ifdef MONITOR
|
||||
for (pp = Monitor; pp < End_monitor; pp++)
|
||||
if (havechar(pp)) {
|
||||
mon_execute(pp);
|
||||
pp->p_nexec++;
|
||||
had_char++;
|
||||
}
|
||||
# endif
|
||||
if (!had_char)
|
||||
break;
|
||||
moveshots();
|
||||
for (pp = Player; pp < End_player; )
|
||||
if (pp->p_death[0] != '\0')
|
||||
zap(pp, TRUE);
|
||||
else
|
||||
pp++;
|
||||
# ifdef MONITOR
|
||||
for (pp = Monitor; pp < End_monitor; )
|
||||
if (pp->p_death[0] != '\0')
|
||||
zap(pp, FALSE);
|
||||
else
|
||||
pp++;
|
||||
# endif
|
||||
}
|
||||
if (FD_ISSET(Socket, &read_fds))
|
||||
if (answer()) {
|
||||
# ifdef INTERNET
|
||||
if (first && standard_port)
|
||||
faketalk();
|
||||
# endif
|
||||
first = FALSE;
|
||||
}
|
||||
if (FD_ISSET(Status, &read_fds))
|
||||
send_stats();
|
||||
for (pp = Player; pp < End_player; pp++) {
|
||||
if (FD_ISSET(pp->p_fd, &read_fds))
|
||||
sendcom(pp, READY, pp->p_nexec);
|
||||
pp->p_nexec = 0;
|
||||
(void) fflush(pp->p_output);
|
||||
}
|
||||
# ifdef MONITOR
|
||||
for (pp = Monitor; pp < End_monitor; pp++) {
|
||||
if (FD_ISSET(pp->p_fd, &read_fds))
|
||||
sendcom(pp, READY, pp->p_nexec);
|
||||
pp->p_nexec = 0;
|
||||
(void) fflush(pp->p_output);
|
||||
}
|
||||
# endif
|
||||
} while (Nplayer > 0);
|
||||
|
||||
read_fds = Fds_mask;
|
||||
if (select(Num_fds, &read_fds, NULL, NULL, &linger) > 0) {
|
||||
goto again;
|
||||
}
|
||||
if (server) {
|
||||
clear_scores();
|
||||
makemaze();
|
||||
clearwalls();
|
||||
# ifdef BOOTS
|
||||
makeboots();
|
||||
# endif
|
||||
first = TRUE;
|
||||
goto again;
|
||||
}
|
||||
|
||||
# ifdef MONITOR
|
||||
for (pp = Monitor; pp < End_monitor; )
|
||||
zap(pp, FALSE);
|
||||
# endif
|
||||
cleanup(0);
|
||||
/* NOTREACHED */
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* init:
|
||||
* Initialize the global parameters.
|
||||
*/
|
||||
static void
|
||||
init()
|
||||
{
|
||||
int i;
|
||||
# ifdef INTERNET
|
||||
SOCKET test_port;
|
||||
int msg;
|
||||
int len;
|
||||
# endif
|
||||
|
||||
# ifndef DEBUG
|
||||
if (setsid() == -1)
|
||||
err(1, "setsid");
|
||||
(void) signal(SIGHUP, SIG_IGN);
|
||||
(void) signal(SIGINT, SIG_IGN);
|
||||
(void) signal(SIGQUIT, SIG_IGN);
|
||||
(void) signal(SIGTERM, cleanup);
|
||||
# endif
|
||||
|
||||
(void) chdir("/var/tmp"); /* just in case it core dumps */
|
||||
(void) umask(0); /* No privacy at all! */
|
||||
(void) signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
# ifdef LOG
|
||||
# ifdef SYSLOG_43
|
||||
openlog("HUNT", LOG_PID, LOG_DAEMON);
|
||||
# endif
|
||||
# ifdef SYSLOG_42
|
||||
openlog("HUNT", LOG_PID);
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/*
|
||||
* Initialize statistics socket
|
||||
*/
|
||||
# ifdef INTERNET
|
||||
Daemon.sin_family = SOCK_FAMILY;
|
||||
Daemon.sin_addr.s_addr = INADDR_ANY;
|
||||
Daemon.sin_port = 0;
|
||||
# else
|
||||
Daemon.sun_family = SOCK_FAMILY;
|
||||
(void) strcpy(Daemon.sun_path, Stat_name);
|
||||
# endif
|
||||
|
||||
Status = socket(SOCK_FAMILY, SOCK_STREAM, 0);
|
||||
if (bind(Status, (struct sockaddr *) &Daemon, DAEMON_SIZE) < 0) {
|
||||
if (errno == EADDRINUSE)
|
||||
exit(0);
|
||||
else {
|
||||
# ifdef LOG
|
||||
syslog(LOG_ERR, "bind: %m");
|
||||
# else
|
||||
warn("bind");
|
||||
# endif
|
||||
cleanup(1);
|
||||
}
|
||||
}
|
||||
(void) listen(Status, 5);
|
||||
|
||||
# ifdef INTERNET
|
||||
len = sizeof (SOCKET);
|
||||
if (getsockname(Status, (struct sockaddr *) &Daemon, &len) < 0) {
|
||||
# ifdef LOG
|
||||
syslog(LOG_ERR, "getsockname: %m");
|
||||
# else
|
||||
warn("getsockname");
|
||||
# endif
|
||||
exit(1);
|
||||
}
|
||||
stat_port = ntohs(Daemon.sin_port);
|
||||
# endif
|
||||
|
||||
/*
|
||||
* Initialize main socket
|
||||
*/
|
||||
# ifdef INTERNET
|
||||
Daemon.sin_family = SOCK_FAMILY;
|
||||
Daemon.sin_addr.s_addr = INADDR_ANY;
|
||||
Daemon.sin_port = 0;
|
||||
# else
|
||||
Daemon.sun_family = SOCK_FAMILY;
|
||||
(void) strcpy(Daemon.sun_path, Sock_name);
|
||||
# endif
|
||||
|
||||
Socket = socket(SOCK_FAMILY, SOCK_STREAM, 0);
|
||||
# if defined(INTERNET)
|
||||
msg = 1;
|
||||
#ifdef SO_USELOOPBACK
|
||||
if (setsockopt(Socket, SOL_SOCKET, SO_USELOOPBACK, &msg, sizeof msg)<0)
|
||||
# ifdef LOG
|
||||
syslog(LOG_WARNING, "setsockopt loopback %m");
|
||||
# else
|
||||
warn("setsockopt loopback");
|
||||
# endif
|
||||
#endif
|
||||
# endif
|
||||
if (bind(Socket, (struct sockaddr *) &Daemon, DAEMON_SIZE) < 0) {
|
||||
if (errno == EADDRINUSE)
|
||||
exit(0);
|
||||
else {
|
||||
# ifdef LOG
|
||||
syslog(LOG_ERR, "bind: %m");
|
||||
# else
|
||||
warn("bind");
|
||||
# endif
|
||||
cleanup(1);
|
||||
}
|
||||
}
|
||||
(void) listen(Socket, 5);
|
||||
|
||||
# ifdef INTERNET
|
||||
len = sizeof (SOCKET);
|
||||
if (getsockname(Socket, (struct sockaddr *) &Daemon, &len) < 0) {
|
||||
# ifdef LOG
|
||||
syslog(LOG_ERR, "getsockname: %m");
|
||||
# else
|
||||
warn("getsockname");
|
||||
# endif
|
||||
exit(1);
|
||||
}
|
||||
sock_port = ntohs(Daemon.sin_port);
|
||||
# endif
|
||||
|
||||
/*
|
||||
* Initialize minimal select mask
|
||||
*/
|
||||
FD_ZERO(&Fds_mask);
|
||||
FD_SET(Socket, &Fds_mask);
|
||||
FD_SET(Status, &Fds_mask);
|
||||
Num_fds = ((Socket > Status) ? Socket : Status) + 1;
|
||||
|
||||
# ifdef INTERNET
|
||||
len = sizeof (SOCKET);
|
||||
if (getsockname(0, (struct sockaddr *) &test_port, &len) >= 0
|
||||
&& test_port.sin_family == AF_INET) {
|
||||
inetd_spawned = TRUE;
|
||||
Test_socket = 0;
|
||||
if (test_port.sin_port != htons((u_short) Test_port)) {
|
||||
standard_port = FALSE;
|
||||
Test_port = ntohs(test_port.sin_port);
|
||||
}
|
||||
} else {
|
||||
test_port = Daemon;
|
||||
test_port.sin_port = htons((u_short) Test_port);
|
||||
|
||||
Test_socket = socket(SOCK_FAMILY, SOCK_DGRAM, 0);
|
||||
if (bind(Test_socket, (struct sockaddr *) &test_port,
|
||||
DAEMON_SIZE) < 0) {
|
||||
# ifdef LOG
|
||||
syslog(LOG_ERR, "bind: %m");
|
||||
# else
|
||||
warn("bind");
|
||||
# endif
|
||||
exit(1);
|
||||
}
|
||||
(void) listen(Test_socket, 5);
|
||||
}
|
||||
|
||||
FD_SET(Test_socket, &Fds_mask);
|
||||
if (Test_socket + 1 > Num_fds)
|
||||
Num_fds = Test_socket + 1;
|
||||
# endif
|
||||
|
||||
Seed = getpid() + time((time_t *) NULL);
|
||||
makemaze();
|
||||
# ifdef BOOTS
|
||||
makeboots();
|
||||
# endif
|
||||
|
||||
for (i = 0; i < NASCII; i++)
|
||||
See_over[i] = TRUE;
|
||||
See_over[DOOR] = FALSE;
|
||||
See_over[WALL1] = FALSE;
|
||||
See_over[WALL2] = FALSE;
|
||||
See_over[WALL3] = FALSE;
|
||||
# ifdef REFLECT
|
||||
See_over[WALL4] = FALSE;
|
||||
See_over[WALL5] = FALSE;
|
||||
# endif
|
||||
|
||||
}
|
||||
|
||||
# ifdef BOOTS
|
||||
/*
|
||||
* makeboots:
|
||||
* Put the boots in the maze
|
||||
*/
|
||||
static void
|
||||
makeboots()
|
||||
{
|
||||
int x, y;
|
||||
PLAYER *pp;
|
||||
|
||||
do {
|
||||
x = rand_num(WIDTH - 1) + 1;
|
||||
y = rand_num(HEIGHT - 1) + 1;
|
||||
} while (Maze[y][x] != SPACE);
|
||||
Maze[y][x] = BOOT_PAIR;
|
||||
for (pp = Boot; pp < &Boot[NBOOTS]; pp++)
|
||||
pp->p_flying = -1;
|
||||
}
|
||||
# endif
|
||||
|
||||
|
||||
/*
|
||||
* checkdam:
|
||||
* Check the damage to the given player, and see if s/he is killed
|
||||
*/
|
||||
void
|
||||
checkdam(ouch, gotcha, credit, amt, shot_type)
|
||||
PLAYER *ouch, *gotcha;
|
||||
IDENT *credit;
|
||||
int amt;
|
||||
char shot_type;
|
||||
{
|
||||
const char *cp;
|
||||
|
||||
if (ouch->p_death[0] != '\0')
|
||||
return;
|
||||
# ifdef BOOTS
|
||||
if (shot_type == SLIME)
|
||||
switch (ouch->p_nboots) {
|
||||
default:
|
||||
break;
|
||||
case 1:
|
||||
amt = (amt + 1) / 2;
|
||||
break;
|
||||
case 2:
|
||||
if (gotcha != NULL)
|
||||
message(gotcha, "He has boots on!");
|
||||
return;
|
||||
}
|
||||
# endif
|
||||
ouch->p_damage += amt;
|
||||
if (ouch->p_damage <= ouch->p_damcap) {
|
||||
(void) sprintf(Buf, "%2d", ouch->p_damage);
|
||||
cgoto(ouch, STAT_DAM_ROW, STAT_VALUE_COL);
|
||||
outstr(ouch, Buf, 2);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Someone DIED */
|
||||
switch (shot_type) {
|
||||
default:
|
||||
cp = "Killed";
|
||||
break;
|
||||
# ifdef FLY
|
||||
case FALL:
|
||||
cp = "Killed on impact";
|
||||
break;
|
||||
# endif
|
||||
case KNIFE:
|
||||
cp = "Stabbed to death";
|
||||
ouch->p_ammo = 0; /* No exploding */
|
||||
break;
|
||||
case SHOT:
|
||||
cp = "Shot to death";
|
||||
break;
|
||||
case GRENADE:
|
||||
case SATCHEL:
|
||||
case BOMB:
|
||||
cp = "Bombed";
|
||||
break;
|
||||
case MINE:
|
||||
case GMINE:
|
||||
cp = "Blown apart";
|
||||
break;
|
||||
# ifdef OOZE
|
||||
case SLIME:
|
||||
cp = "Slimed";
|
||||
if (credit != NULL)
|
||||
credit->i_slime++;
|
||||
break;
|
||||
# endif
|
||||
# ifdef VOLCANO
|
||||
case LAVA:
|
||||
cp = "Baked";
|
||||
break;
|
||||
# endif
|
||||
# ifdef DRONE
|
||||
case DSHOT:
|
||||
cp = "Eliminated";
|
||||
break;
|
||||
# endif
|
||||
}
|
||||
if (credit == NULL) {
|
||||
(void) sprintf(ouch->p_death, "| %s by %s |", cp,
|
||||
(shot_type == MINE || shot_type == GMINE) ?
|
||||
"a mine" : "act of God");
|
||||
return;
|
||||
}
|
||||
|
||||
(void) sprintf(ouch->p_death, "| %s by %s |", cp, credit->i_name);
|
||||
|
||||
if (ouch == gotcha) { /* No use killing yourself */
|
||||
credit->i_kills--;
|
||||
credit->i_bkills++;
|
||||
}
|
||||
else if (ouch->p_ident->i_team == ' '
|
||||
|| ouch->p_ident->i_team != credit->i_team) {
|
||||
credit->i_kills++;
|
||||
credit->i_gkills++;
|
||||
}
|
||||
else {
|
||||
credit->i_kills--;
|
||||
credit->i_bkills++;
|
||||
}
|
||||
credit->i_score = credit->i_kills / (double) credit->i_entries;
|
||||
ouch->p_ident->i_deaths++;
|
||||
if (ouch->p_nchar == 0)
|
||||
ouch->p_ident->i_stillb++;
|
||||
if (gotcha == NULL)
|
||||
return;
|
||||
gotcha->p_damcap += STABDAM;
|
||||
gotcha->p_damage -= STABDAM;
|
||||
if (gotcha->p_damage < 0)
|
||||
gotcha->p_damage = 0;
|
||||
(void) sprintf(Buf, "%2d/%2d", gotcha->p_damage, gotcha->p_damcap);
|
||||
cgoto(gotcha, STAT_DAM_ROW, STAT_VALUE_COL);
|
||||
outstr(gotcha, Buf, 5);
|
||||
(void) sprintf(Buf, "%3d", (gotcha->p_damcap - MAXDAM) / 2);
|
||||
cgoto(gotcha, STAT_KILL_ROW, STAT_VALUE_COL);
|
||||
outstr(gotcha, Buf, 3);
|
||||
(void) sprintf(Buf, "%5.2f", gotcha->p_ident->i_score);
|
||||
for (ouch = Player; ouch < End_player; ouch++) {
|
||||
cgoto(ouch, STAT_PLAY_ROW + 1 + (gotcha - Player),
|
||||
STAT_NAME_COL);
|
||||
outstr(ouch, Buf, 5);
|
||||
}
|
||||
# ifdef MONITOR
|
||||
for (ouch = Monitor; ouch < End_monitor; ouch++) {
|
||||
cgoto(ouch, STAT_PLAY_ROW + 1 + (gotcha - Player),
|
||||
STAT_NAME_COL);
|
||||
outstr(ouch, Buf, 5);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
/*
|
||||
* zap:
|
||||
* Kill off a player and take him out of the game.
|
||||
*/
|
||||
static void
|
||||
zap(pp, was_player)
|
||||
PLAYER *pp;
|
||||
FLAG was_player;
|
||||
{
|
||||
int i, len;
|
||||
BULLET *bp;
|
||||
PLAYER *np;
|
||||
int x, y;
|
||||
int savefd;
|
||||
|
||||
if (was_player) {
|
||||
if (pp->p_undershot)
|
||||
fixshots(pp->p_y, pp->p_x, pp->p_over);
|
||||
drawplayer(pp, FALSE);
|
||||
Nplayer--;
|
||||
}
|
||||
|
||||
len = strlen(pp->p_death); /* Display the cause of death */
|
||||
x = (WIDTH - len) / 2;
|
||||
cgoto(pp, HEIGHT / 2, x);
|
||||
outstr(pp, pp->p_death, len);
|
||||
for (i = 1; i < len; i++)
|
||||
pp->p_death[i] = '-';
|
||||
pp->p_death[0] = '+';
|
||||
pp->p_death[len - 1] = '+';
|
||||
cgoto(pp, HEIGHT / 2 - 1, x);
|
||||
outstr(pp, pp->p_death, len);
|
||||
cgoto(pp, HEIGHT / 2 + 1, x);
|
||||
outstr(pp, pp->p_death, len);
|
||||
cgoto(pp, HEIGHT, 0);
|
||||
|
||||
savefd = pp->p_fd;
|
||||
|
||||
# ifdef MONITOR
|
||||
if (was_player) {
|
||||
# endif
|
||||
for (bp = Bullets; bp != NULL; bp = bp->b_next) {
|
||||
if (bp->b_owner == pp)
|
||||
bp->b_owner = NULL;
|
||||
if (bp->b_x == pp->p_x && bp->b_y == pp->p_y)
|
||||
bp->b_over = SPACE;
|
||||
}
|
||||
|
||||
i = rand_num(pp->p_ammo);
|
||||
x = rand_num(pp->p_ammo);
|
||||
if (x > i)
|
||||
i = x;
|
||||
if (pp->p_ammo == 0)
|
||||
x = 0;
|
||||
else if (i == pp->p_ammo - 1) {
|
||||
x = pp->p_ammo;
|
||||
len = SLIME;
|
||||
}
|
||||
else {
|
||||
for (x = MAXBOMB - 1; x > 0; x--)
|
||||
if (i >= shot_req[x])
|
||||
break;
|
||||
for (y = MAXSLIME - 1; y > 0; y--)
|
||||
if (i >= slime_req[y])
|
||||
break;
|
||||
if (y >= 0 && slime_req[y] > shot_req[x]) {
|
||||
x = slime_req[y];
|
||||
len = SLIME;
|
||||
}
|
||||
else if (x != 0) {
|
||||
len = shot_type[x];
|
||||
x = shot_req[x];
|
||||
}
|
||||
}
|
||||
if (x > 0) {
|
||||
(void) add_shot(len, pp->p_y, pp->p_x, pp->p_face, x,
|
||||
(PLAYER *) NULL, TRUE, SPACE);
|
||||
(void) sprintf(Buf, "%s detonated.",
|
||||
pp->p_ident->i_name);
|
||||
for (np = Player; np < End_player; np++)
|
||||
message(np, Buf);
|
||||
# ifdef MONITOR
|
||||
for (np = Monitor; np < End_monitor; np++)
|
||||
message(np, Buf);
|
||||
# endif
|
||||
# ifdef BOOTS
|
||||
while (pp->p_nboots-- > 0) {
|
||||
for (np = Boot; np < &Boot[NBOOTS]; np++)
|
||||
if (np->p_flying < 0)
|
||||
break;
|
||||
if (np >= &Boot[NBOOTS])
|
||||
err(1, "Too many boots");
|
||||
np->p_undershot = FALSE;
|
||||
np->p_x = pp->p_x;
|
||||
np->p_y = pp->p_y;
|
||||
np->p_flying = rand_num(20);
|
||||
np->p_flyx = 2 * rand_num(6) - 5;
|
||||
np->p_flyy = 2 * rand_num(6) - 5;
|
||||
np->p_over = SPACE;
|
||||
np->p_face = BOOT;
|
||||
showexpl(np->p_y, np->p_x, BOOT);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
# ifdef BOOTS
|
||||
else if (pp->p_nboots > 0) {
|
||||
if (pp->p_nboots == 2)
|
||||
Maze[pp->p_y][pp->p_x] = BOOT_PAIR;
|
||||
else
|
||||
Maze[pp->p_y][pp->p_x] = BOOT;
|
||||
if (pp->p_undershot)
|
||||
fixshots(pp->p_y, pp->p_x,
|
||||
Maze[pp->p_y][pp->p_x]);
|
||||
}
|
||||
# endif
|
||||
|
||||
# ifdef VOLCANO
|
||||
volcano += pp->p_ammo - x;
|
||||
if (rand_num(100) < volcano / 50) {
|
||||
do {
|
||||
x = rand_num(WIDTH / 2) + WIDTH / 4;
|
||||
y = rand_num(HEIGHT / 2) + HEIGHT / 4;
|
||||
} while (Maze[y][x] != SPACE);
|
||||
(void) add_shot(LAVA, y, x, LEFTS, volcano,
|
||||
(PLAYER *) NULL, TRUE, SPACE);
|
||||
for (np = Player; np < End_player; np++)
|
||||
message(np, "Volcano eruption.");
|
||||
volcano = 0;
|
||||
}
|
||||
# endif
|
||||
|
||||
# ifdef DRONE
|
||||
if (rand_num(100) < 2) {
|
||||
do {
|
||||
x = rand_num(WIDTH / 2) + WIDTH / 4;
|
||||
y = rand_num(HEIGHT / 2) + HEIGHT / 4;
|
||||
} while (Maze[y][x] != SPACE);
|
||||
add_shot(DSHOT, y, x, rand_dir(),
|
||||
shot_req[MINDSHOT +
|
||||
rand_num(MAXBOMB - MINDSHOT)],
|
||||
(PLAYER *) NULL, FALSE, SPACE);
|
||||
}
|
||||
# endif
|
||||
|
||||
sendcom(pp, ENDWIN);
|
||||
(void) putc(' ', pp->p_output);
|
||||
(void) fclose(pp->p_output);
|
||||
|
||||
End_player--;
|
||||
if (pp != End_player) {
|
||||
memcpy(pp, End_player, sizeof (PLAYER));
|
||||
(void) sprintf(Buf, "%5.2f%c%-10.10s %c",
|
||||
pp->p_ident->i_score, stat_char(pp),
|
||||
pp->p_ident->i_name, pp->p_ident->i_team);
|
||||
i = STAT_PLAY_ROW + 1 + (pp - Player);
|
||||
for (np = Player; np < End_player; np++) {
|
||||
cgoto(np, i, STAT_NAME_COL);
|
||||
outstr(np, Buf, STAT_NAME_LEN);
|
||||
}
|
||||
# ifdef MONITOR
|
||||
for (np = Monitor; np < End_monitor; np++) {
|
||||
cgoto(np, i, STAT_NAME_COL);
|
||||
outstr(np, Buf, STAT_NAME_LEN);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
/* Erase the last player */
|
||||
i = STAT_PLAY_ROW + 1 + Nplayer;
|
||||
for (np = Player; np < End_player; np++) {
|
||||
cgoto(np, i, STAT_NAME_COL);
|
||||
ce(np);
|
||||
}
|
||||
# ifdef MONITOR
|
||||
for (np = Monitor; np < End_monitor; np++) {
|
||||
cgoto(np, i, STAT_NAME_COL);
|
||||
ce(np);
|
||||
}
|
||||
}
|
||||
else {
|
||||
sendcom(pp, ENDWIN);
|
||||
(void) putc(LAST_PLAYER, pp->p_output);
|
||||
(void) fclose(pp->p_output);
|
||||
|
||||
End_monitor--;
|
||||
if (pp != End_monitor) {
|
||||
memcpy(pp, End_monitor, sizeof (PLAYER));
|
||||
(void) sprintf(Buf, "%5.5s %-10.10s %c", " ",
|
||||
pp->p_ident->i_name, pp->p_ident->i_team);
|
||||
i = STAT_MON_ROW + 1 + (pp - Player);
|
||||
for (np = Player; np < End_player; np++) {
|
||||
cgoto(np, i, STAT_NAME_COL);
|
||||
outstr(np, Buf, STAT_NAME_LEN);
|
||||
}
|
||||
for (np = Monitor; np < End_monitor; np++) {
|
||||
cgoto(np, i, STAT_NAME_COL);
|
||||
outstr(np, Buf, STAT_NAME_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
/* Erase the last monitor */
|
||||
i = STAT_MON_ROW + 1 + (End_monitor - Monitor);
|
||||
for (np = Player; np < End_player; np++) {
|
||||
cgoto(np, i, STAT_NAME_COL);
|
||||
ce(np);
|
||||
}
|
||||
for (np = Monitor; np < End_monitor; np++) {
|
||||
cgoto(np, i, STAT_NAME_COL);
|
||||
ce(np);
|
||||
}
|
||||
|
||||
}
|
||||
# endif
|
||||
|
||||
FD_CLR(savefd, &Fds_mask);
|
||||
if (Num_fds == savefd + 1) {
|
||||
Num_fds = Socket;
|
||||
# ifdef INTERNET
|
||||
if (Test_socket > Socket)
|
||||
Num_fds = Test_socket;
|
||||
# endif
|
||||
for (np = Player; np < End_player; np++)
|
||||
if (np->p_fd > Num_fds)
|
||||
Num_fds = np->p_fd;
|
||||
# ifdef MONITOR
|
||||
for (np = Monitor; np < End_monitor; np++)
|
||||
if (np->p_fd > Num_fds)
|
||||
Num_fds = np->p_fd;
|
||||
# endif
|
||||
Num_fds++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* rand_num:
|
||||
* Return a random number in a given range.
|
||||
*/
|
||||
int
|
||||
rand_num(range)
|
||||
int range;
|
||||
{
|
||||
return (range == 0 ? 0 : RN % range);
|
||||
}
|
||||
|
||||
/*
|
||||
* havechar:
|
||||
* Check to see if we have any characters in the input queue; if
|
||||
* we do, read them, stash them away, and return TRUE; else return
|
||||
* FALSE.
|
||||
*/
|
||||
static int
|
||||
havechar(pp)
|
||||
PLAYER *pp;
|
||||
{
|
||||
|
||||
if (pp->p_ncount < pp->p_nchar)
|
||||
return TRUE;
|
||||
if (!FD_ISSET(pp->p_fd, &Have_inp))
|
||||
return FALSE;
|
||||
FD_CLR(pp->p_fd, &Have_inp);
|
||||
check_again:
|
||||
errno = 0;
|
||||
if ((pp->p_nchar = read(pp->p_fd, pp->p_cbuf, sizeof pp->p_cbuf)) <= 0)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
goto check_again;
|
||||
pp->p_cbuf[0] = 'q';
|
||||
}
|
||||
pp->p_ncount = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* cleanup:
|
||||
* Exit with the given value, cleaning up any droppings lying around
|
||||
*/
|
||||
SIGNAL_TYPE
|
||||
cleanup(eval)
|
||||
int eval;
|
||||
{
|
||||
PLAYER *pp;
|
||||
|
||||
for (pp = Player; pp < End_player; pp++) {
|
||||
cgoto(pp, HEIGHT, 0);
|
||||
sendcom(pp, ENDWIN);
|
||||
(void) putc(LAST_PLAYER, pp->p_output);
|
||||
(void) fclose(pp->p_output);
|
||||
}
|
||||
# ifdef MONITOR
|
||||
for (pp = Monitor; pp < End_monitor; pp++) {
|
||||
cgoto(pp, HEIGHT, 0);
|
||||
sendcom(pp, ENDWIN);
|
||||
(void) putc(LAST_PLAYER, pp->p_output);
|
||||
(void) fclose(pp->p_output);
|
||||
}
|
||||
# endif
|
||||
(void) close(Socket);
|
||||
# ifdef AF_UNIX_HACK
|
||||
(void) unlink(Sock_name);
|
||||
# endif
|
||||
|
||||
exit(eval);
|
||||
}
|
||||
|
||||
/*
|
||||
* send_stats:
|
||||
* Print stats to requestor
|
||||
*/
|
||||
static void
|
||||
send_stats()
|
||||
{
|
||||
IDENT *ip;
|
||||
FILE *fp;
|
||||
int s;
|
||||
SOCKET sockstruct;
|
||||
int socklen;
|
||||
|
||||
/*
|
||||
* Get the output stream ready
|
||||
*/
|
||||
# ifdef INTERNET
|
||||
socklen = sizeof sockstruct;
|
||||
# else
|
||||
socklen = sizeof sockstruct - 1;
|
||||
# endif
|
||||
s = accept(Status, (struct sockaddr *) &sockstruct, &socklen);
|
||||
if (s < 0) {
|
||||
if (errno == EINTR)
|
||||
return;
|
||||
# ifdef LOG
|
||||
syslog(LOG_ERR, "accept: %m");
|
||||
# else
|
||||
warn("accept");
|
||||
# endif
|
||||
return;
|
||||
}
|
||||
fp = fdopen(s, "w");
|
||||
if (fp == NULL) {
|
||||
# ifdef LOG
|
||||
syslog(LOG_ERR, "fdopen: %m");
|
||||
# else
|
||||
warn("fdopen");
|
||||
# endif
|
||||
(void) close(s);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send output to requestor
|
||||
*/
|
||||
fputs("Name\t\tScore\tDucked\tAbsorb\tFaced\tShot\tRobbed\tMissed\tSlimeK\n", fp);
|
||||
for (ip = Scores; ip != NULL; ip = ip->i_next) {
|
||||
fprintf(fp, "%s\t", ip->i_name);
|
||||
if (strlen(ip->i_name) < 8)
|
||||
putc('\t', fp);
|
||||
fprintf(fp, "%.2f\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
|
||||
ip->i_score, ip->i_ducked, ip->i_absorbed,
|
||||
ip->i_faced, ip->i_shot, ip->i_robbed,
|
||||
ip->i_missed, ip->i_slime);
|
||||
}
|
||||
fputs("\n\nName\t\tEnemy\tFriend\tDeaths\tStill\tSaved\n", fp);
|
||||
for (ip = Scores; ip != NULL; ip = ip->i_next) {
|
||||
if (ip->i_team == ' ') {
|
||||
fprintf(fp, "%s\t", ip->i_name);
|
||||
if (strlen(ip->i_name) < 8)
|
||||
putc('\t', fp);
|
||||
}
|
||||
else {
|
||||
fprintf(fp, "%s[%c]\t", ip->i_name, ip->i_team);
|
||||
if (strlen(ip->i_name) + 3 < 8)
|
||||
putc('\t', fp);
|
||||
}
|
||||
fprintf(fp, "%d\t%d\t%d\t%d\t%d\n",
|
||||
ip->i_gkills, ip->i_bkills, ip->i_deaths,
|
||||
ip->i_stillb, ip->i_saved);
|
||||
}
|
||||
|
||||
(void) fclose(fp);
|
||||
}
|
||||
|
||||
/*
|
||||
* clear_scores:
|
||||
* Clear out the scores so the next session start clean
|
||||
*/
|
||||
static void
|
||||
clear_scores()
|
||||
{
|
||||
IDENT *ip, *nextip;
|
||||
|
||||
for (ip = Scores; ip != NULL; ip = nextip) {
|
||||
nextip = ip->i_next;
|
||||
(void) free((char *) ip);
|
||||
}
|
||||
Scores = NULL;
|
||||
}
|
||||
582
hunt/huntd/execute.c
Normal file
582
hunt/huntd/execute.c
Normal file
@@ -0,0 +1,582 @@
|
||||
/* $NetBSD: execute.c,v 1.2 1997/10/10 16:33:13 lukem Exp $ */
|
||||
/*
|
||||
* Hunt
|
||||
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
* San Francisco, California
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: execute.c,v 1.2 1997/10/10 16:33:13 lukem Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
# include <stdlib.h>
|
||||
# include "hunt.h"
|
||||
|
||||
static void cloak __P((PLAYER *));
|
||||
static void face __P((PLAYER *, int));
|
||||
static void fire __P((PLAYER *, int));
|
||||
static void fire_slime __P((PLAYER *, int));
|
||||
static void move_player __P((PLAYER *, int));
|
||||
static void pickup __P((PLAYER *, int, int, int, int));
|
||||
static void scan __P((PLAYER *));
|
||||
|
||||
|
||||
# ifdef MONITOR
|
||||
/*
|
||||
* mon_execute:
|
||||
* Execute a single monitor command
|
||||
*/
|
||||
void
|
||||
mon_execute(pp)
|
||||
PLAYER *pp;
|
||||
{
|
||||
char ch;
|
||||
|
||||
ch = pp->p_cbuf[pp->p_ncount++];
|
||||
switch (ch) {
|
||||
case CTRL('L'):
|
||||
sendcom(pp, REDRAW);
|
||||
break;
|
||||
case 'q':
|
||||
(void) strcpy(pp->p_death, "| Quit |");
|
||||
break;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
/*
|
||||
* execute:
|
||||
* Execute a single command
|
||||
*/
|
||||
void
|
||||
execute(pp)
|
||||
PLAYER *pp;
|
||||
{
|
||||
char ch;
|
||||
|
||||
ch = pp->p_cbuf[pp->p_ncount++];
|
||||
|
||||
# ifdef FLY
|
||||
if (pp->p_flying >= 0) {
|
||||
switch (ch) {
|
||||
case CTRL('L'):
|
||||
sendcom(pp, REDRAW);
|
||||
break;
|
||||
case 'q':
|
||||
(void) strcpy(pp->p_death, "| Quit |");
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
# endif
|
||||
|
||||
switch (ch) {
|
||||
case CTRL('L'):
|
||||
sendcom(pp, REDRAW);
|
||||
break;
|
||||
case 'h':
|
||||
move_player(pp, LEFTS);
|
||||
break;
|
||||
case 'H':
|
||||
face(pp, LEFTS);
|
||||
break;
|
||||
case 'j':
|
||||
move_player(pp, BELOW);
|
||||
break;
|
||||
case 'J':
|
||||
face(pp, BELOW);
|
||||
break;
|
||||
case 'k':
|
||||
move_player(pp, ABOVE);
|
||||
break;
|
||||
case 'K':
|
||||
face(pp, ABOVE);
|
||||
break;
|
||||
case 'l':
|
||||
move_player(pp, RIGHT);
|
||||
break;
|
||||
case 'L':
|
||||
face(pp, RIGHT);
|
||||
break;
|
||||
case 'f':
|
||||
case '1':
|
||||
fire(pp, 0); /* SHOT */
|
||||
break;
|
||||
case 'g':
|
||||
case '2':
|
||||
fire(pp, 1); /* GRENADE */
|
||||
break;
|
||||
case 'F':
|
||||
case '3':
|
||||
fire(pp, 2); /* SATCHEL */
|
||||
break;
|
||||
case 'G':
|
||||
case '4':
|
||||
fire(pp, 3); /* 7x7 BOMB */
|
||||
break;
|
||||
case '5':
|
||||
fire(pp, 4); /* 9x9 BOMB */
|
||||
break;
|
||||
case '6':
|
||||
fire(pp, 5); /* 11x11 BOMB */
|
||||
break;
|
||||
case '7':
|
||||
fire(pp, 6); /* 13x13 BOMB */
|
||||
break;
|
||||
case '8':
|
||||
fire(pp, 7); /* 15x15 BOMB */
|
||||
break;
|
||||
case '9':
|
||||
fire(pp, 8); /* 17x17 BOMB */
|
||||
break;
|
||||
case '0':
|
||||
fire(pp, 9); /* 19x19 BOMB */
|
||||
break;
|
||||
case '@':
|
||||
fire(pp, 10); /* 21x21 BOMB */
|
||||
break;
|
||||
# ifdef OOZE
|
||||
case 'o':
|
||||
fire_slime(pp, 0); /* SLIME */
|
||||
break;
|
||||
case 'O':
|
||||
fire_slime(pp, 1); /* SSLIME */
|
||||
break;
|
||||
case 'p':
|
||||
fire_slime(pp, 2);
|
||||
break;
|
||||
case 'P':
|
||||
fire_slime(pp, 3);
|
||||
break;
|
||||
# endif
|
||||
case 's':
|
||||
scan(pp);
|
||||
break;
|
||||
case 'c':
|
||||
cloak(pp);
|
||||
break;
|
||||
case 'q':
|
||||
(void) strcpy(pp->p_death, "| Quit |");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* move_player:
|
||||
* Execute a move in the given direction
|
||||
*/
|
||||
static void
|
||||
move_player(pp, dir)
|
||||
PLAYER *pp;
|
||||
int dir;
|
||||
{
|
||||
PLAYER *newp;
|
||||
int x, y;
|
||||
FLAG moved;
|
||||
BULLET *bp;
|
||||
|
||||
y = pp->p_y;
|
||||
x = pp->p_x;
|
||||
|
||||
switch (dir) {
|
||||
case LEFTS:
|
||||
x--;
|
||||
break;
|
||||
case RIGHT:
|
||||
x++;
|
||||
break;
|
||||
case ABOVE:
|
||||
y--;
|
||||
break;
|
||||
case BELOW:
|
||||
y++;
|
||||
break;
|
||||
}
|
||||
|
||||
moved = FALSE;
|
||||
switch (Maze[y][x]) {
|
||||
case SPACE:
|
||||
# ifdef RANDOM
|
||||
case DOOR:
|
||||
# endif
|
||||
moved = TRUE;
|
||||
break;
|
||||
case WALL1:
|
||||
case WALL2:
|
||||
case WALL3:
|
||||
# ifdef REFLECT
|
||||
case WALL4:
|
||||
case WALL5:
|
||||
# endif
|
||||
break;
|
||||
case MINE:
|
||||
case GMINE:
|
||||
if (dir == pp->p_face)
|
||||
pickup(pp, y, x, 2, Maze[y][x]);
|
||||
else if (opposite(dir, pp->p_face))
|
||||
pickup(pp, y, x, 95, Maze[y][x]);
|
||||
else
|
||||
pickup(pp, y, x, 50, Maze[y][x]);
|
||||
Maze[y][x] = SPACE;
|
||||
moved = TRUE;
|
||||
break;
|
||||
case SHOT:
|
||||
case GRENADE:
|
||||
case SATCHEL:
|
||||
case BOMB:
|
||||
# ifdef OOZE
|
||||
case SLIME:
|
||||
# endif
|
||||
# ifdef DRONE
|
||||
case DSHOT:
|
||||
# endif
|
||||
bp = is_bullet(y, x);
|
||||
if (bp != NULL)
|
||||
bp->b_expl = TRUE;
|
||||
Maze[y][x] = SPACE;
|
||||
moved = TRUE;
|
||||
break;
|
||||
case LEFTS:
|
||||
case RIGHT:
|
||||
case ABOVE:
|
||||
case BELOW:
|
||||
if (dir != pp->p_face)
|
||||
sendcom(pp, BELL);
|
||||
else {
|
||||
newp = play_at(y, x);
|
||||
checkdam(newp, pp, pp->p_ident, STABDAM, KNIFE);
|
||||
}
|
||||
break;
|
||||
# ifdef FLY
|
||||
case FLYER:
|
||||
newp = play_at(y, x);
|
||||
message(newp, "Oooh, there's a short guy waving at you!");
|
||||
message(pp, "You couldn't quite reach him!");
|
||||
break;
|
||||
# endif
|
||||
# ifdef BOOTS
|
||||
case BOOT:
|
||||
case BOOT_PAIR:
|
||||
if (Maze[y][x] == BOOT)
|
||||
pp->p_nboots++;
|
||||
else
|
||||
pp->p_nboots += 2;
|
||||
for (newp = Boot; newp < &Boot[NBOOTS]; newp++) {
|
||||
if (newp->p_flying < 0)
|
||||
continue;
|
||||
if (newp->p_y == y && newp->p_x == x) {
|
||||
newp->p_flying = -1;
|
||||
if (newp->p_undershot)
|
||||
fixshots(y, x, newp->p_over);
|
||||
}
|
||||
}
|
||||
if (pp->p_nboots == 2)
|
||||
message(pp, "Wow! A pair of boots!");
|
||||
else
|
||||
message(pp, "You can hobble around on one boot.");
|
||||
Maze[y][x] = SPACE;
|
||||
moved = TRUE;
|
||||
break;
|
||||
# endif
|
||||
}
|
||||
if (moved) {
|
||||
if (pp->p_ncshot > 0)
|
||||
if (--pp->p_ncshot == MAXNCSHOT) {
|
||||
cgoto(pp, STAT_GUN_ROW, STAT_VALUE_COL);
|
||||
outstr(pp, " ok", 3);
|
||||
}
|
||||
if (pp->p_undershot) {
|
||||
fixshots(pp->p_y, pp->p_x, pp->p_over);
|
||||
pp->p_undershot = FALSE;
|
||||
}
|
||||
drawplayer(pp, FALSE);
|
||||
pp->p_over = Maze[y][x];
|
||||
pp->p_y = y;
|
||||
pp->p_x = x;
|
||||
drawplayer(pp, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* face:
|
||||
* Change the direction the player is facing
|
||||
*/
|
||||
static void
|
||||
face(pp, dir)
|
||||
PLAYER *pp;
|
||||
int dir;
|
||||
{
|
||||
if (pp->p_face != dir) {
|
||||
pp->p_face = dir;
|
||||
drawplayer(pp, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* fire:
|
||||
* Fire a shot of the given type in the given direction
|
||||
*/
|
||||
static void
|
||||
fire(pp, req_index)
|
||||
PLAYER *pp;
|
||||
int req_index;
|
||||
{
|
||||
if (pp == NULL)
|
||||
return;
|
||||
# ifdef DEBUG
|
||||
if (req_index < 0 || req_index >= MAXBOMB)
|
||||
message(pp, "What you do?");
|
||||
# endif
|
||||
while (req_index >= 0 && pp->p_ammo < shot_req[req_index])
|
||||
req_index--;
|
||||
if (req_index < 0) {
|
||||
message(pp, "Not enough charges.");
|
||||
return;
|
||||
}
|
||||
if (pp->p_ncshot > MAXNCSHOT)
|
||||
return;
|
||||
if (pp->p_ncshot++ == MAXNCSHOT) {
|
||||
cgoto(pp, STAT_GUN_ROW, STAT_VALUE_COL);
|
||||
outstr(pp, " ", 3);
|
||||
}
|
||||
pp->p_ammo -= shot_req[req_index];
|
||||
(void) sprintf(Buf, "%3d", pp->p_ammo);
|
||||
cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
|
||||
outstr(pp, Buf, 3);
|
||||
|
||||
add_shot(shot_type[req_index], pp->p_y, pp->p_x, pp->p_face,
|
||||
shot_req[req_index], pp, FALSE, pp->p_face);
|
||||
pp->p_undershot = TRUE;
|
||||
|
||||
/*
|
||||
* Show the object to everyone
|
||||
*/
|
||||
showexpl(pp->p_y, pp->p_x, shot_type[req_index]);
|
||||
for (pp = Player; pp < End_player; pp++)
|
||||
sendcom(pp, REFRESH);
|
||||
# ifdef MONITOR
|
||||
for (pp = Monitor; pp < End_monitor; pp++)
|
||||
sendcom(pp, REFRESH);
|
||||
# endif
|
||||
}
|
||||
|
||||
# ifdef OOZE
|
||||
/*
|
||||
* fire_slime:
|
||||
* Fire a slime shot in the given direction
|
||||
*/
|
||||
static void
|
||||
fire_slime(pp, req_index)
|
||||
PLAYER *pp;
|
||||
int req_index;
|
||||
{
|
||||
if (pp == NULL)
|
||||
return;
|
||||
# ifdef DEBUG
|
||||
if (req_index < 0 || req_index >= MAXSLIME)
|
||||
message(pp, "What you do?");
|
||||
# endif
|
||||
while (req_index >= 0 && pp->p_ammo < slime_req[req_index])
|
||||
req_index--;
|
||||
if (req_index < 0) {
|
||||
message(pp, "Not enough charges.");
|
||||
return;
|
||||
}
|
||||
if (pp->p_ncshot > MAXNCSHOT)
|
||||
return;
|
||||
if (pp->p_ncshot++ == MAXNCSHOT) {
|
||||
cgoto(pp, STAT_GUN_ROW, STAT_VALUE_COL);
|
||||
outstr(pp, " ", 3);
|
||||
}
|
||||
pp->p_ammo -= slime_req[req_index];
|
||||
(void) sprintf(Buf, "%3d", pp->p_ammo);
|
||||
cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
|
||||
outstr(pp, Buf, 3);
|
||||
|
||||
add_shot(SLIME, pp->p_y, pp->p_x, pp->p_face,
|
||||
slime_req[req_index] * SLIME_FACTOR, pp, FALSE, pp->p_face);
|
||||
pp->p_undershot = TRUE;
|
||||
|
||||
/*
|
||||
* Show the object to everyone
|
||||
*/
|
||||
showexpl(pp->p_y, pp->p_x, SLIME);
|
||||
for (pp = Player; pp < End_player; pp++)
|
||||
sendcom(pp, REFRESH);
|
||||
# ifdef MONITOR
|
||||
for (pp = Monitor; pp < End_monitor; pp++)
|
||||
sendcom(pp, REFRESH);
|
||||
# endif
|
||||
}
|
||||
# endif
|
||||
|
||||
/*
|
||||
* add_shot:
|
||||
* Create a shot with the given properties
|
||||
*/
|
||||
void
|
||||
add_shot(type, y, x, face, charge, owner, expl, over)
|
||||
int type;
|
||||
int y, x;
|
||||
char face;
|
||||
int charge;
|
||||
PLAYER *owner;
|
||||
int expl;
|
||||
char over;
|
||||
{
|
||||
BULLET *bp;
|
||||
int size;
|
||||
|
||||
switch (type) {
|
||||
case SHOT:
|
||||
case MINE:
|
||||
size = 1;
|
||||
break;
|
||||
case GRENADE:
|
||||
case GMINE:
|
||||
size = 2;
|
||||
break;
|
||||
case SATCHEL:
|
||||
size = 3;
|
||||
break;
|
||||
case BOMB:
|
||||
for (size = 3; size < MAXBOMB; size++)
|
||||
if (shot_req[size] >= charge)
|
||||
break;
|
||||
size++;
|
||||
break;
|
||||
default:
|
||||
size = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
bp = create_shot(type, y, x, face, charge, size, owner,
|
||||
(owner == NULL) ? NULL : owner->p_ident, expl, over);
|
||||
bp->b_next = Bullets;
|
||||
Bullets = bp;
|
||||
}
|
||||
|
||||
BULLET *
|
||||
create_shot(type, y, x, face, charge, size, owner, score, expl, over)
|
||||
int type;
|
||||
int y, x;
|
||||
char face;
|
||||
int charge;
|
||||
int size;
|
||||
PLAYER *owner;
|
||||
IDENT *score;
|
||||
int expl;
|
||||
char over;
|
||||
{
|
||||
BULLET *bp;
|
||||
|
||||
bp = (BULLET *) malloc(sizeof (BULLET)); /* NOSTRICT */
|
||||
if (bp == NULL) {
|
||||
if (owner != NULL)
|
||||
message(owner, "Out of memory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bp->b_face = face;
|
||||
bp->b_x = x;
|
||||
bp->b_y = y;
|
||||
bp->b_charge = charge;
|
||||
bp->b_owner = owner;
|
||||
bp->b_score = score;
|
||||
bp->b_type = type;
|
||||
bp->b_size = size;
|
||||
bp->b_expl = expl;
|
||||
bp->b_over = over;
|
||||
bp->b_next = NULL;
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
||||
/*
|
||||
* cloak:
|
||||
* Turn on or increase length of a cloak
|
||||
*/
|
||||
static void
|
||||
cloak(pp)
|
||||
PLAYER *pp;
|
||||
{
|
||||
if (pp->p_ammo <= 0) {
|
||||
message(pp, "No more charges");
|
||||
return;
|
||||
}
|
||||
# ifdef BOOTS
|
||||
if (pp->p_nboots > 0) {
|
||||
message(pp, "Boots are too noisy to cloak!");
|
||||
return;
|
||||
}
|
||||
# endif
|
||||
(void) sprintf(Buf, "%3d", --pp->p_ammo);
|
||||
cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
|
||||
outstr(pp, Buf, 3);
|
||||
|
||||
pp->p_cloak += CLOAKLEN;
|
||||
|
||||
if (pp->p_scan >= 0)
|
||||
pp->p_scan = -1;
|
||||
|
||||
showstat(pp);
|
||||
}
|
||||
|
||||
/*
|
||||
* scan:
|
||||
* Turn on or increase length of a scan
|
||||
*/
|
||||
static void
|
||||
scan(pp)
|
||||
PLAYER *pp;
|
||||
{
|
||||
if (pp->p_ammo <= 0) {
|
||||
message(pp, "No more charges");
|
||||
return;
|
||||
}
|
||||
(void) sprintf(Buf, "%3d", --pp->p_ammo);
|
||||
cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
|
||||
outstr(pp, Buf, 3);
|
||||
|
||||
pp->p_scan += SCANLEN;
|
||||
|
||||
if (pp->p_cloak >= 0)
|
||||
pp->p_cloak = -1;
|
||||
|
||||
showstat(pp);
|
||||
}
|
||||
|
||||
/*
|
||||
* pickup:
|
||||
* check whether the object blew up or whether he picked it up
|
||||
*/
|
||||
void
|
||||
pickup(pp, y, x, prob, obj)
|
||||
PLAYER *pp;
|
||||
int y, x;
|
||||
int prob;
|
||||
int obj;
|
||||
{
|
||||
int req;
|
||||
|
||||
switch (obj) {
|
||||
case MINE:
|
||||
req = BULREQ;
|
||||
break;
|
||||
case GMINE:
|
||||
req = GRENREQ;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
if (rand_num(100) < prob)
|
||||
add_shot(obj, y, x, LEFTS, req, (PLAYER *) NULL,
|
||||
TRUE, pp->p_face);
|
||||
else {
|
||||
pp->p_ammo += req;
|
||||
(void) sprintf(Buf, "%3d", pp->p_ammo);
|
||||
cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
|
||||
outstr(pp, Buf, 3);
|
||||
}
|
||||
}
|
||||
233
hunt/huntd/expl.c
Normal file
233
hunt/huntd/expl.c
Normal file
@@ -0,0 +1,233 @@
|
||||
/* $NetBSD: expl.c,v 1.2 1997/10/10 16:33:18 lukem Exp $ */
|
||||
/*
|
||||
* Hunt
|
||||
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
* San Francisco, California
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: expl.c,v 1.2 1997/10/10 16:33:18 lukem Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
# include <stdlib.h>
|
||||
# include "hunt.h"
|
||||
|
||||
static void remove_wall __P((int, int));
|
||||
|
||||
|
||||
/*
|
||||
* showexpl:
|
||||
* Show the explosions as they currently are
|
||||
*/
|
||||
void
|
||||
showexpl(y, x, type)
|
||||
int y, x;
|
||||
char type;
|
||||
{
|
||||
PLAYER *pp;
|
||||
EXPL *ep;
|
||||
|
||||
if (y < 0 || y >= HEIGHT)
|
||||
return;
|
||||
if (x < 0 || x >= WIDTH)
|
||||
return;
|
||||
ep = (EXPL *) malloc(sizeof (EXPL)); /* NOSTRICT */
|
||||
if (ep == NULL) {
|
||||
# ifdef LOG
|
||||
syslog(LOG_ERR, "Out of memory");
|
||||
# else
|
||||
warnx("Out of memory");
|
||||
# endif
|
||||
cleanup(1);
|
||||
}
|
||||
ep->e_y = y;
|
||||
ep->e_x = x;
|
||||
ep->e_char = type;
|
||||
ep->e_next = NULL;
|
||||
if (Last_expl == NULL)
|
||||
Expl[0] = ep;
|
||||
else
|
||||
Last_expl->e_next = ep;
|
||||
Last_expl = ep;
|
||||
for (pp = Player; pp < End_player; pp++) {
|
||||
if (pp->p_maze[y][x] == type)
|
||||
continue;
|
||||
pp->p_maze[y][x] = type;
|
||||
cgoto(pp, y, x);
|
||||
outch(pp, type);
|
||||
}
|
||||
# ifdef MONITOR
|
||||
for (pp = Monitor; pp < End_monitor; pp++) {
|
||||
if (pp->p_maze[y][x] == type)
|
||||
continue;
|
||||
pp->p_maze[y][x] = type;
|
||||
cgoto(pp, y, x);
|
||||
outch(pp, type);
|
||||
}
|
||||
# endif
|
||||
switch (Maze[y][x]) {
|
||||
case WALL1:
|
||||
case WALL2:
|
||||
case WALL3:
|
||||
# ifdef RANDOM
|
||||
case DOOR:
|
||||
# endif
|
||||
# ifdef REFLECT
|
||||
case WALL4:
|
||||
case WALL5:
|
||||
# endif
|
||||
if (y >= UBOUND && y < DBOUND && x >= LBOUND && x < RBOUND)
|
||||
remove_wall(y, x);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* rollexpl:
|
||||
* Roll the explosions over, so the next one in the list is at the
|
||||
* top
|
||||
*/
|
||||
void
|
||||
rollexpl()
|
||||
{
|
||||
EXPL *ep;
|
||||
PLAYER *pp;
|
||||
int y, x;
|
||||
char c;
|
||||
EXPL *nextep;
|
||||
|
||||
for (ep = Expl[EXPLEN - 1]; ep != NULL; ep = nextep) {
|
||||
nextep = ep->e_next;
|
||||
y = ep->e_y;
|
||||
x = ep->e_x;
|
||||
if (y < UBOUND || y >= DBOUND || x < LBOUND || x >= RBOUND)
|
||||
c = Maze[y][x];
|
||||
else
|
||||
c = SPACE;
|
||||
for (pp = Player; pp < End_player; pp++)
|
||||
if (pp->p_maze[y][x] == ep->e_char) {
|
||||
pp->p_maze[y][x] = c;
|
||||
cgoto(pp, y, x);
|
||||
outch(pp, c);
|
||||
}
|
||||
# ifdef MONITOR
|
||||
for (pp = Monitor; pp < End_monitor; pp++)
|
||||
check(pp, y, x);
|
||||
# endif
|
||||
free((char *) ep);
|
||||
}
|
||||
for (x = EXPLEN - 1; x > 0; x--)
|
||||
Expl[x] = Expl[x - 1];
|
||||
Last_expl = Expl[0] = NULL;
|
||||
}
|
||||
|
||||
/* There's about 700 walls in the initial maze. So we pick a number
|
||||
* that keeps the maze relatively full. */
|
||||
# define MAXREMOVE 40
|
||||
|
||||
static REGEN removed[MAXREMOVE];
|
||||
static REGEN *rem_index = removed;
|
||||
|
||||
/*
|
||||
* remove_wall - add a location where the wall was blown away.
|
||||
* if there is no space left over, put the a wall at
|
||||
* the location currently pointed at.
|
||||
*/
|
||||
static void
|
||||
remove_wall(y, x)
|
||||
int y, x;
|
||||
{
|
||||
REGEN *r;
|
||||
# if defined(MONITOR) || defined(FLY)
|
||||
PLAYER *pp;
|
||||
# endif
|
||||
# ifdef FLY
|
||||
char save_char = 0;
|
||||
# endif
|
||||
|
||||
r = rem_index;
|
||||
while (r->r_y != 0) {
|
||||
# ifdef FLY
|
||||
switch (Maze[r->r_y][r->r_x]) {
|
||||
case SPACE:
|
||||
case LEFTS:
|
||||
case RIGHT:
|
||||
case ABOVE:
|
||||
case BELOW:
|
||||
case FLYER:
|
||||
save_char = Maze[r->r_y][r->r_x];
|
||||
goto found;
|
||||
}
|
||||
# else
|
||||
if (Maze[r->r_y][r->r_x] == SPACE)
|
||||
break;
|
||||
# endif
|
||||
if (++r >= &removed[MAXREMOVE])
|
||||
r = removed;
|
||||
}
|
||||
|
||||
found:
|
||||
if (r->r_y != 0) {
|
||||
/* Slot being used, put back this wall */
|
||||
# ifdef FLY
|
||||
if (save_char == SPACE)
|
||||
Maze[r->r_y][r->r_x] = Orig_maze[r->r_y][r->r_x];
|
||||
else {
|
||||
pp = play_at(r->r_y, r->r_x);
|
||||
if (pp->p_flying >= 0)
|
||||
pp->p_flying += rand_num(10);
|
||||
else {
|
||||
pp->p_flying = rand_num(20);
|
||||
pp->p_flyx = 2 * rand_num(6) - 5;
|
||||
pp->p_flyy = 2 * rand_num(6) - 5;
|
||||
}
|
||||
pp->p_over = Orig_maze[r->r_y][r->r_x];
|
||||
pp->p_face = FLYER;
|
||||
Maze[r->r_y][r->r_x] = FLYER;
|
||||
showexpl(r->r_y, r->r_x, FLYER);
|
||||
}
|
||||
# else
|
||||
Maze[r->r_y][r->r_x] = Orig_maze[r->r_y][r->r_x];
|
||||
# endif
|
||||
# ifdef RANDOM
|
||||
if (rand_num(100) == 0)
|
||||
Maze[r->r_y][r->r_x] = DOOR;
|
||||
# endif
|
||||
# ifdef REFLECT
|
||||
if (rand_num(100) == 0) /* one percent of the time */
|
||||
Maze[r->r_y][r->r_x] = WALL4;
|
||||
# endif
|
||||
# ifdef MONITOR
|
||||
for (pp = Monitor; pp < End_monitor; pp++)
|
||||
check(pp, r->r_y, r->r_x);
|
||||
# endif
|
||||
}
|
||||
|
||||
r->r_y = y;
|
||||
r->r_x = x;
|
||||
if (++r >= &removed[MAXREMOVE])
|
||||
rem_index = removed;
|
||||
else
|
||||
rem_index = r;
|
||||
|
||||
Maze[y][x] = SPACE;
|
||||
# ifdef MONITOR
|
||||
for (pp = Monitor; pp < End_monitor; pp++)
|
||||
check(pp, y, x);
|
||||
# endif
|
||||
}
|
||||
|
||||
/*
|
||||
* clearwalls:
|
||||
* Clear out the walls array
|
||||
*/
|
||||
void
|
||||
clearwalls()
|
||||
{
|
||||
REGEN *rp;
|
||||
|
||||
for (rp = removed; rp < &removed[MAXREMOVE]; rp++)
|
||||
rp->r_y = 0;
|
||||
rem_index = removed;
|
||||
}
|
||||
68
hunt/huntd/extern.c
Normal file
68
hunt/huntd/extern.c
Normal file
@@ -0,0 +1,68 @@
|
||||
/* $NetBSD: extern.c,v 1.2 1997/10/10 16:33:24 lukem Exp $ */
|
||||
/*
|
||||
* Hunt
|
||||
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
* San Francisco, California
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: extern.c,v 1.2 1997/10/10 16:33:24 lukem Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
# include "hunt.h"
|
||||
|
||||
# ifdef MONITOR
|
||||
FLAG Am_monitor = FALSE; /* current process is a monitor */
|
||||
# endif
|
||||
|
||||
char Buf[BUFSIZ]; /* general scribbling buffer */
|
||||
char Maze[HEIGHT][WIDTH2]; /* the maze */
|
||||
char Orig_maze[HEIGHT][WIDTH2]; /* the original maze */
|
||||
|
||||
fd_set Fds_mask; /* mask for the file descriptors */
|
||||
fd_set Have_inp; /* which file descriptors have input */
|
||||
int Nplayer = 0; /* number of players */
|
||||
int Num_fds; /* number of maximum file descriptor */
|
||||
int Socket; /* main socket */
|
||||
int Status; /* stat socket */
|
||||
int See_over[NASCII]; /* lookup table for determining whether
|
||||
* character represents "transparent"
|
||||
* item */
|
||||
|
||||
BULLET *Bullets = NULL; /* linked list of bullets */
|
||||
|
||||
EXPL *Expl[EXPLEN]; /* explosion lists */
|
||||
EXPL *Last_expl; /* last explosion on Expl[0] */
|
||||
|
||||
PLAYER Player[MAXPL]; /* all the players */
|
||||
PLAYER *End_player = Player; /* last active player slot */
|
||||
# ifdef BOOTS
|
||||
PLAYER Boot[NBOOTS]; /* all the boots */
|
||||
# endif
|
||||
IDENT *Scores; /* score cache */
|
||||
# ifdef MONITOR
|
||||
PLAYER Monitor[MAXMON]; /* all the monitors */
|
||||
PLAYER *End_monitor = Monitor; /* last active monitor slot */
|
||||
# endif
|
||||
|
||||
# ifdef VOLCANO
|
||||
int volcano = 0; /* Explosion size */
|
||||
# endif
|
||||
|
||||
int shot_req[MAXBOMB] = {
|
||||
BULREQ, GRENREQ, SATREQ,
|
||||
BOMB7REQ, BOMB9REQ, BOMB11REQ,
|
||||
BOMB13REQ, BOMB15REQ, BOMB17REQ,
|
||||
BOMB19REQ, BOMB21REQ,
|
||||
};
|
||||
int shot_type[MAXBOMB] = {
|
||||
SHOT, GRENADE, SATCHEL,
|
||||
BOMB, BOMB, BOMB,
|
||||
BOMB, BOMB, BOMB,
|
||||
BOMB, BOMB,
|
||||
};
|
||||
|
||||
int slime_req[MAXSLIME] = {
|
||||
SLIMEREQ, SSLIMEREQ, SLIME2REQ, SLIME3REQ,
|
||||
};
|
||||
232
hunt/huntd/faketalk.c
Normal file
232
hunt/huntd/faketalk.c
Normal file
@@ -0,0 +1,232 @@
|
||||
/* $NetBSD: faketalk.c,v 1.4 1997/10/11 08:13:48 lukem Exp $ */
|
||||
/*
|
||||
* Hunt
|
||||
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
* San Francisco, California
|
||||
*
|
||||
* Copyright (c) 1985 Regents of the University of California.
|
||||
* All rights reserved. The Berkeley software License Agreement
|
||||
* specifies the terms and conditions for redistribution.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: faketalk.c,v 1.4 1997/10/11 08:13:48 lukem Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include "bsd.h"
|
||||
|
||||
#if defined(TALK_43) || defined(TALK_42)
|
||||
|
||||
# include <sys/time.h>
|
||||
# include <sys/wait.h>
|
||||
# include <ctype.h>
|
||||
# include <netdb.h>
|
||||
# include <signal.h>
|
||||
# include <stdio.h>
|
||||
# include <string.h>
|
||||
# include <unistd.h>
|
||||
# include "hunt.h"
|
||||
# include "talk_ctl.h"
|
||||
|
||||
# define TRUE 1
|
||||
# define FALSE 0
|
||||
|
||||
/* defines for fake talk message to announce start of game */
|
||||
# ifdef TALK_43
|
||||
# define MASQUERADE "\"Hunt Game\""
|
||||
# else
|
||||
# define MASQUERADE "HuntGame"
|
||||
# endif
|
||||
# define RENDEZVOUS "hunt-players"
|
||||
# define ARGV0 "HUNT-ANNOUNCE"
|
||||
|
||||
extern char *my_machine_name;
|
||||
extern char *First_arg, *Last_arg;
|
||||
|
||||
static void do_announce __P((char *));
|
||||
SIGNAL_TYPE exorcise __P((int));
|
||||
|
||||
/*
|
||||
* exorcise - disspell zombies
|
||||
*/
|
||||
|
||||
SIGNAL_TYPE
|
||||
exorcise(dummy)
|
||||
int dummy __attribute__((unused));
|
||||
{
|
||||
(void) wait(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* query the local SMTP daemon to expand the RENDEZVOUS mailing list
|
||||
* and fake a talk request to each address thus found.
|
||||
*/
|
||||
|
||||
void
|
||||
faketalk()
|
||||
{
|
||||
struct servent *sp;
|
||||
char buf[BUFSIZ];
|
||||
FILE *f;
|
||||
int service; /* socket of service */
|
||||
struct sockaddr_in des; /* address of destination */
|
||||
char *a;
|
||||
const char *b;
|
||||
extern char **environ;
|
||||
|
||||
(void) signal(SIGCHLD, exorcise);
|
||||
|
||||
if (fork() != 0)
|
||||
return;
|
||||
|
||||
(void) signal(SIGINT, SIG_IGN);
|
||||
(void) signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
/*
|
||||
* change argv so that a ps shows ARGV0
|
||||
*/
|
||||
*environ = NULL;
|
||||
for (a = First_arg, b = ARGV0; a < Last_arg; a++) {
|
||||
if (*b)
|
||||
*a = *b++;
|
||||
else
|
||||
*a = ' ';
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize "talk"
|
||||
*/
|
||||
get_local_name(MASQUERADE);
|
||||
open_ctl();
|
||||
|
||||
/*
|
||||
* start fetching addresses
|
||||
*/
|
||||
|
||||
if ((sp = getservbyname("smtp", (char *) NULL)) == NULL) {
|
||||
# ifdef LOG
|
||||
syslog(LOG_ERR, "faketalk: smtp protocol not supported\n");
|
||||
# else
|
||||
warn("faketalk: smtp protocol not supported");
|
||||
# endif
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
memset(&des, 0, sizeof (des));
|
||||
des.sin_family = AF_INET;
|
||||
des.sin_addr = my_machine_addr;
|
||||
des.sin_port = sp->s_port;
|
||||
|
||||
if ((service = socket(des.sin_family, SOCK_STREAM, 0)) < 0) {
|
||||
# ifdef LOG
|
||||
syslog(LOG_ERR, "falktalk: socket");
|
||||
# else
|
||||
warn("falktalk: socket");
|
||||
# endif
|
||||
_exit(-1);
|
||||
}
|
||||
|
||||
if (connect(service, (struct sockaddr *) &des, sizeof(des)) != 0) {
|
||||
# ifdef LOG
|
||||
syslog(LOG_ERR, "faketalk: connect");
|
||||
# else
|
||||
warn("faketalk: connect");
|
||||
# endif
|
||||
_exit(-1);
|
||||
}
|
||||
if ((f = fdopen(service, "r")) == NULL) {
|
||||
# ifdef LOG
|
||||
syslog(LOG_ERR, "fdopen failed\n");
|
||||
# else
|
||||
warn("faketalk: fdopen");
|
||||
# endif
|
||||
_exit(-2);
|
||||
}
|
||||
|
||||
(void) fgets(buf, BUFSIZ, f);
|
||||
(void) sprintf(buf, "HELO HuntGame@%s\r\n", my_machine_name);
|
||||
(void) write(service, buf, strlen(buf));
|
||||
(void) fgets(buf, BUFSIZ, f);
|
||||
(void) sprintf(buf, "EXPN %s@%s\r\n", RENDEZVOUS, my_machine_name);
|
||||
(void) write(service, buf, strlen(buf));
|
||||
while (fgets(buf, BUFSIZ, f) != NULL) {
|
||||
char *s, *t;
|
||||
|
||||
if (buf[0] != '2' || buf[1] != '5' || buf[2] != '0')
|
||||
break;
|
||||
if ((s = strchr(buf + 4, '<')) == NULL)
|
||||
s = buf + 4, t = buf + strlen(buf) - 1;
|
||||
else {
|
||||
s += 1;
|
||||
if ((t = strrchr(s, '>')) == NULL)
|
||||
t = s + strlen(s) - 1;
|
||||
else
|
||||
t -= 1;
|
||||
}
|
||||
while (isspace(*s))
|
||||
s += 1;
|
||||
if (*s == '\\')
|
||||
s += 1;
|
||||
while (isspace(*t))
|
||||
t -= 1;
|
||||
*(t + 1) = '\0';
|
||||
do_announce(s); /* construct and send talk request */
|
||||
if (buf[3] == ' ')
|
||||
break;
|
||||
}
|
||||
(void) shutdown(service, 2);
|
||||
(void) close(service);
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* The msg.id's for the invitations on the local and remote machines.
|
||||
* These are used to delete the invitations.
|
||||
*/
|
||||
|
||||
static void
|
||||
do_announce(s)
|
||||
char *s;
|
||||
{
|
||||
CTL_RESPONSE response;
|
||||
extern struct sockaddr_in ctl_addr;
|
||||
|
||||
get_remote_name(s); /* setup his_machine_addr, msg.r_name */
|
||||
|
||||
# ifdef TALK_43
|
||||
# if BSD_RELEASE >= 44
|
||||
msg.ctl_addr = *(struct osockaddr *) &ctl_addr;
|
||||
# else
|
||||
msg.ctl_addr = *(struct sockaddr *) &ctl_addr;
|
||||
# endif
|
||||
msg.ctl_addr.sa_family = htons(msg.ctl_addr.sa_family);
|
||||
# else
|
||||
msg.ctl_addr = ctl_addr;
|
||||
msg.ctl_addr.sin_family = htons(msg.ctl_addr.sin_family);
|
||||
# endif
|
||||
msg.id_num = (int) htonl((u_int32_t) -1); /* an impossible id_num */
|
||||
ctl_transact(his_machine_addr, msg, ANNOUNCE, &response);
|
||||
if (response.answer != SUCCESS)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Have the daemons delete the invitations now that we
|
||||
* have announced.
|
||||
*/
|
||||
|
||||
/* we don't care if cleanup doesn't make it. */
|
||||
msg.type = DELETE;
|
||||
msg.id_num = (int) htonl(response.id_num);
|
||||
daemon_addr.sin_addr = his_machine_addr;
|
||||
if (sendto(ctl_sockt, (char *) &msg, sizeof (msg), 0,
|
||||
(struct sockaddr *) &daemon_addr, sizeof(daemon_addr))
|
||||
!= sizeof(msg))
|
||||
p_error("send delete remote");
|
||||
}
|
||||
#else
|
||||
faketalk()
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
133
hunt/huntd/get_names.c
Normal file
133
hunt/huntd/get_names.c
Normal file
@@ -0,0 +1,133 @@
|
||||
/* $NetBSD: get_names.c,v 1.3 1998/07/06 07:00:31 mrg Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1983 Regents of the University of California.
|
||||
* All rights reserved. The Berkeley software License Agreement
|
||||
* specifies the terms and conditions for redistribution.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: get_names.c,v 1.3 1998/07/06 07:00:31 mrg Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include "bsd.h"
|
||||
|
||||
#if defined(TALK_43) || defined(TALK_42)
|
||||
|
||||
# include <sys/param.h>
|
||||
# include <netdb.h>
|
||||
# include <stdio.h>
|
||||
# include <string.h>
|
||||
# include <unistd.h>
|
||||
# include "hunt.h"
|
||||
# include "talk_ctl.h"
|
||||
|
||||
extern CTL_MSG msg;
|
||||
|
||||
static char hostname[MAXHOSTNAMELEN + 1];
|
||||
char *my_machine_name;
|
||||
|
||||
/*
|
||||
* Determine the local user and machine
|
||||
*/
|
||||
void
|
||||
get_local_name(my_name)
|
||||
const char *my_name;
|
||||
{
|
||||
struct hostent *hp;
|
||||
struct servent *sp;
|
||||
|
||||
/* Load these useful values into the standard message header */
|
||||
msg.id_num = 0;
|
||||
(void) strncpy(msg.l_name, my_name, NAME_SIZE);
|
||||
msg.l_name[NAME_SIZE - 1] = '\0';
|
||||
msg.r_tty[0] = '\0';
|
||||
msg.pid = getpid();
|
||||
# ifdef TALK_43
|
||||
msg.vers = TALK_VERSION;
|
||||
msg.addr.sa_family = htons(AF_INET);
|
||||
msg.ctl_addr.sa_family = htons(AF_INET);
|
||||
# else
|
||||
msg.addr.sin_family = htons(AF_INET);
|
||||
msg.ctl_addr.sin_family = htons(AF_INET);
|
||||
# endif
|
||||
|
||||
(void)gethostname(hostname, sizeof (hostname));
|
||||
hostname[sizeof(hostname) - 1] = '\0';
|
||||
my_machine_name = hostname;
|
||||
/* look up the address of the local host */
|
||||
hp = gethostbyname(my_machine_name);
|
||||
if (hp == (struct hostent *) 0) {
|
||||
printf("This machine doesn't exist. Boy, am I confused!\n");
|
||||
exit(-1);
|
||||
}
|
||||
memcpy(&my_machine_addr, hp->h_addr, hp->h_length);
|
||||
/* find the daemon portal */
|
||||
# ifdef TALK_43
|
||||
sp = getservbyname("ntalk", "udp");
|
||||
# else
|
||||
sp = getservbyname("talk", "udp");
|
||||
# endif
|
||||
if (sp == 0) {
|
||||
# ifdef LOG
|
||||
syslog(LOG_ERR, "This machine doesn't support talk");
|
||||
# else
|
||||
perror("This machine doesn't support talk");
|
||||
# endif
|
||||
exit(-1);
|
||||
}
|
||||
daemon_port = sp->s_port;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine the remote user and machine
|
||||
*/
|
||||
int
|
||||
get_remote_name(his_address)
|
||||
char *his_address;
|
||||
{
|
||||
char *his_name;
|
||||
char *his_machine_name;
|
||||
char *ptr;
|
||||
struct hostent *hp;
|
||||
|
||||
|
||||
/* check for, and strip out, the machine name of the target */
|
||||
for (ptr = his_address; *ptr != '\0' && *ptr != '@' && *ptr != ':'
|
||||
&& *ptr != '!' && *ptr != '.'; ptr++)
|
||||
continue;
|
||||
if (*ptr == '\0') {
|
||||
/* this is a local to local talk */
|
||||
his_name = his_address;
|
||||
his_machine_name = my_machine_name;
|
||||
} else {
|
||||
if (*ptr == '@') {
|
||||
/* user@host */
|
||||
his_name = his_address;
|
||||
his_machine_name = ptr + 1;
|
||||
} else {
|
||||
/* host.user or host!user or host:user */
|
||||
his_name = ptr + 1;
|
||||
his_machine_name = his_address;
|
||||
}
|
||||
*ptr = '\0';
|
||||
}
|
||||
/* Load these useful values into the standard message header */
|
||||
(void) strncpy(msg.r_name, his_name, NAME_SIZE);
|
||||
msg.r_name[NAME_SIZE - 1] = '\0';
|
||||
|
||||
/* if he is on the same machine, then simply copy */
|
||||
if (memcmp((char *) &his_machine_name, (char *) &my_machine_name,
|
||||
sizeof(his_machine_name)) == 0)
|
||||
memcpy(&his_machine_addr, &my_machine_addr,
|
||||
sizeof(his_machine_name));
|
||||
else {
|
||||
/* look up the address of the recipient's machine */
|
||||
hp = gethostbyname(his_machine_name);
|
||||
if (hp == (struct hostent *) 0)
|
||||
return 0; /* unknown host */
|
||||
memcpy(&his_machine_addr, hp->h_addr, hp->h_length);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
458
hunt/huntd/hunt.h
Normal file
458
hunt/huntd/hunt.h
Normal file
@@ -0,0 +1,458 @@
|
||||
/* $NetBSD: hunt.h,v 1.5 1998/09/13 15:27:28 hubertf Exp $ */
|
||||
|
||||
/*
|
||||
* Hunt
|
||||
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
* San Francisco, California
|
||||
*/
|
||||
|
||||
# include "bsd.h"
|
||||
|
||||
# include <errno.h>
|
||||
# include <stdio.h>
|
||||
# include <string.h>
|
||||
# ifdef LOG
|
||||
# include <syslog.h>
|
||||
# endif
|
||||
# if !defined(TERMINFO) && BSD_RELEASE < 44
|
||||
# include <sgtty.h>
|
||||
# else
|
||||
# include <sys/ioctl.h>
|
||||
# endif
|
||||
# include <sys/types.h>
|
||||
# include <sys/uio.h>
|
||||
# include <sys/socket.h>
|
||||
# ifdef INTERNET
|
||||
# include <netinet/in.h>
|
||||
# include <netdb.h>
|
||||
# include <arpa/inet.h>
|
||||
# ifdef BROADCAST
|
||||
# include <net/if.h>
|
||||
# endif
|
||||
# else
|
||||
# include <sys/un.h>
|
||||
# endif
|
||||
|
||||
# ifdef INTERNET
|
||||
# define SOCK_FAMILY AF_INET
|
||||
# else
|
||||
# define SOCK_FAMILY AF_UNIX
|
||||
# define AF_UNIX_HACK /* 4.2 hack; leaves files around */
|
||||
# endif
|
||||
|
||||
/*
|
||||
* Preprocessor define dependencies
|
||||
*/
|
||||
# if defined(VOLCANO) && !defined(OOZE)
|
||||
# define OOZE
|
||||
# endif
|
||||
# if defined(BOOTS) && !defined(FLY)
|
||||
# define FLY
|
||||
# endif
|
||||
# if !defined(REFLECT) && !defined(RANDOM)
|
||||
# define RANDOM
|
||||
# endif
|
||||
# ifdef TERMINFO
|
||||
/* mvcur() in terminfo needs the curses library to be initialized to not
|
||||
* coredump, so give up and use it. */
|
||||
# define USE_CURSES
|
||||
# endif
|
||||
|
||||
/* decrement version number for each change in startup protocol */
|
||||
# define HUNT_VERSION -1
|
||||
|
||||
# define ADDCH ('a' | 0200)
|
||||
# define MOVE ('m' | 0200)
|
||||
# define REFRESH ('r' | 0200)
|
||||
# define CLRTOEOL ('c' | 0200)
|
||||
# define ENDWIN ('e' | 0200)
|
||||
# define CLEAR ('C' | 0200)
|
||||
# define REDRAW ('R' | 0200)
|
||||
# define LAST_PLAYER ('l' | 0200)
|
||||
# define BELL ('b' | 0200)
|
||||
# define READY ('g' | 0200)
|
||||
|
||||
/*
|
||||
* Choose MAXPL and MAXMON carefully. The screen is assumed to be
|
||||
* 23 lines high and will only tolerate (MAXPL == 17 && MAXMON == 0)
|
||||
* or (MAXPL + MAXMON <= 16).
|
||||
*/
|
||||
# ifdef MONITOR
|
||||
# define MAXPL 15
|
||||
# define MAXMON 1
|
||||
# else
|
||||
# define MAXPL 17
|
||||
# endif
|
||||
# define SHORTLEN 2 /* sizeof (network short) */
|
||||
# define LONGLEN 4 /* sizeof (network long) */
|
||||
# define NAMELEN 20
|
||||
# define MSGLEN SCREEN_WIDTH
|
||||
# define DECAY 50.0
|
||||
|
||||
# define NASCII 128
|
||||
|
||||
# define WIDTH 51
|
||||
# define WIDTH2 64 /* Next power of 2 >= WIDTH (for fast access) */
|
||||
# define HEIGHT 23
|
||||
# define UBOUND 1
|
||||
# define DBOUND (HEIGHT - 1)
|
||||
# define LBOUND 1
|
||||
# define RBOUND (WIDTH - 1)
|
||||
|
||||
# define SCREEN_HEIGHT 24
|
||||
# define SCREEN_WIDTH 80
|
||||
# define SCREEN_WIDTH2 128 /* Next power of 2 >= SCREEN_WIDTH */
|
||||
|
||||
# define STAT_LABEL_COL 60
|
||||
# define STAT_VALUE_COL 74
|
||||
# define STAT_NAME_COL 61
|
||||
# define STAT_SCAN_COL (STAT_NAME_COL + 5)
|
||||
# define STAT_AMMO_ROW 0
|
||||
# define STAT_GUN_ROW 1
|
||||
# define STAT_DAM_ROW 2
|
||||
# define STAT_KILL_ROW 3
|
||||
# define STAT_PLAY_ROW 5
|
||||
# ifdef MONITOR
|
||||
# define STAT_MON_ROW (STAT_PLAY_ROW + MAXPL + 1)
|
||||
# endif
|
||||
# define STAT_NAME_LEN 18
|
||||
|
||||
# define DOOR '#'
|
||||
# define WALL1 '-'
|
||||
# define WALL2 '|'
|
||||
# define WALL3 '+'
|
||||
# ifdef REFLECT
|
||||
# define WALL4 '/'
|
||||
# define WALL5 '\\'
|
||||
# endif
|
||||
# define KNIFE 'K'
|
||||
# define SHOT ':'
|
||||
# define GRENADE 'o'
|
||||
# define SATCHEL 'O'
|
||||
# define BOMB '@'
|
||||
# define MINE ';'
|
||||
# define GMINE 'g'
|
||||
# ifdef OOZE
|
||||
# define SLIME '$'
|
||||
# endif
|
||||
# ifdef VOLCANO
|
||||
# define LAVA '~'
|
||||
# endif
|
||||
# ifdef DRONE
|
||||
# define DSHOT '?'
|
||||
# endif
|
||||
# ifdef FLY
|
||||
# define FALL 'F'
|
||||
# endif
|
||||
# ifdef BOOTS
|
||||
# define NBOOTS 2
|
||||
# define BOOT 'b'
|
||||
# define BOOT_PAIR 'B'
|
||||
# endif
|
||||
# define SPACE ' '
|
||||
|
||||
# define ABOVE 'i'
|
||||
# define BELOW '!'
|
||||
# define RIGHT '}'
|
||||
# define LEFTS '{'
|
||||
# ifdef FLY
|
||||
# define FLYER '&'
|
||||
# define is_player(c) (c == LEFTS || c == RIGHT ||\
|
||||
c == ABOVE || c == BELOW || c == FLYER)
|
||||
# else
|
||||
# define is_player(c) (c == LEFTS || c == RIGHT ||\
|
||||
c == ABOVE || c == BELOW)
|
||||
# endif
|
||||
|
||||
# define NORTH 01
|
||||
# define SOUTH 02
|
||||
# define EAST 010
|
||||
# define WEST 020
|
||||
|
||||
# ifndef TRUE
|
||||
# define TRUE 1
|
||||
# define FALSE 0
|
||||
# endif
|
||||
# undef CTRL
|
||||
# define CTRL(x) ((x) & 037)
|
||||
|
||||
# define BULSPD 5 /* bullets movement speed */
|
||||
# define ISHOTS 15
|
||||
# define NSHOTS 5
|
||||
# define MAXNCSHOT 2
|
||||
# define MAXDAM 10
|
||||
# define MINDAM 5
|
||||
# define STABDAM 2
|
||||
|
||||
# define BULREQ 1
|
||||
# define GRENREQ 9
|
||||
# define SATREQ 25
|
||||
# define BOMB7REQ 49
|
||||
# define BOMB9REQ 81
|
||||
# define BOMB11REQ 121
|
||||
# define BOMB13REQ 169
|
||||
# define BOMB15REQ 225
|
||||
# define BOMB17REQ 289
|
||||
# define BOMB19REQ 361
|
||||
# define BOMB21REQ 441
|
||||
# define MAXBOMB 11
|
||||
# ifdef DRONE
|
||||
# define MINDSHOT 2 /* At least a satchel bomb */
|
||||
# endif
|
||||
extern int shot_req[];
|
||||
extern int shot_type[];
|
||||
# ifdef OOZE
|
||||
# define SLIME_FACTOR 3
|
||||
# define SLIMEREQ 5
|
||||
# define SSLIMEREQ 10
|
||||
# define SLIME2REQ 15
|
||||
# define SLIME3REQ 20
|
||||
# define MAXSLIME 4
|
||||
# define SLIMESPEED 5
|
||||
extern int slime_req[];
|
||||
# endif
|
||||
# ifdef VOLCANO
|
||||
# define LAVASPEED 1
|
||||
# endif
|
||||
|
||||
# define CLOAKLEN 20
|
||||
# define SCANLEN (Nplayer * 20)
|
||||
# define EXPLEN 4
|
||||
|
||||
# define Q_QUIT 0
|
||||
# define Q_CLOAK 1
|
||||
# define Q_FLY 2
|
||||
# define Q_SCAN 3
|
||||
# define Q_MESSAGE 4
|
||||
|
||||
# define C_PLAYER 0
|
||||
# define C_MONITOR 1
|
||||
# define C_MESSAGE 2
|
||||
# define C_SCORES 3
|
||||
|
||||
# ifdef MONITOR
|
||||
# define C_TESTMSG() (Query_driver ? C_MESSAGE :\
|
||||
(Show_scores ? C_SCORES :\
|
||||
(Am_monitor ? C_MONITOR :\
|
||||
C_PLAYER)))
|
||||
# else
|
||||
# define C_TESTMSG() (Show_scores ? C_SCORES :\
|
||||
(Query_driver ? C_MESSAGE :\
|
||||
C_PLAYER))
|
||||
# endif
|
||||
|
||||
# ifdef FLY
|
||||
# define _scan_char(pp) (((pp)->p_scan < 0) ? ' ' : '*')
|
||||
# define _cloak_char(pp) (((pp)->p_cloak < 0) ? _scan_char(pp) : '+')
|
||||
# define stat_char(pp) (((pp)->p_flying < 0) ? _cloak_char(pp) : FLYER)
|
||||
# else
|
||||
# define _scan_char(pp) (((pp)->p_scan < 0) ? ' ' : '*')
|
||||
# define stat_char(pp) (((pp)->p_cloak < 0) ? _scan_char(pp) : '+')
|
||||
# endif
|
||||
|
||||
typedef int FLAG;
|
||||
typedef struct bullet_def BULLET;
|
||||
typedef struct expl_def EXPL;
|
||||
typedef struct player_def PLAYER;
|
||||
typedef struct ident_def IDENT;
|
||||
typedef struct regen_def REGEN;
|
||||
# ifdef INTERNET
|
||||
typedef struct sockaddr_in SOCKET;
|
||||
# else
|
||||
typedef struct sockaddr_un SOCKET;
|
||||
# endif
|
||||
|
||||
struct ident_def {
|
||||
char i_name[NAMELEN];
|
||||
char i_team;
|
||||
long i_machine;
|
||||
long i_uid;
|
||||
float i_kills;
|
||||
int i_entries;
|
||||
float i_score;
|
||||
int i_absorbed;
|
||||
int i_faced;
|
||||
int i_shot;
|
||||
int i_robbed;
|
||||
int i_slime;
|
||||
int i_missed;
|
||||
int i_ducked;
|
||||
int i_gkills, i_bkills, i_deaths, i_stillb, i_saved;
|
||||
IDENT *i_next;
|
||||
};
|
||||
|
||||
struct player_def {
|
||||
IDENT *p_ident;
|
||||
char p_over;
|
||||
int p_face;
|
||||
int p_undershot;
|
||||
# ifdef FLY
|
||||
int p_flying;
|
||||
int p_flyx, p_flyy;
|
||||
# endif
|
||||
# ifdef BOOTS
|
||||
int p_nboots;
|
||||
# endif
|
||||
FILE *p_output;
|
||||
int p_fd;
|
||||
int p_mask;
|
||||
int p_damage;
|
||||
int p_damcap;
|
||||
int p_ammo;
|
||||
int p_ncshot;
|
||||
int p_scan;
|
||||
int p_cloak;
|
||||
int p_x, p_y;
|
||||
int p_ncount;
|
||||
int p_nexec;
|
||||
long p_nchar;
|
||||
char p_death[MSGLEN];
|
||||
char p_maze[HEIGHT][WIDTH2];
|
||||
int p_curx, p_cury;
|
||||
int p_lastx, p_lasty;
|
||||
char p_cbuf[BUFSIZ];
|
||||
};
|
||||
|
||||
struct bullet_def {
|
||||
int b_x, b_y;
|
||||
int b_face;
|
||||
int b_charge;
|
||||
char b_type;
|
||||
char b_size;
|
||||
char b_over;
|
||||
PLAYER *b_owner;
|
||||
IDENT *b_score;
|
||||
FLAG b_expl;
|
||||
BULLET *b_next;
|
||||
};
|
||||
|
||||
struct expl_def {
|
||||
int e_x, e_y;
|
||||
char e_char;
|
||||
EXPL *e_next;
|
||||
};
|
||||
|
||||
struct regen_def {
|
||||
int r_x, r_y;
|
||||
REGEN *r_next;
|
||||
};
|
||||
|
||||
/*
|
||||
* external variables
|
||||
*/
|
||||
|
||||
extern FLAG Last_player;
|
||||
|
||||
extern char Buf[BUFSIZ], Maze[HEIGHT][WIDTH2], Orig_maze[HEIGHT][WIDTH2];
|
||||
|
||||
extern char *Sock_name;
|
||||
extern const char *Driver;
|
||||
|
||||
extern int Nplayer, Num_fds, Socket, Status;
|
||||
extern fd_set Fds_mask, Have_inp;
|
||||
|
||||
# ifdef INTERNET
|
||||
extern u_short Test_port;
|
||||
# else
|
||||
extern char *Sock_name;
|
||||
# endif
|
||||
|
||||
# ifdef VOLCANO
|
||||
extern int volcano;
|
||||
# endif
|
||||
|
||||
extern int See_over[NASCII];
|
||||
|
||||
extern BULLET *Bullets;
|
||||
|
||||
extern EXPL *Expl[EXPLEN];
|
||||
extern EXPL *Last_expl;
|
||||
|
||||
extern IDENT *Scores;
|
||||
|
||||
extern PLAYER Player[MAXPL], *End_player;
|
||||
# ifdef BOOTS
|
||||
extern PLAYER Boot[NBOOTS];
|
||||
# endif
|
||||
|
||||
# ifdef MONITOR
|
||||
extern FLAG Am_monitor;
|
||||
extern PLAYER Monitor[MAXMON], *End_monitor;
|
||||
# endif
|
||||
|
||||
# ifdef INTERNET
|
||||
extern char *Send_message;
|
||||
# endif
|
||||
|
||||
extern char map_key[256];
|
||||
extern FLAG no_beep;
|
||||
|
||||
/*
|
||||
* function types
|
||||
*/
|
||||
|
||||
void add_shot __P((int, int, int, char, int, PLAYER *, int, char));
|
||||
int answer __P((void));
|
||||
void bad_con __P((void));
|
||||
void bad_ver __P((void));
|
||||
int broadcast_vec __P((int, struct sockaddr **));
|
||||
void ce __P((PLAYER *));
|
||||
void cgoto __P((PLAYER *, int, int));
|
||||
void check __P((PLAYER *, int, int));
|
||||
void checkdam __P((PLAYER *, PLAYER *, IDENT *, int, char));
|
||||
void clearwalls __P((void));
|
||||
void clear_eol __P((void));
|
||||
void clear_the_screen __P((void));
|
||||
void clrscr __P((PLAYER *));
|
||||
BULLET *create_shot __P((int, int, int, char, int, int, PLAYER *,
|
||||
IDENT *, int, char));
|
||||
void do_connect __P((const char *, char, long));
|
||||
void do_message __P((void));
|
||||
void drawmaze __P((PLAYER *));
|
||||
void drawplayer __P((PLAYER *, FLAG));
|
||||
void drawstatus __P((PLAYER *));
|
||||
void execute __P((PLAYER *));
|
||||
void faketalk __P((void));
|
||||
void find_driver __P((FLAG));
|
||||
void fixshots __P((int, int, char));
|
||||
IDENT *get_ident __P((u_long, u_long, const char *, char));
|
||||
void get_local_name __P((const char *));
|
||||
int get_remote_name __P((char *));
|
||||
BULLET *is_bullet __P((int, int));
|
||||
void look __P((PLAYER *));
|
||||
void makemaze __P((void));
|
||||
void message __P((PLAYER *, const char *));
|
||||
void mon_execute __P((PLAYER *));
|
||||
void moveshots __P((void));
|
||||
void open_ctl __P((void));
|
||||
int opposite __P((int, char));
|
||||
void otto __P((int, int, char));
|
||||
void outch __P((PLAYER *, int));
|
||||
void outstr __P((PLAYER *, const char *, int));
|
||||
int player_sym __P((const PLAYER *, int, int));
|
||||
PLAYER *play_at __P((int, int));
|
||||
void playit __P((void));
|
||||
void put_ch __P((char));
|
||||
# ifndef USE_CURSES
|
||||
void put_str __P((const char *));
|
||||
# endif
|
||||
int quit __P((int));
|
||||
int rand_dir __P((void));
|
||||
int rand_num __P((int));
|
||||
void redraw_screen __P((void));
|
||||
void rmnl __P((char *));
|
||||
void rollexpl __P((void));
|
||||
void see __P((PLAYER *, int));
|
||||
void sendcom __P((PLAYER *, int, ...));
|
||||
void showexpl __P((int, int, char));
|
||||
void showstat __P((PLAYER *));
|
||||
void start_driver __P((void));
|
||||
void stmonitor __P((PLAYER *));
|
||||
void stplayer __P((PLAYER *, int));
|
||||
char translate __P((char));
|
||||
SIGNAL_TYPE cleanup __P((int)) __attribute__((__noreturn__));
|
||||
SIGNAL_TYPE intr __P((int));
|
||||
SIGNAL_TYPE sigalrm __P((int));
|
||||
SIGNAL_TYPE sigemt __P((int));
|
||||
SIGNAL_TYPE sigterm __P((int));
|
||||
SIGNAL_TYPE tstp __P((int));
|
||||
100
hunt/huntd/huntd.6.in
Normal file
100
hunt/huntd/huntd.6.in
Normal file
@@ -0,0 +1,100 @@
|
||||
.\" $NetBSD: huntd.6,v 1.3 1998/01/09 08:03:42 perry Exp $
|
||||
.\"
|
||||
.\" Hunt
|
||||
.\" Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
.\" San Francisco, California
|
||||
.\"
|
||||
.\" Copyright (c) 1985 Regents of the University of California.
|
||||
.\" All rights reserved. The Berkeley software License Agreement
|
||||
.\" specifies the terms and conditions for redistribution.
|
||||
.\"
|
||||
.TH HUNTD 6 "21 August 1986"
|
||||
.UC 4
|
||||
.SH NAME
|
||||
huntd \- hunt daemon, back-end for hunt game
|
||||
.SH SYNOPSIS
|
||||
\fB@sbindir@/huntd\fP [ \fB\-s\fP ] [ \fB\-p\fP port ]
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
.I huntd
|
||||
controls the multi-player
|
||||
.IR hunt (6)
|
||||
game.
|
||||
When it starts up, it tries to notify all members of the
|
||||
.I hunt-players
|
||||
mailing list (see
|
||||
.IR sendmail (8))
|
||||
by faking a
|
||||
.IR talk (1)
|
||||
request from user ``Hunt Game''.
|
||||
.PP
|
||||
The
|
||||
.B \-s
|
||||
option is for running
|
||||
.I huntd
|
||||
forever (server mode).
|
||||
This is similar to running it under the control of
|
||||
.I inetd
|
||||
(see below),
|
||||
but it consumes a process table entry when no one is playing.
|
||||
.PP
|
||||
The
|
||||
.B \-p
|
||||
option changes the udp port number used to rendezvous with the player
|
||||
process and thus allows for private games of hunt.
|
||||
This option turns off the notification of players on the
|
||||
.I hunt-players
|
||||
mailing list.
|
||||
.SH INETD
|
||||
.PP
|
||||
To run
|
||||
.I huntd
|
||||
from
|
||||
.IR inetd ,
|
||||
you'll need to put the
|
||||
.I hunt
|
||||
service in
|
||||
.BR /etc/services :
|
||||
.IP
|
||||
hunt 26740/udp # multi-player/multi-host mazewars
|
||||
.LP
|
||||
and add a line in
|
||||
.BR /etc/inetd.conf :
|
||||
.IP
|
||||
hunt dgram udp wait nobody @sbindir@/huntd HUNT
|
||||
.LP
|
||||
except for Suns which use
|
||||
.BR /etc/servers :
|
||||
.IP
|
||||
hunt udp @sbindir@/huntd
|
||||
.LP
|
||||
Do not use any of the command line options \(em if you want
|
||||
.I inetd
|
||||
to start up
|
||||
.I huntd
|
||||
on a private port, change the port listed in
|
||||
.BR /etc/services .
|
||||
.SH "NETWORK RENDEZVOUS"
|
||||
When
|
||||
.IR hunt (6)
|
||||
starts up, it broadcasts on the local area net
|
||||
(using the broadcast address for each interface) to find a
|
||||
.I hunt
|
||||
game in progress.
|
||||
If a
|
||||
.I huntd
|
||||
hears the request, it sends back the port number for the
|
||||
.I hunt
|
||||
process to connect to.
|
||||
Otherwise, the
|
||||
.I hunt
|
||||
process starts up a
|
||||
.I huntd
|
||||
on the local machine and trys to rendezvous with it.
|
||||
.SH "SEE ALSO"
|
||||
hunt(6), talk(1), sendmail(8)
|
||||
.SH AUTHORS
|
||||
Conrad Huang, Ken Arnold, and Greg Couch;
|
||||
.br
|
||||
University of California, San Francisco, Computer Graphics Lab
|
||||
.\"SH BUGS
|
||||
208
hunt/huntd/makemaze.c
Normal file
208
hunt/huntd/makemaze.c
Normal file
@@ -0,0 +1,208 @@
|
||||
/* $NetBSD: makemaze.c,v 1.2 1997/10/10 16:33:43 lukem Exp $ */
|
||||
/*
|
||||
* Hunt
|
||||
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
* San Francisco, California
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: makemaze.c,v 1.2 1997/10/10 16:33:43 lukem Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
# include "hunt.h"
|
||||
|
||||
# define ISCLEAR(y,x) (Maze[y][x] == SPACE)
|
||||
# define ODD(n) ((n) & 01)
|
||||
|
||||
static int candig __P((int, int));
|
||||
static void dig __P((int, int));
|
||||
static void dig_maze __P((int, int));
|
||||
static void remap __P((void));
|
||||
|
||||
void
|
||||
makemaze()
|
||||
{
|
||||
char *sp;
|
||||
int y, x;
|
||||
|
||||
/*
|
||||
* fill maze with walls
|
||||
*/
|
||||
sp = &Maze[0][0];
|
||||
while (sp < &Maze[HEIGHT - 1][WIDTH])
|
||||
*sp++ = DOOR;
|
||||
|
||||
x = rand_num(WIDTH / 2) * 2 + 1;
|
||||
y = rand_num(HEIGHT / 2) * 2 + 1;
|
||||
dig_maze(x, y);
|
||||
remap();
|
||||
}
|
||||
|
||||
# define NPERM 24
|
||||
# define NDIR 4
|
||||
|
||||
int dirs[NPERM][NDIR] = {
|
||||
{0,1,2,3}, {3,0,1,2}, {0,2,3,1}, {0,3,2,1},
|
||||
{1,0,2,3}, {2,3,0,1}, {0,2,1,3}, {2,3,1,0},
|
||||
{1,0,3,2}, {1,2,0,3}, {3,1,2,0}, {2,0,3,1},
|
||||
{1,3,0,2}, {0,3,1,2}, {1,3,2,0}, {2,0,1,3},
|
||||
{0,1,3,2}, {3,1,0,2}, {2,1,0,3}, {1,2,3,0},
|
||||
{2,1,3,0}, {3,0,2,1}, {3,2,0,1}, {3,2,1,0}
|
||||
};
|
||||
|
||||
int incr[NDIR][2] = {
|
||||
{0, 1}, {1, 0}, {0, -1}, {-1, 0}
|
||||
};
|
||||
|
||||
static void
|
||||
dig(y, x)
|
||||
int y, x;
|
||||
{
|
||||
int *dp;
|
||||
int *ip;
|
||||
int ny, nx;
|
||||
int *endp;
|
||||
|
||||
Maze[y][x] = SPACE; /* Clear this spot */
|
||||
dp = dirs[rand_num(NPERM)];
|
||||
endp = &dp[NDIR];
|
||||
while (dp < endp) {
|
||||
ip = &incr[*dp++][0];
|
||||
ny = y + *ip++;
|
||||
nx = x + *ip;
|
||||
if (candig(ny, nx))
|
||||
dig(ny, nx);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* candig:
|
||||
* Is it legal to clear this spot?
|
||||
*/
|
||||
static int
|
||||
candig(y, x)
|
||||
int y, x;
|
||||
{
|
||||
int i;
|
||||
|
||||
if (ODD(x) && ODD(y))
|
||||
return FALSE; /* can't touch ODD spots */
|
||||
|
||||
if (y < UBOUND || y >= DBOUND)
|
||||
return FALSE; /* Beyond vertical bounds, NO */
|
||||
if (x < LBOUND || x >= RBOUND)
|
||||
return FALSE; /* Beyond horizontal bounds, NO */
|
||||
|
||||
if (ISCLEAR(y, x))
|
||||
return FALSE; /* Already clear, NO */
|
||||
|
||||
i = ISCLEAR(y, x + 1);
|
||||
i += ISCLEAR(y, x - 1);
|
||||
if (i > 1)
|
||||
return FALSE; /* Introduces cycle, NO */
|
||||
i += ISCLEAR(y + 1, x);
|
||||
if (i > 1)
|
||||
return FALSE; /* Introduces cycle, NO */
|
||||
i += ISCLEAR(y - 1, x);
|
||||
if (i > 1)
|
||||
return FALSE; /* Introduces cycle, NO */
|
||||
|
||||
return TRUE; /* OK */
|
||||
}
|
||||
|
||||
void
|
||||
dig_maze(x, y)
|
||||
int x, y;
|
||||
{
|
||||
int tx, ty;
|
||||
int i, j;
|
||||
int order[4];
|
||||
#define MNORTH 0x1
|
||||
#define MSOUTH 0x2
|
||||
#define MEAST 0x4
|
||||
#define MWEST 0x8
|
||||
|
||||
tx = ty = 0;
|
||||
Maze[y][x] = SPACE;
|
||||
order[0] = MNORTH;
|
||||
for (i = 1; i < 4; i++) {
|
||||
j = rand_num(i + 1);
|
||||
order[i] = order[j];
|
||||
order[j] = 0x1 << i;
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
switch (order[i]) {
|
||||
case MNORTH:
|
||||
tx = x;
|
||||
ty = y - 2;
|
||||
break;
|
||||
case MSOUTH:
|
||||
tx = x;
|
||||
ty = y + 2;
|
||||
break;
|
||||
case MEAST:
|
||||
tx = x + 2;
|
||||
ty = y;
|
||||
break;
|
||||
case MWEST:
|
||||
tx = x - 2;
|
||||
ty = y;
|
||||
break;
|
||||
}
|
||||
if (tx < 0 || ty < 0 || tx >= WIDTH || ty >= HEIGHT)
|
||||
continue;
|
||||
if (Maze[ty][tx] == SPACE)
|
||||
continue;
|
||||
Maze[(y + ty) / 2][(x + tx) / 2] = SPACE;
|
||||
dig_maze(tx, ty);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
remap()
|
||||
{
|
||||
int y, x;
|
||||
char *sp;
|
||||
int stat;
|
||||
|
||||
for (y = 0; y < HEIGHT; y++)
|
||||
for (x = 0; x < WIDTH; x++) {
|
||||
sp = &Maze[y][x];
|
||||
if (*sp == SPACE)
|
||||
continue;
|
||||
stat = 0;
|
||||
if (y - 1 >= 0 && Maze[y - 1][x] != SPACE)
|
||||
stat |= NORTH;
|
||||
if (y + 1 < HEIGHT && Maze[y + 1][x] != SPACE)
|
||||
stat |= SOUTH;
|
||||
if (x + 1 < WIDTH && Maze[y][x + 1] != SPACE)
|
||||
stat |= EAST;
|
||||
if (x - 1 >= 0 && Maze[y][x - 1] != SPACE)
|
||||
stat |= WEST;
|
||||
switch (stat) {
|
||||
case WEST | EAST:
|
||||
case EAST:
|
||||
case WEST:
|
||||
*sp = WALL1;
|
||||
break;
|
||||
case NORTH | SOUTH:
|
||||
case NORTH:
|
||||
case SOUTH:
|
||||
*sp = WALL2;
|
||||
break;
|
||||
case 0:
|
||||
# ifdef RANDOM
|
||||
*sp = DOOR;
|
||||
# endif
|
||||
# ifdef REFLECT
|
||||
*sp = rand_num(2) ? WALL4 : WALL5;
|
||||
# endif
|
||||
break;
|
||||
default:
|
||||
*sp = WALL3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
memcpy(Orig_maze, Maze, sizeof Maze);
|
||||
}
|
||||
41
hunt/huntd/pathname.c
Normal file
41
hunt/huntd/pathname.c
Normal file
@@ -0,0 +1,41 @@
|
||||
/* $NetBSD: pathname.c,v 1.2 1997/10/10 16:33:49 lukem Exp $ */
|
||||
/*
|
||||
* Hunt
|
||||
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
* San Francisco, California
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: pathname.c,v 1.2 1997/10/10 16:33:49 lukem Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
* There is no particular significance to the numbers assigned
|
||||
* to Test_port. They're just random numbers greater than the
|
||||
* range reserved for privileged sockets.
|
||||
*/
|
||||
|
||||
# include <sys/types.h>
|
||||
|
||||
# ifdef DEBUG
|
||||
|
||||
char *Driver = "/home/socr/a/conrad/games/src/hunt/huntd.dbg";
|
||||
# ifdef INTERNET
|
||||
u_short Test_port = ('h' << 8) | 't';
|
||||
# else
|
||||
char *Sock_name = "/tmp/hunt";
|
||||
char *Stat_name = "/tmp/hunt.stats";
|
||||
# endif
|
||||
|
||||
# else
|
||||
|
||||
const char *Driver = HUNTD;
|
||||
# ifdef INTERNET
|
||||
u_short Test_port = ('h' << 8) | 't';
|
||||
# else
|
||||
char *Sock_name = "/tmp/hunt";
|
||||
char *Stat_name = "/tmp/hunt.stats";
|
||||
# endif
|
||||
|
||||
# endif
|
||||
1144
hunt/huntd/shots.c
Normal file
1144
hunt/huntd/shots.c
Normal file
File diff suppressed because it is too large
Load Diff
82
hunt/huntd/talk_ctl.h
Normal file
82
hunt/huntd/talk_ctl.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/* $NetBSD: talk_ctl.h,v 1.4 1998/01/09 08:03:42 perry Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983 Regents of the University of California.
|
||||
* All rights reserved. The Berkeley software License Agreement
|
||||
* specifies the terms and conditions for redistribution.
|
||||
*
|
||||
* @(#)talk_ctl.h 5.2 (Berkeley) 3/13/86
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#ifdef TALK_43
|
||||
#include <protocols/talkd.h>
|
||||
#else
|
||||
|
||||
#define NAME_SIZE 9
|
||||
#define TTY_SIZE 16
|
||||
#ifndef MAXHOSTNAMELEN
|
||||
#define MAXHOSTNAMELEN 256
|
||||
#endif
|
||||
|
||||
#define MAX_LIFE 60 /* max time daemon saves invitations */
|
||||
/* RING_WAIT should be 10's of seconds less than MAX_LIFE */
|
||||
#define RING_WAIT 30 /* time to wait before refreshing invitation */
|
||||
|
||||
/* type values */
|
||||
#define LEAVE_INVITE 0
|
||||
#define LOOK_UP 1
|
||||
#define DELETE 2
|
||||
#define ANNOUNCE 3
|
||||
|
||||
/* answer values */
|
||||
#define SUCCESS 0
|
||||
#define NOT_HERE 1
|
||||
#define FAILED 2
|
||||
#define MACHINE_UNKNOWN 3
|
||||
#define PERMISSION_DENIED 4
|
||||
#define UNKNOWN_REQUEST 5
|
||||
|
||||
typedef struct ctl_response {
|
||||
char type;
|
||||
char answer;
|
||||
int id_num;
|
||||
struct sockaddr_in addr;
|
||||
} CTL_RESPONSE;
|
||||
|
||||
typedef struct ctl_msg {
|
||||
char type;
|
||||
char l_name[NAME_SIZE];
|
||||
char r_name[NAME_SIZE];
|
||||
int id_num;
|
||||
int pid;
|
||||
char r_tty[TTY_SIZE];
|
||||
struct sockaddr_in addr;
|
||||
struct sockaddr_in ctl_addr;
|
||||
} CTL_MSG;
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#ifdef LOG
|
||||
#include <syslog.h>
|
||||
#endif
|
||||
|
||||
extern struct sockaddr_in daemon_addr;
|
||||
extern struct sockaddr_in ctl_addr;
|
||||
extern struct sockaddr_in my_addr;
|
||||
extern struct in_addr my_machine_addr;
|
||||
extern struct in_addr his_machine_addr;
|
||||
extern u_short daemon_port;
|
||||
extern int ctl_sockt;
|
||||
extern CTL_MSG msg;
|
||||
|
||||
#ifdef LOG
|
||||
#define p_error(str) syslog(LOG_WARNING, "faketalk %s: %m", str)
|
||||
#else
|
||||
#define p_error(str) warn(str)
|
||||
#endif
|
||||
|
||||
void ctl_transact __P((struct in_addr, CTL_MSG, int, CTL_RESPONSE *));
|
||||
145
hunt/huntd/terminal.c
Normal file
145
hunt/huntd/terminal.c
Normal file
@@ -0,0 +1,145 @@
|
||||
/* $NetBSD: terminal.c,v 1.2 1997/10/10 16:34:05 lukem Exp $ */
|
||||
/*
|
||||
* Hunt
|
||||
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
* San Francisco, California
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: terminal.c,v 1.2 1997/10/10 16:34:05 lukem Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#if __STDC__
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
# include "hunt.h"
|
||||
# define TERM_WIDTH 80 /* Assume terminals are 80-char wide */
|
||||
|
||||
/*
|
||||
* cgoto:
|
||||
* Move the cursor to the given position on the given player's
|
||||
* terminal.
|
||||
*/
|
||||
void
|
||||
cgoto(pp, y, x)
|
||||
PLAYER *pp;
|
||||
int y, x;
|
||||
{
|
||||
if (x == pp->p_curx && y == pp->p_cury)
|
||||
return;
|
||||
sendcom(pp, MOVE, y, x);
|
||||
pp->p_cury = y;
|
||||
pp->p_curx = x;
|
||||
}
|
||||
|
||||
/*
|
||||
* outch:
|
||||
* Put out a single character.
|
||||
*/
|
||||
void
|
||||
outch(pp, ch)
|
||||
PLAYER *pp;
|
||||
char ch;
|
||||
{
|
||||
if (++pp->p_curx >= TERM_WIDTH) {
|
||||
pp->p_curx = 0;
|
||||
pp->p_cury++;
|
||||
}
|
||||
(void) putc(ch, pp->p_output);
|
||||
}
|
||||
|
||||
/*
|
||||
* outstr:
|
||||
* Put out a string of the given length.
|
||||
*/
|
||||
void
|
||||
outstr(pp, str, len)
|
||||
PLAYER *pp;
|
||||
const char *str;
|
||||
int len;
|
||||
{
|
||||
pp->p_curx += len;
|
||||
pp->p_cury += (pp->p_curx / TERM_WIDTH);
|
||||
pp->p_curx %= TERM_WIDTH;
|
||||
while (len--)
|
||||
(void) putc(*str++, pp->p_output);
|
||||
}
|
||||
|
||||
/*
|
||||
* clrscr:
|
||||
* Clear the screen, and reset the current position on the screen.
|
||||
*/
|
||||
void
|
||||
clrscr(pp)
|
||||
PLAYER *pp;
|
||||
{
|
||||
sendcom(pp, CLEAR);
|
||||
pp->p_cury = 0;
|
||||
pp->p_curx = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ce:
|
||||
* Clear to the end of the line
|
||||
*/
|
||||
void
|
||||
ce(pp)
|
||||
PLAYER *pp;
|
||||
{
|
||||
sendcom(pp, CLRTOEOL);
|
||||
}
|
||||
|
||||
#if 0 /* XXX lukem*/
|
||||
/*
|
||||
* ref;
|
||||
* Refresh the screen
|
||||
*/
|
||||
void
|
||||
ref(pp)
|
||||
PLAYER *pp;
|
||||
{
|
||||
sendcom(pp, REFRESH);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* sendcom:
|
||||
* Send a command to the given user
|
||||
*/
|
||||
void
|
||||
#if __STDC__
|
||||
sendcom(PLAYER *pp, int command, ...)
|
||||
#else
|
||||
sendcom(pp, command, va_alist)
|
||||
PLAYER *pp;
|
||||
int command;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list ap;
|
||||
int arg1, arg2;
|
||||
#if __STDC__
|
||||
va_start(ap, command);
|
||||
#else
|
||||
va_start(ap);
|
||||
#endif
|
||||
(void) putc(command, pp->p_output);
|
||||
switch (command & 0377) {
|
||||
case MOVE:
|
||||
arg1 = va_arg(ap, int);
|
||||
arg2 = va_arg(ap, int);
|
||||
(void) putc(arg1, pp->p_output);
|
||||
(void) putc(arg2, pp->p_output);
|
||||
break;
|
||||
case ADDCH:
|
||||
case READY:
|
||||
arg1 = va_arg(ap, int);
|
||||
(void) putc(arg1, pp->p_output);
|
||||
break;
|
||||
}
|
||||
|
||||
va_end(ap); /* No return needed for void functions. */
|
||||
}
|
||||
Reference in New Issue
Block a user