summaryrefslogtreecommitdiff
path: root/games/hunt/huntd
diff options
context:
space:
mode:
authorDavid Leonard <d@cvs.openbsd.org>1999-01-29 07:30:38 +0000
committerDavid Leonard <d@cvs.openbsd.org>1999-01-29 07:30:38 +0000
commit9fd17607ee9aca36de862c448a6c22177b84d215 (patch)
tree33e448e38134371bc7ad1ae1faeeadb9936e5ab9 /games/hunt/huntd
parent26b686ad51fb59b91e320e0bb8a394b6670ea667 (diff)
major changes: security, curses, config
Diffstat (limited to 'games/hunt/huntd')
-rw-r--r--games/hunt/huntd/Makefile8
-rw-r--r--games/hunt/huntd/answer.c338
-rw-r--r--games/hunt/huntd/bsd.h18
-rw-r--r--games/hunt/huntd/conf.c232
-rw-r--r--games/hunt/huntd/conf.h51
-rw-r--r--games/hunt/huntd/ctl.c56
-rw-r--r--games/hunt/huntd/ctl_transact.c109
-rw-r--r--games/hunt/huntd/draw.c285
-rw-r--r--games/hunt/huntd/driver.c882
-rw-r--r--games/hunt/huntd/execute.c305
-rw-r--r--games/hunt/huntd/expl.c80
-rw-r--r--games/hunt/huntd/extern.c11
-rw-r--r--games/hunt/huntd/faketalk.c227
-rw-r--r--games/hunt/huntd/get_names.c129
-rw-r--r--games/hunt/huntd/hunt.h416
-rw-r--r--games/hunt/huntd/huntd.6138
-rw-r--r--games/hunt/huntd/makemaze.c29
-rw-r--r--games/hunt/huntd/pathname.c37
-rw-r--r--games/hunt/huntd/server.h239
-rw-r--r--games/hunt/huntd/shots.c439
-rw-r--r--games/hunt/huntd/talk_ctl.h83
-rw-r--r--games/hunt/huntd/terminal.c144
22 files changed, 2022 insertions, 2234 deletions
diff --git a/games/hunt/huntd/Makefile b/games/hunt/huntd/Makefile
index 708b0bc5174..344bf2fff02 100644
--- a/games/hunt/huntd/Makefile
+++ b/games/hunt/huntd/Makefile
@@ -1,9 +1,11 @@
# $NetBSD: Makefile,v 1.1 1997/10/04 09:11:21 mrg Exp $
-# $OpenBSD: Makefile,v 1.2 1999/01/21 05:47:39 d Exp $
+# $OpenBSD: Makefile,v 1.3 1999/01/29 07:30:34 d 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
+SRCS= answer.c conf.c draw.c driver.c execute.c expl.c \
+ extern.c makemaze.c shots.c terminal.c
MAN= huntd.6
+LDADD+= -lwrap
+DPADD+= ${LIBWRAP}
.include <bsd.prog.mk>
diff --git a/games/hunt/huntd/answer.c b/games/hunt/huntd/answer.c
index eed0c82de46..2adf3ba2bfd 100644
--- a/games/hunt/huntd/answer.c
+++ b/games/hunt/huntd/answer.c
@@ -1,74 +1,84 @@
+/* $OpenBSD: answer.c,v 1.3 1999/01/29 07:30:34 d Exp $ */
/* $NetBSD: answer.c,v 1.3 1997/10/10 16:32:50 lukem Exp $ */
-/* $OpenBSD: answer.c,v 1.2 1999/01/21 05:47:39 d Exp $ */
/*
* Hunt
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
* San Francisco, California
*/
-# include <ctype.h>
-# include <errno.h>
-# include <fcntl.h>
-# include <stdlib.h>
-# include <unistd.h>
-# include "hunt.h"
-
-# define SCOREDECAY 15
-
-static char Ttyname[NAMELEN];
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <tcpd.h>
+#include <syslog.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include "hunt.h"
+#include "server.h"
+#include "conf.h"
+
+/* Exported symbols for hosts_access(): */
+int allow_severity = LOG_INFO;
+int deny_severity = LOG_WARNING;
+
+static void stplayer __P((PLAYER *, int));
+static void stmonitor __P((PLAYER *));
+static IDENT * get_ident __P((u_long, u_long, char *, char,
+ struct request_info *));
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;
+ u_int32_t mode;
+ char name[NAMELEN];
+ u_int8_t team;
+ u_int32_t enter_status;
+ int socklen;
+ u_long machine;
+ u_int32_t uid;
+ struct sockaddr_in sockstruct;
char *cp1, *cp2;
int flags;
- long version;
+ u_int32_t version;
+ struct request_info ri;
+ char Ttyname[NAMELEN]; /* never used */
-# 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
+ /* Check for access permissions: */
+ request_init(&ri, RQ_DAEMON, "huntd", RQ_FILE, newsock, 0);
+ if (hosts_access(&ri) == 0) {
+ close(newsock);
+ return (FALSE);
+ }
+
+ machine = ntohl((u_int32_t)((struct sockaddr_in *) &sockstruct)->sin_addr.s_addr);
version = htonl((u_int32_t) HUNT_VERSION);
- (void) write(newsock, (char *) &version, LONGLEN);
- (void) read(newsock, (char *) &uid, LONGLEN);
+ (void) write(newsock, &version, sizeof version);
+ (void) read(newsock, &uid, sizeof uid);
uid = ntohl((unsigned long) uid);
- (void) read(newsock, name, NAMELEN);
- (void) read(newsock, &team, 1);
- (void) read(newsock, (char *) &enter_status, LONGLEN);
+ (void) read(newsock, name, sizeof name);
+ (void) read(newsock, &team, sizeof team);
+ (void) read(newsock, &enter_status, sizeof enter_status);
enter_status = ntohl((unsigned long) enter_status);
- (void) read(newsock, Ttyname, NAMELEN);
- (void) read(newsock, (char *) &mode, sizeof mode);
+ (void) read(newsock, Ttyname, sizeof Ttyname);
+ (void) read(newsock, &mode, sizeof mode);
mode = ntohl(mode);
/*
@@ -89,62 +99,79 @@ answer()
*cp2++ = *cp1;
*cp2 = '\0';
-# ifdef INTERNET
+ /* The connection is solely for a message: */
if (mode == C_MESSAGE) {
+ fd_set r;
+ struct timeval tmo = { 0, 1000000 / 2 };
char buf[BUFSIZ + 1];
+ int buflen;
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);
+ /* wait for 0.5 second for the message packet */
+ FD_ZERO(&r);
+ FD_SET(newsock, &r);
+ n = select(newsock+1, &r, 0, 0, &tmo);
+ if (n < 0)
+ syslog(LOG_ERR, "select: %m");
+ else if (n > 0) {
+ buflen = 0;
+ while (buflen < (BUFSIZ - 1) && (n = read(newsock,
+ buf + buflen, (BUFSIZ - 1) - buflen)) > 0)
+ buflen += n;
+ buf[buflen] = '\0';
+
+ if (team == ' ')
+ outyx(ALL_PLAYERS, HEIGHT, 0, "%s: %s",
+ name, buf);
+ else
+ outyx(ALL_PLAYERS, HEIGHT, 0, "%s[%c]: %s",
+ name, team, buf);
+ ce(ALL_PLAYERS);
+ sendcom(ALL_PLAYERS, REFRESH);
+ sendcom(ALL_PLAYERS, READY, 0);
+ flush(ALL_PLAYERS);
}
+
(void) close(newsock);
return FALSE;
}
- else
-# endif
-# ifdef MONITOR
- if (mode == C_MONITOR)
- if (End_monitor < &Monitor[MAXMON])
+
+ /* The player is a monitor: */
+ else if (mode == C_MONITOR) {
+ if (conf_monitor && End_monitor < &Monitor[MAXMON]) {
pp = End_monitor++;
- else {
- socklen = 0;
- (void) write(newsock, (char *) &socklen,
- sizeof socklen);
+ if (team == ' ')
+ team = '*';
+ } else {
+ u_int32_t response;
+
+ /* Too many monitors */
+ response = htonl(0);
+ (void) write(newsock, (char *) &response,
+ sizeof response);
(void) close(newsock);
+ syslog(LOG_NOTICE, "too many monitors");
return FALSE;
}
- else
-# endif
+
+ /* The player is a normal hunter: */
+ } else {
if (End_player < &Player[MAXPL])
pp = End_player++;
else {
- socklen = 0;
- (void) write(newsock, (char *) &socklen,
- sizeof socklen);
+ u_int32_t response;
+
+ /* Too many players */
+ response = htonl(0);
+ (void) write(newsock, (char *) &response,
+ sizeof response);
(void) close(newsock);
+ syslog(LOG_NOTICE, "too many players");
return FALSE;
}
+ }
-#ifdef MONITOR
- if (mode == C_MONITOR && team == ' ')
- team = '*';
-#endif
- pp->p_ident = get_ident(machine, uid, name, team);
+ pp->p_ident = get_ident(machine, uid, name, team, &ri);
pp->p_output = fdopen(newsock, "w");
pp->p_death[0] = '\0';
pp->p_fd = newsock;
@@ -155,52 +182,44 @@ answer()
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
+/* Start a monitor: */
+static void
stmonitor(pp)
PLAYER *pp;
{
- int line;
- PLAYER *npp;
-
- memcpy(pp->p_maze, Maze, sizeof Maze);
+ /* Monitors get to see the entire maze: */
+ memcpy(pp->p_maze, Maze, sizeof pp->p_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);
- }
+ /* Put the monitor's name near the bottom right on all screens: */
+ outyx(ALL_PLAYERS,
+ STAT_MON_ROW + 1 + (pp - Monitor), STAT_NAME_COL,
+ "%5.5s%c%-10.10s %c", " ",
+ stat_char(pp), pp->p_ident->i_name, pp->p_ident->i_team);
+ /* Ready the monitor: */
sendcom(pp, REFRESH);
sendcom(pp, READY, 0);
- (void) fflush(pp->p_output);
+ flush(pp);
}
-# endif
-void
+/* Start a player: */
+static void
stplayer(newpp, enter_status)
PLAYER *newpp;
int enter_status;
{
int x, y;
PLAYER *pp;
+ int len;
Nplayer++;
@@ -219,6 +238,7 @@ stplayer(newpp, enter_status)
for (x = 0; x < WIDTH; x++)
newpp->p_maze[y][x] = Maze[y][x];
+ /* Drop the new player somewhere in the maze: */
do {
x = rand_num(WIDTH - 1) + 1;
y = rand_num(HEIGHT - 1) + 1;
@@ -228,93 +248,90 @@ stplayer(newpp, enter_status)
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;
+ /* Send them flying if needed */
+ if (enter_status == Q_FLY && conf_fly) {
+ newpp->p_flying = rand_num(conf_flytime);
+ newpp->p_flyx = 2 * rand_num(conf_flystep + 1) - conf_flystep;
+ newpp->p_flyy = 2 * rand_num(conf_flystep + 1) - conf_flystep;
newpp->p_face = FLYER;
- }
- else
-# endif
- {
+ } else {
newpp->p_flying = -1;
newpp->p_face = rand_dir();
}
+
+ /* Initialize the new player's attributes: */
newpp->p_damage = 0;
- newpp->p_damcap = MAXDAM;
+ newpp->p_damcap = conf_maxdam;
newpp->p_nchar = 0;
newpp->p_ncount = 0;
newpp->p_nexec = 0;
- newpp->p_ammo = ISHOTS;
-# ifdef BOOTS
+ newpp->p_ammo = conf_ishots;
newpp->p_nboots = 0;
-# endif
- if (enter_status == Q_SCAN) {
- newpp->p_scan = SCANLEN;
+
+ /* Decide on what cloak/scan status to enter with */
+ if (enter_status == Q_SCAN && conf_scan) {
+ newpp->p_scan = conf_scanlen * Nplayer;
newpp->p_cloak = 0;
- }
- else {
+ } else if (conf_cloak) {
newpp->p_scan = 0;
- newpp->p_cloak = CLOAKLEN;
+ newpp->p_cloak = conf_cloaklen;
+ } else {
+ newpp->p_scan = 0;
+ newpp->p_cloak = 0;
}
newpp->p_ncshot = 0;
+ /*
+ * For each new player, place a large mine and
+ * a small mine somewhere in the maze:
+ */
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);
+ /* Create a score line for the new player: */
+ (void) snprintf(Buf, sizeof 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);
+ len = strlen(Buf);
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);
+ /* Give everyone a few more shots: */
+ pp->p_ammo += conf_nshots;
+ newpp->p_ammo += conf_nshots;
+ outyx(pp, y, STAT_NAME_COL, Buf, len);
+ ammo_update(pp);
}
}
-# ifdef MONITOR
- for (pp = Monitor; pp < End_monitor; pp++) {
- cgoto(pp, y, STAT_NAME_COL);
- outstr(pp, Buf, STAT_NAME_LEN);
- }
-# endif
+ for (pp = Monitor; pp < End_monitor; pp++)
+ outyx(pp, y, STAT_NAME_COL, Buf, len);
+ /* Show the new player what they can see and where they are: */
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 */
+
+ /* Make sure that the position they enter in will be erased: */
+ if (enter_status == Q_FLY && conf_fly)
showexpl(newpp->p_y, newpp->p_x, FLYER);
-# endif
+
+ /* Ready the new player: */
sendcom(newpp, REFRESH);
sendcom(newpp, READY, 0);
- (void) fflush(newpp->p_output);
+ flush(newpp);
}
/*
@@ -342,12 +359,13 @@ rand_dir()
* get_ident:
* Get the score structure of a player
*/
-IDENT *
-get_ident(machine, uid, name, team)
+static IDENT *
+get_ident(machine, uid, name, team, ri)
u_long machine;
u_long uid;
char *name;
char team;
+ struct request_info *ri;
{
IDENT *ip;
static IDENT punt;
@@ -355,28 +373,38 @@ get_ident(machine, uid, name, team)
for (ip = Scores; ip != NULL; ip = ip->i_next)
if (ip->i_machine == machine
&& ip->i_uid == uid
- && ip->i_team == team
+ /* && ip->i_team == team */
&& strncmp(ip->i_name, name, NAMELEN) == 0)
break;
if (ip != NULL) {
- if (ip->i_entries < SCOREDECAY)
+ if (ip->i_team != team) {
+ syslog(LOG_INFO, "player %s %s team %c",
+ name,
+ team == ' ' ? "left" : ip->i_team == ' ' ?
+ "joined" : "changed to",
+ team == ' ' ? ip->i_team : team);
+ ip->i_team = team;
+ }
+ if (ip->i_entries < conf_scoredecay)
ip->i_entries++;
else
- ip->i_kills = (ip->i_kills * (SCOREDECAY - 1))
- / SCOREDECAY;
+ ip->i_kills = (ip->i_kills * (conf_scoredecay - 1))
+ / conf_scoredecay;
ip->i_score = ip->i_kills / (double) ip->i_entries;
}
else {
+ /* Alloc new entry -- it is released in clear_scores() */
ip = (IDENT *) malloc(sizeof (IDENT));
if (ip == NULL) {
+ syslog(LOG_ERR, "malloc: %m");
/* 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);
+ strlcpy(ip->i_name, name, sizeof ip->i_name);
ip->i_kills = 0;
ip->i_entries = 1;
ip->i_score = 0;
@@ -391,6 +419,12 @@ get_ident(machine, uid, name, team)
ip->i_stillb = ip->i_saved = 0;
ip->i_next = Scores;
Scores = ip;
+
+ syslog(LOG_INFO, "new player: %s%s%c%s",
+ name,
+ team == ' ' ? "" : " (team ",
+ team,
+ team == ' ' ? "" : ")");
}
return ip;
diff --git a/games/hunt/huntd/bsd.h b/games/hunt/huntd/bsd.h
deleted file mode 100644
index f27a6ddfaa4..00000000000
--- a/games/hunt/huntd/bsd.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* $NetBSD: bsd.h,v 1.2 1998/01/09 08:03:40 perry Exp $ */
-/* $OpenBSD: bsd.h,v 1.2 1999/01/21 05:47:39 d 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
-# define TALK_43
-# endif
-# if defined(BSD_RELEASE) && BSD_RELEASE == 42
-# define SYSLOG_42
-# define TALK_42
-# endif
diff --git a/games/hunt/huntd/conf.c b/games/hunt/huntd/conf.c
new file mode 100644
index 00000000000..1d20d3436a1
--- /dev/null
+++ b/games/hunt/huntd/conf.c
@@ -0,0 +1,232 @@
+/* $OpenBSD: conf.c,v 1.1 1999/01/29 07:30:34 d Exp $ */
+/* David Leonard <d@openbsd.org>, 1999. Public domain. */
+
+#include <stdio.h>
+#include <string.h>
+#include <dirent.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "conf.h"
+
+/* Configuration option variables for the server: */
+
+int conf_random = 1; /* enable dispersion doors */
+int conf_reflect = 1; /* enable generation of reflection walls */
+int conf_monitor = 1; /* enable monitors */
+int conf_ooze = 1; /* enable slime shots */
+int conf_fly = 1; /* enable flight */
+int conf_volcano = 1; /* enable volcanoes */
+int conf_drone = 1; /* enable drone */
+int conf_boots = 1; /* enable boots */
+int conf_scan = 1; /* enable scanning */
+int conf_cloak = 1; /* enable cloaking */
+int conf_logerr = 1; /* errors to stderr as well as syslog(8) */
+
+int conf_scoredecay = 15; /* nr deaths before nr kills begins to decay */
+int conf_maxremove = 40; /* Maximum number of holes in the maze wall */
+int conf_linger = 90; /* Seconds to keep game open with no players */
+
+int conf_flytime = 20; /* max time flying */
+int conf_flystep = 5; /* max displacement each flying time unit */
+int conf_volcano_max = 50; /* max size of volcano */
+int conf_ptrip_face = 2; /* chace of tripping a grenade on pickup, */
+int conf_ptrip_back = 95; /* - when backing onto it */
+int conf_ptrip_side = 50; /* - when walking sideways into it */
+int conf_prandom = 1; /* percentage of time dispersion doors appear */
+int conf_preflect = 1; /* percentage of time reflection walls appear */
+int conf_pshot_coll = 5; /* percent chance of shots colliding */
+int conf_pgren_coll = 10; /* percent chance of grenades colliding */
+int conf_pgren_catch = 10; /* facing player chance of catching grenade */
+int conf_pmiss = 5; /* chance of bullet missing player */
+int conf_pdroneabsorb = 1; /* chance of absorbing a drone */
+int conf_fall_frac = 5; /* divisor of damage used for fall damage */
+
+int conf_bulspd = 5; /* speed of bullets */
+int conf_ishots = 15; /* initial ammo for player */
+int conf_nshots = 5; /* ammo boost for all when new player joins */
+int conf_maxncshot = 2; /* max number of simultaneous shots per player*/
+int conf_maxdam = 10; /* the initial shield for each player */
+int conf_mindam = 5; /* minimum damage from one unit of ammo */
+int conf_stabdam = 2; /* damage from stabbing */
+int conf_killgain = 2; /* shield gained from killing someone */
+int conf_slimefactor = 3; /* charge multiplier for slime */
+int conf_slimespeed = 5; /* speed of slime */
+int conf_lavaspeed = 1; /* speed of volcano lava */
+int conf_cloaklen = 20; /* duration of a cloak */
+int conf_scanlen = 20; /* duration of a scan */
+int conf_mindshot = 2; /* minium shot class needed to make a drone */
+
+struct kwvar {
+ char * kw;
+ int * var;
+};
+
+static struct kwvar keywords[] = {
+ { "random", &conf_random },
+ { "reflect", &conf_reflect },
+ { "monitor", &conf_monitor },
+ { "ooze", &conf_ooze },
+ { "fly", &conf_fly },
+ { "volcano", &conf_volcano },
+ { "drone", &conf_drone },
+ { "boots", &conf_boots },
+ { "scan", &conf_scan },
+ { "cloak", &conf_cloak },
+ { "logerr", &conf_logerr },
+ { "scoredecay", &conf_scoredecay },
+ { "maxremove", &conf_maxremove },
+ { "linger", &conf_linger },
+
+ { "flytime", &conf_flytime },
+ { "flystep", &conf_flystep },
+ { "volcano_max", &conf_volcano_max },
+ { "ptrip_face", &conf_ptrip_face },
+ { "ptrip_back", &conf_ptrip_back },
+ { "ptrip_side", &conf_ptrip_side },
+ { "prandom", &conf_prandom },
+ { "preflect", &conf_preflect },
+ { "pshot_coll", &conf_pshot_coll },
+ { "pgren_coll", &conf_pgren_coll },
+ { "pgren_catch", &conf_pgren_catch },
+ { "pmiss", &conf_pmiss },
+ { "pdroneabsorb", &conf_pdroneabsorb },
+ { "fall_frac", &conf_fall_frac },
+
+ { "bulspd", &conf_bulspd },
+ { "ishots", &conf_ishots },
+ { "nshots", &conf_nshots },
+ { "maxncshot", &conf_maxncshot },
+ { "maxdam", &conf_maxdam },
+ { "mindam", &conf_mindam },
+ { "stabdam", &conf_stabdam },
+ { "killgain", &conf_killgain },
+ { "slimefactor", &conf_slimefactor },
+ { "slimespeed", &conf_slimespeed },
+ { "lavaspeed", &conf_lavaspeed },
+ { "cloaklen", &conf_cloaklen },
+ { "scanlen", &conf_scanlen },
+ { "mindshot", &conf_mindshot },
+
+ { NULL, NULL}
+};
+
+static void
+load_config(f, fnm)
+ FILE * f;
+ char * fnm;
+{
+ char buf[BUFSIZ];
+ char *p;
+ char *word, *value;
+ struct kwvar *kvp;
+ int *varp;
+ int *nextp;
+ int line = 0;
+ int len;
+ int newval;
+
+ static const char *delim = " \t\n\r\f";
+
+ while ((p = fgetln(f, &len)) != NULL) {
+ line++;
+ if (p[len-1] == '\n')
+ len--;
+ if (len >= sizeof(buf))
+ continue;
+ (void)memcpy(buf, p, len);
+ buf[len] = '\0'; /* code assumes newlines later on */
+ p = buf;
+
+ /* skip leading white */
+ while (*p && isspace(*p))
+ p++;
+ /* allow blank lines and comment lines */
+ if (*p == '\0' || *p == '#')
+ continue;
+
+
+ /* first word must match a keyword */
+ varp = NULL;
+ for (kvp = keywords; kvp->kw; kvp++) {
+ int len;
+ len = strlen(kvp->kw);
+
+ if (strncmp(kvp->kw, p, len) != 0)
+ continue;
+ if (isspace(p[len]) || p[len] == '=')
+ break;
+ }
+
+ if (kvp->kw == NULL) {
+ fprintf(stderr, "%s:%d: unrecognised keyword\n",
+ fnm, line);
+ continue;
+ }
+
+ p += strlen(kvp->kw);
+
+ /* skip whitespace */
+ while (*p && isspace(*p))
+ p++;
+
+ if (*p++ != '=') {
+ fprintf(stderr, "%s:%d: expected `='\n", fnm, line);
+ continue;
+ }
+
+ /* skip whitespace */
+ while (*p && isspace(*p))
+ p++;
+
+ /* expect a number */
+ value = p;
+ while (*p && isdigit(*p))
+ p++;
+ if (!(*p == '\0' || isspace(*p) || *p == '#') || value == p) {
+ fprintf(stderr, "%s:%d: invalid value\n",
+ fnm, line);
+ continue;
+ }
+ *p = '\0';
+ newval = atoi(value);
+
+#ifdef DIAGNOSTIC
+ if (newval != *kvp->var)
+ printf("%s:%d: %s: %d -> %d\n", fnm, line,
+ kvp->kw, *kvp->var, newval);
+#endif
+
+ *kvp->var = newval;
+ }
+}
+
+/*
+ * load various config file, allowing later ones to
+ * overwrite earlier values
+ */
+void
+config()
+{
+ char *home;
+ char nm[MAXNAMLEN + 1];
+ static char *fnms[] = {
+ "/etc/hunt.conf"
+ "%s/.hunt.conf",
+ ".hunt.conf",
+ NULL
+ };
+ int fn;
+ FILE *f;
+
+ if ((home = getenv("HOME")) == NULL)
+ home = "";
+
+ for (fn = 0; fnms[fn]; fn++) {
+ snprintf(nm, sizeof nm, fnms[fn], home);
+ if (f = fopen(nm, "r")) {
+ load_config(f, nm);
+ fclose(f);
+ }
+ }
+}
diff --git a/games/hunt/huntd/conf.h b/games/hunt/huntd/conf.h
new file mode 100644
index 00000000000..e40d908253f
--- /dev/null
+++ b/games/hunt/huntd/conf.h
@@ -0,0 +1,51 @@
+/* $OpenBSD: conf.h,v 1.1 1999/01/29 07:30:34 d Exp $ */
+
+/* Configuration option variables for the server: */
+
+extern int conf_random; /* enable dispersion doors */
+extern int conf_reflect; /* enable generation of reflection walls */
+extern int conf_monitor; /* enable monitors */
+extern int conf_ooze; /* enable slime shots */
+extern int conf_fly; /* enable flight */
+extern int conf_volcano; /* enable volcanoes */
+extern int conf_drone; /* enable drone */
+extern int conf_boots; /* enable boots */
+extern int conf_scan; /* enable scanning */
+extern int conf_cloak; /* enable cloaking */
+extern int conf_logerr; /* errors to stderr as well as syslog(8) */
+
+extern int conf_scoredecay;
+extern int conf_maxremove; /* Maximum number of holes in the maze wall */
+extern int conf_linger; /* Seconds to keep game open with no players */
+
+extern int conf_flytime; /* max time flying */
+extern int conf_flystep; /* max displacement each flying time unit */
+extern int conf_volcano_max; /* max size of volcano */
+extern int conf_ptrip_face; /* chace of tripping a grenade on pickup, */
+extern int conf_ptrip_back; /* - when backing onto it */
+extern int conf_ptrip_side; /* - when walking sideways into it */
+extern int conf_prandom; /* percentage of time dispersion doors appear */
+extern int conf_preflect; /* percentage of time reflection walls appear */
+extern int conf_pshot_coll; /* percent chance of shots colliding */
+extern int conf_pgren_coll; /* percent chance of grenades colliding */
+extern int conf_pgren_catch; /* facing player chance of catching grenade */
+extern int conf_pmiss; /* chance of bullet missing player */
+extern int conf_pdroneabsorb; /* chance of absorbing a drone */
+extern int conf_fall_frac; /* divisor of damage used for fall damage */
+
+extern int conf_bulspd; /* speed of bullets */
+extern int conf_ishots; /* initial ammo for player */
+extern int conf_nshots; /* ammo boost for all when new player joins */
+extern int conf_maxncshot; /* max number of simultaneous shots per player*/
+extern int conf_maxdam; /* the initial shield for each player */
+extern int conf_mindam; /* minimum damage from one unit of ammo */
+extern int conf_stabdam; /* damage from stabbing */
+extern int conf_killgain; /* shield gained from killing someone */
+extern int conf_slimefactor; /* charge multiplier for slime */
+extern int conf_slimespeed; /* speed of slime */
+extern int conf_lavaspeed; /* speed of volcano lava */
+extern int conf_cloaklen; /* duration of a cloak */
+extern int conf_scanlen; /* duration of a scan */
+extern int conf_mindshot; /* minium shot class needed to make a drone */
+
+void config __P((void));
diff --git a/games/hunt/huntd/ctl.c b/games/hunt/huntd/ctl.c
deleted file mode 100644
index 14f3261b815..00000000000
--- a/games/hunt/huntd/ctl.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/* $NetBSD: ctl.c,v 1.2 1997/10/10 16:32:54 lukem Exp $ */
-/* $OpenBSD: ctl.c,v 1.2 1999/01/21 05:47:40 d 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)
-
-#ifndef lint
-static char sccsid[] = "@(#)ctl.c 5.2 (Berkeley) 3/13/86";
-#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
diff --git a/games/hunt/huntd/ctl_transact.c b/games/hunt/huntd/ctl_transact.c
deleted file mode 100644
index 35f1c4fd25b..00000000000
--- a/games/hunt/huntd/ctl_transact.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/* $NetBSD: ctl_transact.c,v 1.3 1997/10/20 00:37:16 lukem Exp $ */
-/* $OpenBSD: ctl_transact.c,v 1.2 1999/01/21 05:47:40 d 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)
-
-#ifndef lint
-static char sccsid[] = "@(#)ctl_transact.c 5.2 (Berkeley) 3/13/86";
-#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
diff --git a/games/hunt/huntd/draw.c b/games/hunt/huntd/draw.c
index 2262407a989..ac6c32ba148 100644
--- a/games/hunt/huntd/draw.c
+++ b/games/hunt/huntd/draw.c
@@ -1,13 +1,24 @@
+/* $OpenBSD: draw.c,v 1.3 1999/01/29 07:30:35 d Exp $ */
/* $NetBSD: draw.c,v 1.2 1997/10/10 16:33:04 lukem Exp $ */
-/* $OpenBSD: draw.c,v 1.2 1999/01/21 05:47:40 d Exp $ */
/*
* Hunt
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
* San Francisco, California
*/
-# include "hunt.h"
+#include "hunt.h"
+#include "server.h"
+#include "conf.h"
+static char translate __P((char));
+static int player_sym __P((PLAYER *, int, int));
+static void drawstatus __P((PLAYER *));
+static void see __P((PLAYER *, int));
+
+/*
+ * drawmaze:
+ * Draw the entire maze on a player's screen.
+ */
void
drawmaze(pp)
PLAYER *pp;
@@ -17,21 +28,26 @@ drawmaze(pp)
int y;
char *endp;
+ /* Clear the client's screen: */
clrscr(pp);
+ /* Draw the top row of the maze: */
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);
+ /* Draw the player as themselves */
if (pp->p_x == x && pp->p_y == y)
outch(pp, translate(*sp));
+ /* Possibly draw other players as team nrs */
else if (isplayer(*sp))
outch(pp, player_sym(pp, y, x));
else
outch(pp, *sp);
}
}
+ /* Draw the last row of the maze: */
cgoto(pp, HEIGHT - 1, 0);
outstr(pp, pp->p_maze[HEIGHT - 1], WIDTH);
drawstatus(pp);
@@ -41,58 +57,46 @@ drawmaze(pp)
* drawstatus - put up the status lines (this assumes the screen
* size is 80x24 with the maze being 64x24)
*/
-void
+static 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);
- }
+ outyx(pp, STAT_AMMO_ROW, STAT_LABEL_COL, "Ammo:");
+ ammo_update(pp);
+
+ outyx(pp, STAT_GUN_ROW, STAT_LABEL_COL, "Gun:");
+ outyx(pp, STAT_GUN_ROW, STAT_VALUE_COL, "%3s",
+ (pp->p_ncshot < conf_maxncshot) ? "ok" : "");
-# 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", " ",
+ outyx(pp, STAT_DAM_ROW, STAT_LABEL_COL, "Damage:");
+ outyx(pp, STAT_DAM_ROW, STAT_VALUE_COL, "%2d/%2d",
+ pp->p_damage, pp->p_damcap);
+
+ outyx(pp, STAT_KILL_ROW, STAT_LABEL_COL, "Kills:");
+ outyx(pp, STAT_KILL_ROW, STAT_VALUE_COL, "%3d",
+ (pp->p_damcap - conf_maxdam) / 2);
+
+ outyx(pp, STAT_PLAY_ROW, STAT_LABEL_COL, "Player:");
+ for (i = STAT_PLAY_ROW + 1, np = Player; np < End_player; np++, i++) {
+ outyx(pp, i, STAT_NAME_COL, "%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);
}
-# endif
+
+ outyx(pp, STAT_MON_ROW, STAT_LABEL_COL, "Monitor:");
+ for (i = STAT_MON_ROW + 1, np = Monitor; np < End_monitor; np++, i++) {
+ outyx(pp, i++, STAT_NAME_COL, "%5.5s %-10.10s %c",
+ " ", np->p_ident->i_name, np->p_ident->i_team);
+ }
}
+/*
+ * look
+ * check and update the visible area around the player
+ */
void
look(pp)
PLAYER *pp;
@@ -102,6 +106,10 @@ look(pp)
x = pp->p_x;
y = pp->p_y;
+ /*
+ * The player is aware of all objects immediately adjacent to
+ * their position:
+ */
check(pp, y - 1, x - 1);
check(pp, y - 1, x );
check(pp, y - 1, x + 1);
@@ -113,6 +121,7 @@ look(pp)
check(pp, y + 1, x + 1);
switch (pp->p_face) {
+ /* The player can see down corridors in directions except behind: */
case LEFTS:
see(pp, LEFTS);
see(pp, ABOVE);
@@ -133,101 +142,62 @@ look(pp)
see(pp, LEFTS);
see(pp, RIGHT);
break;
-# ifdef FLY
+ /* But they don't see too far when they are flying about: */
case FLYER:
break;
-# endif
}
+
+ /* Move the cursor back over the player: */
cgoto(pp, y, x);
}
-void
+/*
+ * see
+ * Look down a corridor, or towards an open space. This
+ * is a simulation of visibility from the player's perspective.
+ */
+static void
see(pp, face)
PLAYER *pp;
int face;
{
char *sp;
- int y, x, i, cnt;
+ int y, x;
+ /* Start from the player's position: */
x = pp->p_x;
y = pp->p_y;
+ #define seewalk(dx, dy) \
+ x += (dx); \
+ y += (dy); \
+ sp = &Maze[y][x]; \
+ while (See_over[(int)*sp]) { \
+ x += (dx); \
+ y += (dy); \
+ sp += ((dx) + (dy) * sizeof Maze[0]); \
+ check(pp, y + dx, x + dy); \
+ check(pp, y, x); \
+ check(pp, y - dx, x - dy); \
+ }
+
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;
+ seewalk(-1, 0); 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;
+ seewalk(1, 0); 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;
+ seewalk(0, -1); 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;
+ seewalk(0, 1); break;
}
}
+/*
+ * check
+ * The player is aware of a cell in the maze.
+ * Ensure it is shown properly on their screen.
+ */
void
check(pp, y, x)
PLAYER *pp;
@@ -237,6 +207,14 @@ check(pp, y, x)
int ch;
PLAYER *rpp;
+ if (pp == ALL_PLAYERS) {
+ for (pp = Player; pp < End_player; pp++)
+ check(pp, y, x);
+ for (pp = Monitor; pp < End_monitor; pp++)
+ check(pp, y, x);
+ return;
+ }
+
index = y * sizeof Maze[0] + x;
ch = ((char *) Maze)[index];
if (ch != ((char *) pp->p_maze)[index]) {
@@ -254,34 +232,24 @@ check(pp, y, x)
/*
* showstat
- * Update the status of players
+ * Update the status of a player on everyone's screen
*/
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);
- }
+
+ outyx(ALL_PLAYERS,
+ STAT_PLAY_ROW + 1 + (pp - Player), STAT_SCAN_COL,
+ "%c", stat_char(pp));
}
/*
* drawplayer:
* Draw the player on the screen and show him to everyone who's scanning
* unless he is cloaked.
+ * The 'draw' flag when false, causes the 'saved under' character to
+ * be drawn instead of the player; effectively un-drawing the player.
*/
void
drawplayer(pp, draw)
@@ -293,34 +261,54 @@ drawplayer(pp, draw)
x = pp->p_x;
y = pp->p_y;
+
+ /* Draw or un-draw the player into the master map: */
Maze[y][x] = draw ? pp->p_face : pp->p_over;
-# ifdef MONITOR
+ /* The monitors can always see this player: */
for (newp = Monitor; newp < End_monitor; newp++)
check(newp, y, x);
-# endif
+ /* Check if other players can see this player: */
for (newp = Player; newp < End_player; newp++) {
- if (!draw || newp == pp) {
+ if (!draw) {
+ /* When un-drawing, show everyone what was under */
+ check(newp, y, x);
+ continue;
+ }
+ if (newp == pp) {
+ /* The player can always see themselves: */
check(newp, y, x);
continue;
}
+ /* Check if the other player just run out of scans */
if (newp->p_scan == 0) {
+ /* The other player is no longer scanning: */
newp->p_scan--;
showstat(newp);
- }
- else if (newp->p_scan > 0) {
+ /* Check if the other play is scannning */
+ } else if (newp->p_scan > 0) {
+ /* If this player's not cloacked, draw him: */
if (pp->p_cloak < 0)
check(newp, y, x);
+ /* And this uses up a scan. */
newp->p_scan--;
}
}
- if (!draw || pp->p_cloak < 0)
- return;
- if (pp->p_cloak-- == 0)
- showstat(pp);
+
+ /* Use up one point of cloak time when drawing: */
+ if (draw && pp->p_cloak >= 0) {
+ pp->p_cloak--;
+ /* Check if we ran out of cloak: */
+ if (pp->p_cloak < 0)
+ showstat(pp);
+ }
}
+/*
+ * message:
+ * Write a message at the bottom of the screen.
+ */
void
message(pp, s)
PLAYER *pp;
@@ -333,10 +321,10 @@ message(pp, s)
/*
* translate:
- * Turn a character into the right direction character if we are
- * looking at the current player.
+ * Turn a player character into a more personal player character.
+ * ie: {,},!,i becomes <,>,v,^
*/
-char
+static char
translate(ch)
char ch;
{
@@ -355,9 +343,12 @@ translate(ch)
/*
* player_sym:
- * Return the player symbol
+ * Return the symbol for the player at (y,x) when viewed by player 'pp'.
+ * ie: - unteamed players appear as {,},!,i
+ * - unteamed monitors see all players as team digits
+ * - teamed players see other players on their team, as a digit
*/
-int
+static int
player_sym(pp, y, x)
PLAYER *pp;
int y, x;
@@ -367,10 +358,8 @@ player_sym(pp, y, x)
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;
diff --git a/games/hunt/huntd/driver.c b/games/hunt/huntd/driver.c
index c842448bc43..9a8af5a4fbd 100644
--- a/games/hunt/huntd/driver.c
+++ b/games/hunt/huntd/driver.c
@@ -1,43 +1,40 @@
+/* $OpenBSD: driver.c,v 1.3 1999/01/29 07:30:35 d Exp $ */
/* $NetBSD: driver.c,v 1.5 1997/10/20 00:37:16 lukem Exp $ */
-/* $OpenBSD: driver.c,v 1.2 1999/01/21 05:47:40 d Exp $ */
/*
* Hunt
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
* San Francisco, California
*/
-# 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
+#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 <stdio.h>
+#include <tcpd.h>
+#include <syslog.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include "hunt.h"
+#include "conf.h"
+#include "server.h"
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 */
+u_int16_t Server_port = HUNT_PORT;
+int Server_socket; /* test socket to answer datagrams */
FLAG inetd_spawned; /* invoked via inetd */
-FLAG standard_port = TRUE; /* true if listening on standard port */
+FLAG should_announce = 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
+in_addr_t Server_addr = INADDR_ANY; /* address to bind to */
static void clear_scores __P((void));
static int havechar __P((PLAYER *));
@@ -46,7 +43,7 @@ static void init __P((void));
static void makeboots __P((void));
static void send_stats __P((void));
static void zap __P((PLAYER *, FLAG));
-
+static void announce_game __P((void));
/*
* main:
@@ -59,19 +56,15 @@ main(ac, 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 };
+ FILE * cffile;
+ static struct timeval linger = { 0, 0 };
First_arg = av[0];
if (ep == NULL || *ep == NULL)
@@ -80,77 +73,100 @@ main(ac, av, ep)
ep++;
Last_arg = ep[-1] + strlen(ep[-1]);
- while ((c = getopt(ac, av, "sp:")) != -1) {
+ config();
+
+ while ((c = getopt(ac, av, "sp:a:")) != -1) {
switch (c) {
case 's':
server = TRUE;
break;
-# ifdef INTERNET
case 'p':
- standard_port = FALSE;
- Test_port = atoi(optarg);
+ should_announce = FALSE;
+ Server_port = atoi(optarg);
+ break;
+ case 'a':
+ Server_addr = inet_addr(optarg);
+ if (Server_addr == INADDR_NONE)
+ err(1, "bad interface address: %s", optarg);
break;
-# endif
default:
erred:
- fprintf(stderr, "Usage: %s [-s] [-p port]\n", av[0]);
- exit(1);
+ fprintf(stderr, "Usage: %s [-s] [-p port] [-a addr]\n",
+ av[0]);
+ exit(2);
}
}
if (optind < ac)
goto erred;
- init();
+ /* Open syslog: */
+ openlog("huntd", LOG_PID | (conf_logerr && !server? LOG_PERROR : 0),
+ LOG_DAEMON);
+ /* Initialise game parameters: */
+ init();
again:
do {
+ /* Wait for something to happen: */
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
+ if (errno != EINTR) {
+ syslog(LOG_ERR, "select: %m");
+ cleanup(1);
+ }
errno = 0;
}
+
+ /* Remember which descriptors are active: */
Have_inp = read_fds;
-# ifdef INTERNET
- if (FD_ISSET(Test_socket, &read_fds)) {
- namelen = DAEMON_SIZE;
+
+ /* Handle a datagram sent to the server socket: */
+ if (FD_ISSET(Server_socket, &read_fds)) {
+ struct sockaddr_in test;
+ int namelen;
+ u_int16_t msg;
+
+ namelen = sizeof test;
+ (void) recvfrom(Server_socket,
+ &msg, sizeof msg,
+ 0,
+ (struct sockaddr *) &test, &namelen);
+
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);
+ (void) sendto(Server_socket,
+ &reply, sizeof reply,
+ 0,
+ (struct sockaddr *) &test, sizeof test);
break;
case C_SCORES:
reply = htons(stat_port);
- (void) sendto(Test_socket, (char *) &reply,
- sizeof reply, 0,
- (struct sockaddr *) &test, DAEMON_SIZE);
+ (void) sendto(Server_socket,
+ &reply, sizeof reply,
+ 0,
+ (struct sockaddr *) &test, sizeof test);
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);
+ (void) sendto(Server_socket,
+ &reply, sizeof reply,
+ 0,
+ (struct sockaddr *) &test, sizeof test);
break;
}
}
-# endif
+
+ /* Process input and move bullets until we've exhausted input */
for (;;) {
had_char = FALSE;
for (pp = Player; pp < End_player; pp++)
@@ -159,14 +175,12 @@ again:
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();
@@ -175,62 +189,65 @@ again:
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
}
+
+ /* Answer new player connections: */
if (FD_ISSET(Socket, &read_fds))
if (answer()) {
-# ifdef INTERNET
- if (first && standard_port)
- faketalk();
-# endif
+ if (first && should_announce)
+ announce_game();
first = FALSE;
}
+
+ /* Answer statistics connections: */
if (FD_ISSET(Status, &read_fds))
send_stats();
+
+ /* Flush/synchronize all the displays: */
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);
+ flush(pp);
}
-# 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);
+ flush(pp);
}
-# endif
} while (Nplayer > 0);
+ /* No more players. Wait for a short while for one to come back: */
read_fds = Fds_mask;
+ linger.tv_sec = conf_linger;
if (select(Num_fds, &read_fds, NULL, NULL, &linger) > 0) {
+ /* Someone returned! Resume the game: */
goto again;
}
+
+ /* If we are an inetd server, we should restart: */
if (server) {
clear_scores();
makemaze();
clearwalls();
-# ifdef BOOTS
makeboots();
-# endif
first = TRUE;
goto again;
}
-# ifdef MONITOR
+ /* Destroy all the monitors: */
for (pp = Monitor; pp < End_monitor; )
zap(pp, FALSE);
-# endif
+
+ /* The end: */
cleanup(0);
- /* NOTREACHED */
- return(0);
+ exit(0);
}
/*
@@ -241,185 +258,124 @@ static void
init()
{
int i;
-# ifdef INTERNET
- SOCKET test_port;
+ struct sockaddr_in test_port;
int msg;
int len;
-# endif
+ struct sockaddr_in addr;
+
+ /* XXX should we call deamon() instead ??? */
+ (void) setsid();
+ (void) setpgid(getpid(), getpid());
-# ifndef DEBUG
-# ifdef TIOCNOTTY
- (void) ioctl(fileno(stdout), TIOCNOTTY, NULL);
-# endif
- (void) setpgrp(getpid(), getpid());
+ /* Handle some signals: */
(void) signal(SIGHUP, SIG_IGN);
- (void) signal(SIGINT, SIG_IGN);
+ (void) signal(SIGINT, cleanup);
(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) chdir("/"); /* just in case it core dumps */
+ (void) umask(0777); /* No privacy at all! */
+
+ /* Initialize statistics socket: */
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = Server_addr;
+ addr.sin_port = 0;
+
+ Status = socket(AF_INET, SOCK_STREAM, 0);
+ if (bind(Status, (struct sockaddr *) &addr, sizeof addr) < 0) {
+ syslog(LOG_ERR, "bind: %m");
+ cleanup(1);
}
(void) listen(Status, 5);
-# ifdef INTERNET
- len = sizeof (SOCKET);
- if (getsockname(Status, (struct sockaddr *) &Daemon, &len) < 0) {
-# ifdef LOG
+ len = sizeof (struct sockaddr_in);
+ if (getsockname(Status, (struct sockaddr *) &addr, &len) < 0) {
syslog(LOG_ERR, "getsockname: %m");
-# else
- warn("getsockname");
-# endif
- exit(1);
+ cleanup(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)
+ stat_port = ntohs(addr.sin_port);
+
+ /* Initialize main socket: */
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = Server_addr;
+ addr.sin_port = 0;
+
+ Socket = socket(AF_INET, SOCK_STREAM, 0);
msg = 1;
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
- 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);
- }
+ syslog(LOG_ERR, "setsockopt loopback %m");
+ if (bind(Socket, (struct sockaddr *) &addr, sizeof addr) < 0) {
+ syslog(LOG_ERR, "bind: %m");
+ cleanup(1);
}
(void) listen(Socket, 5);
-# ifdef INTERNET
- len = sizeof (SOCKET);
- if (getsockname(Socket, (struct sockaddr *) &Daemon, &len) < 0) {
-# ifdef LOG
+ len = sizeof (struct sockaddr_in);
+ if (getsockname(Socket, (struct sockaddr *) &addr, &len) < 0) {
syslog(LOG_ERR, "getsockname: %m");
-# else
- warn("getsockname");
-# endif
- exit(1);
+ cleanup(1);
}
- sock_port = ntohs(Daemon.sin_port);
-# endif
+ sock_port = ntohs(addr.sin_port);
- /*
- * Initialize minimal select mask
- */
+ /* 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) {
+ /* Check if stdin is a socket: */
+ len = sizeof (struct sockaddr_in);
+ if (getsockname(STDIN_FILENO, (struct sockaddr *) &test_port, &len) >= 0
+ && test_port.sin_family == AF_INET) {
+ /* We are probably running from inetd: */
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);
+ Server_socket = STDIN_FILENO;
+ if (test_port.sin_port != htons((u_short) Server_port)) {
+ should_announce = FALSE;
+ Server_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);
+ /* We need to listen on a socket: */
+ test_port = addr;
+ test_port.sin_port = htons((u_short) Server_port);
+
+ Server_socket = socket(AF_INET, SOCK_DGRAM, 0);
+ if (bind(Server_socket, (struct sockaddr *) &test_port,
+ sizeof test_port) < 0) {
+ syslog(LOG_ERR, "bind port %d: %m", Server_port);
+ cleanup(1);
}
- (void) listen(Test_socket, 5);
+ (void) listen(Server_socket, 5);
}
- FD_SET(Test_socket, &Fds_mask);
- if (Test_socket + 1 > Num_fds)
- Num_fds = Test_socket + 1;
-# endif
+ /* We'll handle the broadcast listener in the main loop: */
+ FD_SET(Server_socket, &Fds_mask);
+ if (Server_socket + 1 > Num_fds)
+ Num_fds = Server_socket + 1;
+ /* Initialise the random seed: */
Seed = getpid() + time((time_t *) NULL);
+
+ /* Dig the maze: */
makemaze();
-# ifdef BOOTS
+
+ /* Create some boots, if needed: */
makeboots();
-# endif
+ /* Construct a table of what objects a player can see over: */
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
+ syslog(LOG_INFO, "game started");
}
-# ifdef BOOTS
/*
* makeboots:
* Put the boots in the maze
@@ -430,67 +386,74 @@ 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;
+ if (conf_boots) {
+ 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
+ * Apply damage to the victim from an attacker.
+ * If the victim dies as a result, give points to 'credit',
*/
void
-checkdam(ouch, gotcha, credit, amt, shot_type)
- PLAYER *ouch, *gotcha;
+checkdam(victim, attacker, credit, damage, shot_type)
+ PLAYER *victim, *attacker;
IDENT *credit;
- int amt;
+ int damage;
char shot_type;
{
char *cp;
+ int y;
- if (ouch->p_death[0] != '\0')
+ /* Don't do anything if the victim is already in the throes of death */
+ if (victim->p_death[0] != '\0')
return;
-# ifdef BOOTS
+
+ /* Weaken slime attacks by 0.5 * number of boots the victim has on: */
if (shot_type == SLIME)
- switch (ouch->p_nboots) {
+ switch (victim->p_nboots) {
default:
break;
case 1:
- amt = (amt + 1) / 2;
+ damage = (damage + 1) / 2;
break;
case 2:
- if (gotcha != NULL)
- message(gotcha, "He has boots on!");
+ if (attacker != NULL)
+ message(attacker, "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);
+
+ /* The victim sustains some damage: */
+ victim->p_damage += damage;
+
+ /* Check if the victim survives the hit: */
+ if (victim->p_damage <= victim->p_damcap) {
+ /* They survive. */
+ outyx(victim, STAT_DAM_ROW, STAT_VALUE_COL, "%2d",
+ victim->p_damage);
return;
}
- /* Someone DIED */
+ /* Describe how the victim 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 */
+ victim->p_ammo = 0; /* No exploding */
break;
case SHOT:
cp = "Shot to death";
@@ -504,172 +467,219 @@ checkdam(ouch, gotcha, credit, amt, shot_type)
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");
+ char *blame;
+
+ /*
+ * Nobody is taking the credit for the kill.
+ * Attribute it to either a mine or 'act of God'.
+ */
+ switch (shot_type) {
+ case MINE:
+ case GMINE:
+ blame = "a mine";
+ break;
+ default:
+ blame = "act of God";
+ break;
+ }
+
+ /* Set the death message: */
+ (void) snprintf(victim->p_death, sizeof victim->p_death,
+ "| %s by %s |", cp, blame);
+
+ /* No further score crediting needed. */
return;
}
- (void) sprintf(ouch->p_death, "| %s by %s |", cp, credit->i_name);
+ /* Set the death message: */
+ (void) snprintf(victim->p_death, sizeof victim->p_death,
+ "| %s by %s |", cp, credit->i_name);
- if (ouch == gotcha) { /* No use killing yourself */
+ if (victim == attacker) {
+ /* 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) {
+ }
+ else if (victim->p_ident->i_team == ' '
+ || victim->p_ident->i_team != credit->i_team) {
+ /* A cross-team kill: */
credit->i_kills++;
credit->i_gkills++;
}
else {
+ /* They killed someone on the same team: */
credit->i_kills--;
credit->i_bkills++;
}
+
+ /* Compute the new credited score: */
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);
+
+ /* The victim accrues one death: */
+ victim->p_ident->i_deaths++;
+
+ /* Account for 'Stillborn' deaths */
+ if (victim->p_nchar == 0)
+ victim->p_ident->i_stillb++;
+
+ if (attacker) {
+ /* Give the attacker player a bit more strength */
+ attacker->p_damcap += conf_killgain;
+ attacker->p_damage -= conf_killgain;
+ if (attacker->p_damage < 0)
+ attacker->p_damage = 0;
+
+ /* Tell the attacker's his new strength: */
+ outyx(attacker, STAT_DAM_ROW, STAT_VALUE_COL, "%2d/%2d",
+ attacker->p_damage, attacker->p_damcap);
+
+ /* Tell the attacker's his new 'kill count': */
+ outyx(attacker, STAT_KILL_ROW, STAT_VALUE_COL, "%3d",
+ (attacker->p_damcap - conf_maxdam) / 2);
+
+ /* Update the attacker's score for everyone else */
+ y = STAT_PLAY_ROW + 1 + (attacker - Player);
+ outyx(ALL_PLAYERS, y, STAT_NAME_COL,
+ "%5.2f", attacker->p_ident->i_score);
}
-# endif
}
/*
* zap:
- * Kill off a player and take him out of the game.
+ * Kill off a player and take them out of the game.
+ * The 'was_player' flag indicates that the player was not
+ * a monitor and needs extra cleaning up.
*/
static void
zap(pp, was_player)
PLAYER *pp;
FLAG was_player;
{
- int i, len;
+ int len;
BULLET *bp;
PLAYER *np;
int x, y;
int savefd;
if (was_player) {
+ /* If they died from a shot, clean up shrapnel */
if (pp->p_undershot)
fixshots(pp->p_y, pp->p_x, pp->p_over);
+ /* Let the player see their last position: */
drawplayer(pp, FALSE);
+ /* Remove from game: */
Nplayer--;
}
- len = strlen(pp->p_death); /* Display the cause of death */
+ /* Display the cause of death in the centre of the screen: */
+ len = strlen(pp->p_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] = '-';
+ outyx(pp, HEIGHT / 2, x, "%s", pp->p_death);
+
+ /* Put some horizontal lines around and below the death message: */
+ memset(pp->p_death + 1, '-', len - 2);
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);
+ outyx(pp, HEIGHT / 2 - 1, x, "%s", pp->p_death);
+ outyx(pp, HEIGHT / 2 + 1, x, "%s", pp->p_death);
+
+ /* Move to bottom left */
cgoto(pp, HEIGHT, 0);
savefd = pp->p_fd;
-# ifdef MONITOR
if (was_player) {
-# endif
+ int expl_charge;
+ int expl_type;
+ int ammo_exploding;
+
+ /* Check all the bullets: */
for (bp = Bullets; bp != NULL; bp = bp->b_next) {
if (bp->b_owner == pp)
+ /* Zapped players can't own bullets: */
bp->b_owner = NULL;
if (bp->b_x == pp->p_x && bp->b_y == pp->p_y)
+ /* Bullets over the player are now over air: */
bp->b_over = SPACE;
}
- i = rand_num(pp->p_ammo);
- x = rand_num(pp->p_ammo);
- if (x > i)
- i = x;
+ /* Explode a random fraction of the player's ammo: */
+ ammo_exploding = rand_num(pp->p_ammo);
+
+ /* Determine the type and amount of detonation: */
+ expl_charge = rand_num(ammo_exploding + 1);
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])
+ /* Ignore the no-ammo case: */
+ expl_charge = 0;
+ else if (ammo_exploding >= pp->p_ammo - 1) {
+ /* Maximal explosions always appear as slime: */
+ expl_charge = pp->p_ammo;
+ expl_type = SLIME;
+ } else {
+ /*
+ * Figure out the best effective explosion
+ * type to use, given the amount of charge
+ */
+ int btype, stype;
+ for (btype = MAXBOMB - 1; btype > 0; btype--)
+ if (expl_charge >= shot_req[btype])
break;
- for (y = MAXSLIME - 1; y > 0; y--)
- if (i >= slime_req[y])
+ for (stype = MAXSLIME - 1; stype > 0; stype--)
+ if (expl_charge >= slime_req[stype])
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];
+ /* Pick the larger of the bomb or slime: */
+ if (btype >= 0 && stype >= 0) {
+ if (shot_req[btype] > slime_req[btype])
+ btype = -1;
}
+ if (btype >= 0) {
+ expl_type = shot_type[btype];
+ expl_charge = shot_req[btype];
+ } else
+ expl_type = SLIME;
}
- 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.",
+
+ if (expl_charge > 0) {
+ char buf[BUFSIZ];
+
+ /* Detonate: */
+ (void) add_shot(expl_type, pp->p_y, pp->p_x,
+ pp->p_face, expl_charge, (PLAYER *) NULL,
+ TRUE, SPACE);
+
+ /* Explain what the explosion is about. */
+ snprintf(buf, sizeof 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
+ message(ALL_PLAYERS, buf);
+
while (pp->p_nboots-- > 0) {
+ /* Throw one of the boots away: */
for (np = Boot; np < &Boot[NBOOTS]; np++)
if (np->p_flying < 0)
break;
+#ifdef DIAGNOSTIC
if (np >= &Boot[NBOOTS])
err(1, "Too many boots");
+#endif
+ /* Start the boots from where the player is */
np->p_undershot = FALSE;
np->p_x = pp->p_x;
np->p_y = pp->p_y;
+ /* Throw for up to 20 steps */
np->p_flying = rand_num(20);
np->p_flyx = 2 * rand_num(6) - 5;
np->p_flyy = 2 * rand_num(6) - 5;
@@ -677,9 +687,8 @@ zap(pp, was_player)
np->p_face = BOOT;
showexpl(np->p_y, np->p_x, BOOT);
}
-# endif
}
-# ifdef BOOTS
+ /* No explosion. Leave the player's boots behind. */
else if (pp->p_nboots > 0) {
if (pp->p_nboots == 2)
Maze[pp->p_y][pp->p_x] = BOOT_PAIR;
@@ -689,121 +698,100 @@ zap(pp, was_player)
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) {
+ /* Any unexploded ammo builds up in the volcano: */
+ volcano += pp->p_ammo - expl_charge;
+
+ /* Volcano eruption: */
+ if (conf_volcano && rand_num(100) < volcano /
+ conf_volcano_max) {
+ /* Erupt near the middle of the map */
do {
x = rand_num(WIDTH / 2) + WIDTH / 4;
y = rand_num(HEIGHT / 2) + HEIGHT / 4;
} while (Maze[y][x] != SPACE);
+
+ /* Convert volcano charge into lava: */
(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;
+
+ /* Tell eveyone what's happening */
+ message(ALL_PLAYERS, "Volcano eruption.");
}
-# endif
-# ifdef DRONE
- if (rand_num(100) < 2) {
+ /* Drone: */
+ if (conf_drone && rand_num(100) < 2) {
+ /* Find a starting place near the middle of the map: */
do {
x = rand_num(WIDTH / 2) + WIDTH / 4;
y = rand_num(HEIGHT / 2) + HEIGHT / 4;
} while (Maze[y][x] != SPACE);
+
+ /* Start the drone going: */
add_shot(DSHOT, y, x, rand_dir(),
- shot_req[MINDSHOT +
- rand_num(MAXBOMB - MINDSHOT)],
+ shot_req[conf_mindshot +
+ rand_num(MAXBOMB - conf_mindshot)],
(PLAYER *) NULL, FALSE, SPACE);
}
-# endif
- sendcom(pp, ENDWIN);
- (void) putc(' ', pp->p_output);
+ /* Tell the zapped player's client to shut down. */
+ sendcom(pp, ENDWIN, ' ');
(void) fclose(pp->p_output);
+ /* Close up the gap in the Player array: */
End_player--;
if (pp != End_player) {
- memcpy(pp, End_player, sizeof (PLAYER));
- (void) sprintf(Buf, "%5.2f%c%-10.10s %c",
+ /* Move the last player into the gap: */
+ memcpy(pp, End_player, sizeof *pp);
+ outyx(ALL_PLAYERS,
+ STAT_PLAY_ROW + 1 + (pp - Player),
+ STAT_NAME_COL,
+ "%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);
- }
+ /* Erase the last player from the display: */
+ cgoto(ALL_PLAYERS, STAT_PLAY_ROW + 1 + Nplayer, STAT_NAME_COL);
+ ce(ALL_PLAYERS);
}
else {
- sendcom(pp, ENDWIN);
- (void) putc(LAST_PLAYER, pp->p_output);
+ /* Zap a monitor */
+
+ /* Close the session: */
+ sendcom(pp, ENDWIN, LAST_PLAYER);
(void) fclose(pp->p_output);
+ /* shuffle the monitor table */
End_monitor--;
if (pp != End_monitor) {
- memcpy(pp, End_monitor, sizeof (PLAYER));
- (void) sprintf(Buf, "%5.5s %-10.10s %c", " ",
+ memcpy(pp, End_monitor, sizeof *pp);
+ outyx(ALL_PLAYERS,
+ STAT_MON_ROW + 1 + (pp - Player), STAT_NAME_COL,
+ "%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);
}
+ /* Erase the last monitor in the list */
+ cgoto(ALL_PLAYERS,
+ STAT_MON_ROW + 1 + (End_monitor - Monitor),
+ STAT_NAME_COL);
+ ce(ALL_PLAYERS);
}
-# endif
+ /* Update the file descriptor sets used by select: */
FD_CLR(savefd, &Fds_mask);
if (Num_fds == savefd + 1) {
Num_fds = Socket;
-# ifdef INTERNET
- if (Test_socket > Socket)
- Num_fds = Test_socket;
-# endif
+ if (Server_socket > Socket)
+ Num_fds = Server_socket;
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++;
}
}
@@ -816,7 +804,10 @@ int
rand_num(range)
int range;
{
- return (range == 0 ? 0 : RN % range);
+ if (range == 0)
+ return 0;
+ Seed = Seed * 11109 + 13849;
+ return (((Seed >> 16) & 0xffff) % range);
}
/*
@@ -851,37 +842,36 @@ check_again:
* cleanup:
* Exit with the given value, cleaning up any droppings lying around
*/
-SIGNAL_TYPE
+void
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);
+ /* Place their cursor in a friendly position: */
+ cgoto(ALL_PLAYERS, HEIGHT, 0);
+
+ /* Send them all the ENDWIN command: */
+ sendcom(ALL_PLAYERS, ENDWIN, LAST_PLAYER);
+
+ /* And close their connections: */
+ for (pp = Player; pp < End_player; pp++)
(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);
+ for (pp = Monitor; pp < End_monitor; pp++)
(void) fclose(pp->p_output);
- }
-# endif
+
+ /* Close the server socket: */
(void) close(Socket);
-# ifdef AF_UNIX_HACK
- (void) unlink(Sock_name);
-# endif
+ /* The end: */
+ syslog(LOG_INFO, "game over");
exit(eval);
}
/*
* send_stats:
- * Print stats to requestor
+ * Accept a connection to the statistics port, and emit
+ * the stats.
*/
static void
send_stats()
@@ -889,46 +879,43 @@ send_stats()
IDENT *ip;
FILE *fp;
int s;
- SOCKET sockstruct;
+ struct sockaddr_in sockstruct;
int socklen;
+ struct request_info ri;
- /*
- * Get the output stream ready
- */
-# ifdef INTERNET
+ /* Accept a connection to the statistics socket: */
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;
}
+
+ /* Check for access permissions: */
+ request_init(&ri, RQ_DAEMON, "huntd", RQ_FILE, s, 0);
+ if (hosts_access(&ri) == 0) {
+ close(s);
+ 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
- */
+ /* Send the statistics as raw text down the socket: */
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)
+ fprintf(fp, "%s%c%c%c\t", ip->i_name,
+ ip->i_team == ' ' ? ' ' : '[',
+ ip->i_team,
+ ip->i_team == ' ' ? ' ' : ']'
+ );
+ if (strlen(ip->i_name) + 3 < 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,
@@ -937,16 +924,13 @@ send_stats()
}
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, "%s%c%c%c\t", ip->i_name,
+ ip->i_team == ' ' ? ' ' : '[',
+ ip->i_team,
+ 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);
@@ -957,16 +941,28 @@ send_stats()
/*
* clear_scores:
- * Clear out the scores so the next session start clean
+ * Clear the Scores list.
*/
static void
clear_scores()
{
IDENT *ip, *nextip;
+ /* Release the list of scores: */
for (ip = Scores; ip != NULL; ip = nextip) {
nextip = ip->i_next;
(void) free((char *) ip);
}
Scores = NULL;
}
+
+/*
+ * announce_game:
+ * Publically announce the game
+ */
+static void
+announce_game()
+{
+
+ /* Stub */
+}
diff --git a/games/hunt/huntd/execute.c b/games/hunt/huntd/execute.c
index 53695c72f88..8719f63dac3 100644
--- a/games/hunt/huntd/execute.c
+++ b/games/hunt/huntd/execute.c
@@ -1,24 +1,27 @@
+/* $OpenBSD: execute.c,v 1.3 1999/01/29 07:30:35 d Exp $ */
/* $NetBSD: execute.c,v 1.2 1997/10/10 16:33:13 lukem Exp $ */
-/* $OpenBSD: execute.c,v 1.2 1999/01/21 05:47:40 d Exp $ */
/*
* Hunt
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
* San Francisco, California
*/
-# include <stdlib.h>
-# include "hunt.h"
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include "hunt.h"
+#include "conf.h"
+#include "server.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 *));
+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
@@ -30,20 +33,24 @@ mon_execute(pp)
char ch;
ch = pp->p_cbuf[pp->p_ncount++];
+
switch (ch) {
case CTRL('L'):
+ /* Redraw messed-up screen */
sendcom(pp, REDRAW);
break;
case 'q':
- (void) strcpy(pp->p_death, "| Quit |");
+ /* Quit client */
+ (void) strlcpy(pp->p_death, "| Quit |", sizeof pp->p_death);
break;
+ default:
+ /* Ignore everything else */
}
}
-# endif
/*
* execute:
- * Execute a single command
+ * Execute a single command from a player
*/
void
execute(pp)
@@ -53,47 +60,48 @@ execute(pp)
ch = pp->p_cbuf[pp->p_ncount++];
-# ifdef FLY
+ /* When flying, only allow refresh and quit. */
if (pp->p_flying >= 0) {
switch (ch) {
case CTRL('L'):
sendcom(pp, REDRAW);
break;
case 'q':
- (void) strcpy(pp->p_death, "| Quit |");
+ (void) strlcpy(pp->p_death, "| Quit |",
+ sizeof pp->p_death);
break;
}
return;
}
-# endif
+ /* Decode the command character: */
switch (ch) {
case CTRL('L'):
- sendcom(pp, REDRAW);
+ sendcom(pp, REDRAW); /* Refresh */
break;
case 'h':
- move_player(pp, LEFTS);
+ move_player(pp, LEFTS); /* Move left */
break;
case 'H':
- face(pp, LEFTS);
+ face(pp, LEFTS); /* Face left */
break;
case 'j':
- move_player(pp, BELOW);
+ move_player(pp, BELOW); /* Move down */
break;
case 'J':
- face(pp, BELOW);
+ face(pp, BELOW); /* Face down */
break;
case 'k':
- move_player(pp, ABOVE);
+ move_player(pp, ABOVE); /* Move up */
break;
case 'K':
- face(pp, ABOVE);
+ face(pp, ABOVE); /* Face up */
break;
case 'l':
- move_player(pp, RIGHT);
+ move_player(pp, RIGHT); /* Move right */
break;
case 'L':
- face(pp, RIGHT);
+ face(pp, RIGHT); /* Face right */
break;
case 'f':
case '1':
@@ -132,7 +140,6 @@ execute(pp)
case '@':
fire(pp, 10); /* 21x21 BOMB */
break;
-# ifdef OOZE
case 'o':
fire_slime(pp, 0); /* SLIME */
break;
@@ -140,27 +147,26 @@ execute(pp)
fire_slime(pp, 1); /* SSLIME */
break;
case 'p':
- fire_slime(pp, 2);
+ fire_slime(pp, 2); /* large slime */
break;
case 'P':
- fire_slime(pp, 3);
+ fire_slime(pp, 3); /* very large slime */
break;
-# endif
- case 's':
+ case 's': /* start scanning */
scan(pp);
break;
- case 'c':
+ case 'c': /* start cloaking */
cloak(pp);
break;
- case 'q':
- (void) strcpy(pp->p_death, "| Quit |");
+ case 'q': /* quit */
+ (void) strlcpy(pp->p_death, "| Quit |", sizeof pp->p_death);
break;
}
}
/*
* move_player:
- * Execute a move in the given direction
+ * Try to move player 'pp' in direction 'dir'.
*/
static void
move_player(pp, dir)
@@ -191,73 +197,78 @@ move_player(pp, dir)
}
moved = FALSE;
+
+ /* What would the player move over: */
switch (Maze[y][x]) {
+ /* Players can move through spaces and doors, no problem: */
case SPACE:
-# ifdef RANDOM
case DOOR:
-# endif
moved = TRUE;
break;
+ /* Can't move through walls: */
case WALL1:
case WALL2:
case WALL3:
-# ifdef REFLECT
case WALL4:
case WALL5:
-# endif
break;
+ /* Moving over a mine - try to pick it up: */
case MINE:
case GMINE:
if (dir == pp->p_face)
- pickup(pp, y, x, 2, Maze[y][x]);
+ /* facing it: 2% chance of trip */
+ pickup(pp, y, x, conf_ptrip_face, Maze[y][x]);
else if (opposite(dir, pp->p_face))
- pickup(pp, y, x, 95, Maze[y][x]);
+ /* facing away: 95% chance of trip */
+ pickup(pp, y, x, conf_ptrip_back, Maze[y][x]);
else
- pickup(pp, y, x, 50, Maze[y][x]);
+ /* facing sideways: 50% chance of trip */
+ pickup(pp, y, x, conf_ptrip_side, Maze[y][x]);
+ /* Remove the mine: */
Maze[y][x] = SPACE;
moved = TRUE;
break;
+ /* Moving into a bullet: */
case SHOT:
case GRENADE:
case SATCHEL:
case BOMB:
-# ifdef OOZE
case SLIME:
-# endif
-# ifdef DRONE
case DSHOT:
-# endif
+ /* Find which bullet: */
bp = is_bullet(y, x);
if (bp != NULL)
+ /* Detonate it: */
bp->b_expl = TRUE;
+ /* Remove it: */
Maze[y][x] = SPACE;
moved = TRUE;
break;
+ /* Moving into another player: */
case LEFTS:
case RIGHT:
case ABOVE:
case BELOW:
if (dir != pp->p_face)
+ /* Can't walk backwards/sideways into another player: */
sendcom(pp, BELL);
else {
+ /* Stab the other player */
newp = play_at(y, x);
- checkdam(newp, pp, pp->p_ident, STABDAM, KNIFE);
+ checkdam(newp, pp, pp->p_ident, conf_stabdam, KNIFE);
}
break;
-# ifdef FLY
+ /* Moving into a player flying overhead: */
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:
+ /* Picking up a boot, or two: */
case BOOT_PAIR:
- if (Maze[y][x] == BOOT)
- pp->p_nboots++;
- else
- pp->p_nboots += 2;
+ pp->p_nboots++;
+ case BOOT:
+ pp->p_nboots++;
for (newp = Boot; newp < &Boot[NBOOTS]; newp++) {
if (newp->p_flying < 0)
continue;
@@ -274,22 +285,27 @@ move_player(pp, dir)
Maze[y][x] = SPACE;
moved = TRUE;
break;
-# endif
}
+
+ /* Can the player be moved? */
if (moved) {
+ /* Check the gun status: */
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_ncshot == conf_maxncshot)
+ outyx(pp, STAT_GUN_ROW, STAT_VALUE_COL, " ok");
+ /* Check for bullets flying past: */
if (pp->p_undershot) {
fixshots(pp->p_y, pp->p_x, pp->p_over);
pp->p_undershot = FALSE;
}
+ /* Erase the player: */
drawplayer(pp, FALSE);
+ /* Save under: */
pp->p_over = Maze[y][x];
+ /* Move the player: */
pp->p_y = y;
pp->p_x = x;
+ /* Draw the player in their new position */
drawplayer(pp, TRUE);
}
}
@@ -320,44 +336,41 @@ fire(pp, req_index)
{
if (pp == NULL)
return;
-# ifdef DEBUG
- if (req_index < 0 || req_index >= MAXBOMB)
- message(pp, "What you do?");
-# endif
+
+ /* Drop the shot type down until we can afford it: */
while (req_index >= 0 && pp->p_ammo < shot_req[req_index])
req_index--;
+
+ /* Can we shoot at all? */
if (req_index < 0) {
message(pp, "Not enough charges.");
return;
}
- if (pp->p_ncshot > MAXNCSHOT)
+
+ /* Check if the gun is too hot: */
+ if (pp->p_ncshot > conf_maxncshot)
return;
- if (pp->p_ncshot++ == MAXNCSHOT) {
- cgoto(pp, STAT_GUN_ROW, STAT_VALUE_COL);
- outstr(pp, " ", 3);
+
+ /* Heat up the gun: */
+ if (pp->p_ncshot++ == conf_maxncshot) {
+ /* The gun has overheated: */
+ outyx(pp, STAT_GUN_ROW, STAT_VALUE_COL, " ");
}
+
+ /* Use up some ammo: */
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);
+ ammo_update(pp);
+ /* Start the bullet moving: */
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
- */
+ /* Show the bullet 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
+ sendcom(ALL_PLAYERS, REFRESH);
}
-# ifdef OOZE
/*
* fire_slime:
* Fire a slime shot in the given direction
@@ -369,43 +382,44 @@ fire_slime(pp, req_index)
{
if (pp == NULL)
return;
-# ifdef DEBUG
- if (req_index < 0 || req_index >= MAXSLIME)
- message(pp, "What you do?");
-# endif
+
+ /* Check configuration: */
+ if (!conf_ooze)
+ return;
+
+ /* Drop the slime type back util we can afford it: */
while (req_index >= 0 && pp->p_ammo < slime_req[req_index])
req_index--;
+
+ /* Can we afford to slime at all? */
if (req_index < 0) {
message(pp, "Not enough charges.");
return;
}
- if (pp->p_ncshot > MAXNCSHOT)
+
+ /* Is the gun too hot? */
+ if (pp->p_ncshot > conf_maxncshot)
return;
- if (pp->p_ncshot++ == MAXNCSHOT) {
- cgoto(pp, STAT_GUN_ROW, STAT_VALUE_COL);
- outstr(pp, " ", 3);
+
+ /* Heat up the gun: */
+ if (pp->p_ncshot++ == conf_maxncshot) {
+ /* The gun has overheated: */
+ outyx(pp, STAT_GUN_ROW, STAT_VALUE_COL, " ");
}
+
+ /* Use up some ammo: */
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);
+ ammo_update(pp);
+ /* Start the slime moving: */
add_shot(SLIME, pp->p_y, pp->p_x, pp->p_face,
- slime_req[req_index] * SLIME_FACTOR, pp, FALSE, pp->p_face);
+ slime_req[req_index] * conf_slimefactor, pp, FALSE, pp->p_face);
pp->p_undershot = TRUE;
- /*
- * Show the object to everyone
- */
+ /* 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
+ sendcom(ALL_PLAYERS, REFRESH);
}
-# endif
/*
* add_shot:
@@ -413,17 +427,18 @@ fire_slime(pp, req_index)
*/
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;
+ int type;
+ int y, x;
+ char face;
+ int charge;
+ PLAYER *owner;
+ int expl;
+ char over;
{
BULLET *bp;
int size;
+ /* Determine the bullet's size based on its type and charge: */
switch (type) {
case SHOT:
case MINE:
@@ -447,12 +462,20 @@ char over;
break;
}
+ /* Create the bullet: */
bp = create_shot(type, y, x, face, charge, size, owner,
(owner == NULL) ? NULL : owner->p_ident, expl, over);
+
+ /* Insert the bullet into the front of the bullet list: */
bp->b_next = Bullets;
Bullets = bp;
}
+/*
+ * create_shot:
+ * allocate storage for an (unlinked) bullet structure;
+ * initialize and return it
+ */
BULLET *
create_shot(type, y, x, face, charge, size, owner, score, expl, over)
int type;
@@ -469,6 +492,7 @@ create_shot(type, y, x, face, charge, size, owner, score, expl, over)
bp = (BULLET *) malloc(sizeof (BULLET)); /* NOSTRICT */
if (bp == NULL) {
+ syslog(LOG_ERR, "malloc: %m");
if (owner != NULL)
message(owner, "Out of memory");
return NULL;
@@ -497,25 +521,34 @@ static void
cloak(pp)
PLAYER *pp;
{
+ /* Check configuration: */
+ if (!conf_cloak)
+ return;
+
+ /* Can we afford it?: */
if (pp->p_ammo <= 0) {
message(pp, "No more charges");
return;
}
-# ifdef BOOTS
+
+ /* Can't cloak with 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;
+ /* Consume a unit of ammo: */
+ pp->p_ammo--;
+ ammo_update(pp);
+
+ /* Add to the duration of a cloak: */
+ pp->p_cloak += conf_cloaklen;
+ /* Disable scan, if enabled: */
if (pp->p_scan >= 0)
pp->p_scan = -1;
+ /* Re-draw the player's scan/cloak status: */
showstat(pp);
}
@@ -527,27 +560,36 @@ static void
scan(pp)
PLAYER *pp;
{
+ /* Check configuration: */
+ if (!conf_scan)
+ return;
+
+ /* Can we afford it?: */
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;
+ /* Consume one unit of ammo: */
+ pp->p_ammo--;
+ ammo_update(pp);
+
+ /* Increase the scan time: */
+ pp->p_scan += Nplayer * conf_scanlen;
+ /* Disable cloak, if enabled: */
if (pp->p_cloak >= 0)
pp->p_cloak = -1;
+ /* Re-draw the player's scan/cloak status: */
showstat(pp);
}
/*
* pickup:
- * check whether the object blew up or whether he picked it up
+ * pick up a mine or grenade, with some probability of it exploding
*/
-void
+static void
pickup(pp, y, x, prob, obj)
PLAYER *pp;
int y, x;
@@ -556,6 +598,7 @@ pickup(pp, y, x, prob, obj)
{
int req;
+ /* Figure out how much ammo the player is trying to pick up: */
switch (obj) {
case MINE:
req = BULREQ;
@@ -564,15 +607,27 @@ pickup(pp, y, x, prob, obj)
req = GRENREQ;
break;
default:
+#ifdef DIAGNOSTIC
abort();
+#endif
+ return;
}
+
+ /* Does it explode? */
if (rand_num(100) < prob)
+ /* Ooooh, unlucky: (Boom) */
add_shot(obj, y, x, LEFTS, req, (PLAYER *) NULL,
TRUE, pp->p_face);
else {
+ /* Safely picked it up. Add to player's ammo: */
pp->p_ammo += req;
- (void) sprintf(Buf, "%3d", pp->p_ammo);
- cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
- outstr(pp, Buf, 3);
+ ammo_update(pp);
}
}
+
+void
+ammo_update(pp)
+ PLAYER *pp;
+{
+ outyx(pp, STAT_AMMO_ROW, STAT_VALUE_COL - 1, "%4d", pp->p_ammo);
+}
diff --git a/games/hunt/huntd/expl.c b/games/hunt/huntd/expl.c
index 8de5adba1df..bf0eeea5bc0 100644
--- a/games/hunt/huntd/expl.c
+++ b/games/hunt/huntd/expl.c
@@ -1,15 +1,19 @@
+/* $OpenBSD: expl.c,v 1.3 1999/01/29 07:30:35 d Exp $ */
/* $NetBSD: expl.c,v 1.2 1997/10/10 16:33:18 lukem Exp $ */
-/* $OpenBSD: expl.c,v 1.2 1999/01/21 05:47:41 d Exp $ */
/*
* Hunt
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
* San Francisco, California
*/
-# include <stdlib.h>
-# include "hunt.h"
+#include <stdlib.h>
+#include <syslog.h>
+#include "hunt.h"
+#include "server.h"
+#include "conf.h"
static void remove_wall __P((int, int));
+static void init_removed __P((void));
/*
@@ -45,7 +49,6 @@ showexpl(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;
@@ -53,18 +56,13 @@ showexpl(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;
@@ -99,10 +97,8 @@ rollexpl()
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--)
@@ -110,12 +106,18 @@ rollexpl()
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 = NULL;
+static REGEN *rem_index = NULL;
-static REGEN removed[MAXREMOVE];
-static REGEN *rem_index = removed;
+static void
+init_removed()
+{
+ rem_index = removed = malloc(conf_maxremove * sizeof(REGEN));
+ if (rem_index == NULL) {
+ syslog(LOG_ERR, "malloc: %m");
+ cleanup(1);
+ }
+}
/*
* remove_wall - add a location where the wall was blown away.
@@ -127,16 +129,14 @@ remove_wall(y, x)
int y, x;
{
REGEN *r;
-# if defined(MONITOR) || defined(FLY)
PLAYER *pp;
-# endif
-# ifdef FLY
char save_char = 0;
-# endif
+
+ if (removed == NULL)
+ init_removed();
r = rem_index;
while (r->r_y != 0) {
-# ifdef FLY
switch (Maze[r->r_y][r->r_x]) {
case SPACE:
case LEFTS:
@@ -147,63 +147,51 @@ remove_wall(y, x)
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])
+ if (++r >= removed + conf_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 {
+ /* We throw the player off the wall: */
pp = play_at(r->r_y, r->r_x);
if (pp->p_flying >= 0)
- pp->p_flying += rand_num(10);
+ pp->p_flying += rand_num(conf_flytime / 2);
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_flying = rand_num(conf_flytime);
+ pp->p_flyx = 2 * rand_num(conf_flystep + 1) -
+ conf_flystep;
+ pp->p_flyy = 2 * rand_num(conf_flystep + 1) -
+ conf_flystep;
}
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)
+ if (conf_random && rand_num(100) < conf_prandom)
Maze[r->r_y][r->r_x] = DOOR;
-# endif
-# ifdef REFLECT
- if (rand_num(100) == 0) /* one percent of the time */
+ if (conf_reflect && rand_num(100) == conf_preflect)
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])
+ if (++r >= removed + conf_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
}
/*
@@ -215,7 +203,9 @@ clearwalls()
{
REGEN *rp;
- for (rp = removed; rp < &removed[MAXREMOVE]; rp++)
+ if (removed == NULL)
+ init_removed();
+ for (rp = removed; rp < removed + conf_maxremove; rp++)
rp->r_y = 0;
rem_index = removed;
}
diff --git a/games/hunt/huntd/extern.c b/games/hunt/huntd/extern.c
index 7bf4290e165..94cd82e1580 100644
--- a/games/hunt/huntd/extern.c
+++ b/games/hunt/huntd/extern.c
@@ -1,5 +1,5 @@
+/* $OpenBSD: extern.c,v 1.3 1999/01/29 07:30:35 d Exp $ */
/* $NetBSD: extern.c,v 1.2 1997/10/10 16:33:24 lukem Exp $ */
-/* $OpenBSD: extern.c,v 1.2 1999/01/21 05:47:41 d Exp $ */
/*
* Hunt
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
@@ -7,10 +7,9 @@
*/
# include "hunt.h"
+# include "server.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 */
@@ -33,18 +32,12 @@ 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,
diff --git a/games/hunt/huntd/faketalk.c b/games/hunt/huntd/faketalk.c
deleted file mode 100644
index 26365bc48fb..00000000000
--- a/games/hunt/huntd/faketalk.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/* $NetBSD: faketalk.c,v 1.4 1997/10/11 08:13:48 lukem Exp $ */
-/* $OpenBSD: faketalk.c,v 1.2 1999/01/21 05:47:41 d 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 "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;
-{
- (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, *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: stmp 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
diff --git a/games/hunt/huntd/get_names.c b/games/hunt/huntd/get_names.c
deleted file mode 100644
index c32461d2de8..00000000000
--- a/games/hunt/huntd/get_names.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/* $NetBSD: get_names.c,v 1.3 1998/07/06 07:00:31 mrg Exp $ */
-/* $OpenBSD: get_names.c,v 1.2 1999/01/21 05:47:41 d 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/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)
- 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
diff --git a/games/hunt/huntd/hunt.h b/games/hunt/huntd/hunt.h
index 0ecfa4a569b..fa8e083c89f 100644
--- a/games/hunt/huntd/hunt.h
+++ b/games/hunt/huntd/hunt.h
@@ -1,5 +1,5 @@
+/* $OpenBSD: hunt.h,v 1.3 1999/01/29 07:30:36 d Exp $ */
/* $NetBSD: hunt.h,v 1.5 1998/09/13 15:27:28 hubertf Exp $ */
-/* $OpenBSD: hunt.h,v 1.2 1999/01/21 05:47:41 d Exp $ */
/*
* Hunt
@@ -7,59 +7,13 @@
* San Francisco, California
*/
-# include "bsd.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 HUNT_VERSION (-1)
+# define HUNT_PORT (('h' << 8) | 't')
# define ADDCH ('a' | 0200)
# define MOVE ('m' | 0200)
@@ -72,59 +26,40 @@
# 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 SCREEN_HEIGHT 24
+# define SCREEN_WIDTH 80
+# define HEIGHT 23
+# define WIDTH 51
+# define SCREEN_WIDTH2 128 /* Next power of 2 >= SCREEN_WIDTH */
+# define WIDTH2 64 /* Next power of 2 >= WIDTH (for fast access) */
+
# define NAMELEN 20
-# define MSGLEN SCREEN_WIDTH
-# define DECAY 50.0
-# define NASCII 128
+# define Q_QUIT 0
+# define Q_CLOAK 1
+# define Q_FLY 2
+# define Q_SCAN 3
+# define Q_MESSAGE 4
-# 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 C_PLAYER 0
+# define C_MONITOR 1
+# define C_MESSAGE 2
+# define C_SCORES 3
+# define C_TESTMSG() (Query_driver ? C_MESSAGE :\
+ (Show_scores ? C_SCORES :\
+ (Am_monitor ? C_MONITOR :\
+ C_PLAYER)))
-# define SCREEN_HEIGHT 24
-# define SCREEN_WIDTH 80
-# define SCREEN_WIDTH2 128 /* Next power of 2 >= SCREEN_WIDTH */
+typedef int FLAG;
-# 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
+/* Objects within the maze: */
# define DOOR '#'
# define WALL1 '-'
# define WALL2 '|'
# define WALL3 '+'
-# ifdef REFLECT
# define WALL4 '/'
# define WALL5 '\\'
-# endif
# define KNIFE 'K'
# define SHOT ':'
# define GRENADE 'o'
@@ -132,324 +67,25 @@
# 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 isplayer(c) (c == LEFTS || c == RIGHT ||\
c == ABOVE || c == BELOW || c == FLYER)
-# else
-# define isplayer(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, *Driver;
-
-extern int errno, 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((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, char *, char));
-void get_local_name __P((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 *, 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 *, char *, int));
-int player_sym __P((PLAYER *, int, int));
-PLAYER *play_at __P((int, int));
-void playit __P((void));
-void put_ch __P((char));
-void put_str __P((char *));
-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));
diff --git a/games/hunt/huntd/huntd.6 b/games/hunt/huntd/huntd.6
index 984736b42d1..b991bcf4ff7 100644
--- a/games/hunt/huntd/huntd.6
+++ b/games/hunt/huntd/huntd.6
@@ -1,5 +1,5 @@
.\" $NetBSD: huntd.6,v 1.3 1998/01/09 08:03:42 perry Exp $
-.\" $OpenBSD: huntd.6,v 1.2 1999/01/21 05:47:41 d Exp $
+.\" $OpenBSD: huntd.6,v 1.3 1999/01/29 07:30:36 d Exp $
.\"
.\" Hunt
.\" Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
@@ -19,19 +19,12 @@
.Nm huntd
.Op Fl s
.Op Fl p Ar port
+.Op Fl a Ar addr
.Sh DESCRIPTION
.Nm huntd
controls the multi-player
.Xr hunt 6
game.
-When it starts up, it tries to notify all members of the
-.Pa hunt-players
-mailing list (see
-.Xr sendmail 8)
-by faking a
-.Xr talk 1
-request from user
-.Sq Hunt Game .
.Pp
The
.Fl s
@@ -44,12 +37,16 @@ This is similar to running it under the control of
but it consumes a process table entry when no one is playing.
.Pp
The
-.Fl p
+.Fl p Ar port
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
-.Pa hunt-players
-mailing list.
+.Pp
+The
+.Fl a Ar addr
+option is used to cause the server to bind to a specific interface address.
+The
+.Ar addr
+must be given as an IP address.
.Sh INETD
.Pp
To run
@@ -88,11 +85,120 @@ Otherwise, the
process starts up a
.Nm huntd
on the local machine and trys to rendezvous with it.
+.Pp
+Regardless of how
+.Nm huntd
+is started, it always checks incoming connections with
+.Xr host_access 5 ,
+using a service name of
+.Sq huntd .
+.Sh "CONFIGURATION"
+When
+.Nm huntd
+starts, it looks for configuration files that determine
+game parameters.
+Each line of a configuration file is of the form
+.Ar var No = Ar value .
+Comments start with a hash sign (`#').
+The configuration files loaded in order (if they exist) are:
+.Pa /etc/hunt.conf ,
+.Pa "$HOME/.hunt.conf" ,
+and
+.Pa ./.hunt.conf .
+.Pp
+Many of these variables require intimate knowledge of the
+driver source code.
+The complete list of configurable variables is:
+.Bl -tag -width pdroneabsorb -compact
+.It random
+enable dispersion doors (default 1)
+.It reflect
+enable generation of reflection walls (default 1)
+.It monitor
+enable monitors (default 1)
+.It ooze
+enable slime shots (default 1)
+.It fly
+enable flight (default 1)
+.It volcano
+enable volcanoes (default 1)
+.It drone
+enable drone (default 1)
+.It boots
+enable boots (default 1)
+.It scan
+enable scanning (default 1)
+.It cloak
+enable cloaking (default 1)
+.It logerr
+errors to stderr as well as syslog(8) (default 1)
+.It scoredecay
+nr deaths before nr kills begins to decay (default 15)
+.It maxremove
+Maximum number of holes in the maze wall (default 40)
+.It linger
+Seconds to keep game open with no players (default 90)
+.It flytime
+max time flying (default 20)
+.It flystep
+max displacement each flying time unit (default 5)
+.It volcano_max
+max size of volcano (default 50)
+.It ptrip_face
+chace of tripping a grenade on pickup, (default 2)
+.It ptrip_back
+\&" when backing onto it (default 95)
+.It ptrip_side
+\&" when walking sideways into it (default 50)
+.It prandom
+percentage of time dispersion doors appear (default 1)
+.It preflect
+percentage of time reflection walls appear (default 1)
+.It pshot_coll
+percent chance of shots colliding (default 5)
+.It pgren_coll
+percent chance of grenades colliding (default 10)
+.It pgren_catch
+facing player chance of catching grenade (default 10)
+.It pmiss
+chance of bullet missing player (default 5)
+.It pdroneabsorb
+chance of absorbing a drone (default 1)
+.It fall_frac
+divisor of damage used for fall damage (default 5)
+.It bulspd
+speed of bullets (default 5)
+.It ishots
+initial ammo for player (default 15)
+.It nshots
+ammo boost for all when new player joins (default 5)
+.It maxncshot
+max number of simultaneous shots per player (default 2)
+.It maxdam
+the initial shield for each player (default 10)
+.It mindam
+minimum damage from one unit of ammo (default 5)
+.It stabdam
+damage from stabbing (default 2)
+.It killgain
+shield gained from killing someone (default 2)
+.It slimefactor
+charge multiplier for slime (default 3)
+.It slimespeed
+speed of slime (default 5)
+.It lavaspeed
+speed of volcano lava (default 1)
+.It cloaklen
+duration of a cloak (default 20)
+.It scanlen
+duration of a scan (default 20)
+.It mindshot
+minimum shot class needed to make a drone (default 2)
+.El
.Sh "SEE ALSO"
.Xr hunt 6 ,
-.Xr talk 1 ,
-.Xr sendmaail 8 ,
-.Xr inetd 8
+.Xr inetd 8 ,
+.Xr hosts_options 5 .
.Sh AUTHORS
Conrad Huang, Ken Arnold, and Greg Couch;
.br
diff --git a/games/hunt/huntd/makemaze.c b/games/hunt/huntd/makemaze.c
index 508d0109ee0..6dd08dab7af 100644
--- a/games/hunt/huntd/makemaze.c
+++ b/games/hunt/huntd/makemaze.c
@@ -1,12 +1,14 @@
+/* $OpenBSD: makemaze.c,v 1.3 1999/01/29 07:30:36 d Exp $ */
/* $NetBSD: makemaze.c,v 1.2 1997/10/10 16:33:43 lukem Exp $ */
-/* $OpenBSD: makemaze.c,v 1.2 1999/01/21 05:47:42 d Exp $ */
/*
* Hunt
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
* San Francisco, California
*/
-# include "hunt.h"
+#include "hunt.h"
+#include "server.h"
+#include "conf.h"
# define ISCLEAR(y,x) (Maze[y][x] == SPACE)
# define ODD(n) ((n) & 01)
@@ -107,7 +109,7 @@ candig(y, x)
return TRUE; /* OK */
}
-void
+static void
dig_maze(x, y)
int x, y;
{
@@ -155,7 +157,7 @@ dig_maze(x, y)
}
}
-void
+static void
remap()
{
int y, x;
@@ -167,6 +169,7 @@ remap()
sp = &Maze[y][x];
if (*sp == SPACE)
continue;
+ /* Find occupied adjacent cells. */
stat = 0;
if (y - 1 >= 0 && Maze[y - 1][x] != SPACE)
stat |= NORTH;
@@ -180,25 +183,23 @@ remap()
case WEST | EAST:
case EAST:
case WEST:
- *sp = WALL1;
+ *sp = WALL1; /* - */
break;
case NORTH | SOUTH:
case NORTH:
case SOUTH:
- *sp = WALL2;
+ *sp = WALL2; /* | */
break;
case 0:
-# ifdef RANDOM
- *sp = DOOR;
-# endif
-# ifdef REFLECT
- *sp = rand_num(2) ? WALL4 : WALL5;
-# endif
+ if (conf_random)
+ *sp = DOOR;
+ if (conf_reflect)
+ *sp = rand_num(2) ? WALL4 : WALL5;
break;
default:
- *sp = WALL3;
+ *sp = WALL3; /* + */
break;
}
}
- memcpy(Orig_maze, Maze, sizeof Maze);
+ memcpy(Orig_maze, Maze, sizeof Orig_maze);
}
diff --git a/games/hunt/huntd/pathname.c b/games/hunt/huntd/pathname.c
deleted file mode 100644
index d4ed5b2ada6..00000000000
--- a/games/hunt/huntd/pathname.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/* $NetBSD: pathname.c,v 1.2 1997/10/10 16:33:49 lukem Exp $ */
-/* $OpenBSD: pathname.c,v 1.2 1999/01/21 05:47:42 d Exp $ */
-/*
- * Hunt
- * Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
- * San Francisco, California
- */
-
-/*
- * 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
-
-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
diff --git a/games/hunt/huntd/server.h b/games/hunt/huntd/server.h
new file mode 100644
index 00000000000..b6c79f952df
--- /dev/null
+++ b/games/hunt/huntd/server.h
@@ -0,0 +1,239 @@
+/* $OpenBSD: server.h,v 1.1 1999/01/29 07:30:36 d Exp $ */
+/* $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 <stdio.h>
+
+/*
+ * 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).
+ */
+#define MAXPL 14
+#define MAXMON 2
+#if (MAXPL + MAXMON > 16)
+#warning "MAXPL + MAXMON is excessive"
+#endif
+
+#define MSGLEN SCREEN_WIDTH
+
+#define UBOUND 1
+#define DBOUND (HEIGHT - 1)
+#define LBOUND 1
+#define RBOUND (WIDTH - 1)
+
+#define NASCII 128
+
+/* Layout of the scoreboard: */
+#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
+#define STAT_MON_ROW (STAT_PLAY_ROW + MAXPL + 1)
+#define STAT_NAME_LEN 18
+
+/* Number of boots: */
+#define NBOOTS 2
+
+/* Bitmask of directions */
+#define NORTH 01
+#define SOUTH 02
+#define EAST 010
+#define WEST 020
+
+# undef CTRL
+#define CTRL(x) ((x) & 037)
+
+#define BULREQ 1 /* 0 */
+#define GRENREQ 9 /* 1 */
+#define SATREQ 25 /* 2 */
+#define BOMB7REQ 49 /* 3 */
+#define BOMB9REQ 81 /* 4 */
+#define BOMB11REQ 121 /* 5 */
+#define BOMB13REQ 169 /* 6 */
+#define BOMB15REQ 225 /* 7 */
+#define BOMB17REQ 289 /* 8 */
+#define BOMB19REQ 361 /* 9 */
+#define BOMB21REQ 441 /* 10 */
+#define MAXBOMB 11
+
+#define SLIMEREQ 5 /* 0 */
+#define SSLIMEREQ 10 /* 1 */
+#define SLIME2REQ 15 /* 2 */
+#define SLIME3REQ 20 /* 3 */
+#define MAXSLIME 4
+
+#define EXPLEN 16
+
+#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)
+
+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;
+
+#define ALL_PLAYERS ((PLAYER *)1)
+
+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;
+ int p_flying;
+ int p_flyx, p_flyy;
+ int p_nboots;
+ 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;
+};
+
+extern int Socket;
+
+/* answer.c */
+int answer __P((void));
+int rand_dir __P((void));
+
+/* draw.c */
+void drawmaze __P((PLAYER *));
+void look __P((PLAYER *));
+void check __P((PLAYER *, int, int));
+void showstat __P((PLAYER *));
+void drawplayer __P((PLAYER *, FLAG));
+void message __P((PLAYER *, char *));
+
+/* driver.c */
+int rand_num __P((int));
+void checkdam __P((PLAYER *, PLAYER *, IDENT *, int, char));
+void cleanup __P((int));
+
+/* execute.c */
+void mon_execute __P((PLAYER *));
+void execute __P((PLAYER *));
+void add_shot __P((int, int, int, char, int, PLAYER *, int, char));
+BULLET *create_shot __P((int, int, int, char, int, int, PLAYER *, IDENT *,
+ int, char));
+void ammo_update __P((PLAYER *));
+
+/* expl.c */
+void showexpl __P((int, int, char));
+void rollexpl __P((void));
+void makemaze __P((void));
+void clearwalls __P((void));
+
+/* makemaze.c */
+void makemaze __P((void));
+
+/* shots.c */
+void moveshots __P((void));
+PLAYER *play_at __P((int, int));
+int opposite __P((int, char));
+BULLET *is_bullet __P((int, int));
+void fixshots __P((int, int, char));
+
+/* terminal.c */
+void cgoto __P((PLAYER *, int, int));
+void outch __P((PLAYER *, char));
+void outstr __P((PLAYER *, char *, int));
+void outyx __P((PLAYER *, int, int, const char *, ...))
+ __attribute__((format (printf, 4, 5)));
+void clrscr __P((PLAYER *));
+void ce __P((PLAYER *));
+void sendcom __P((PLAYER *, int, ...));
+void flush __P((PLAYER *));
+
+/* extern.c */
+extern FLAG Am_monitor;
+extern char Buf[BUFSIZ];
+extern char Maze[HEIGHT][WIDTH2];
+extern char Orig_maze[HEIGHT][WIDTH2];
+extern fd_set Fds_mask;
+extern fd_set Have_inp;
+extern int Nplayer;
+extern int Num_fds;
+extern int Socket;
+extern int Status;
+extern int See_over[NASCII];
+extern BULLET * Bullets;
+extern EXPL * Expl[EXPLEN];
+extern EXPL * Last_expl;
+extern PLAYER Player[MAXPL];
+extern PLAYER * End_player;
+extern PLAYER Boot[NBOOTS];
+extern IDENT * Scores;
+extern PLAYER Monitor[MAXMON];
+extern PLAYER * End_monitor;
+extern int volcano;
+extern int shot_req[MAXBOMB];
+extern int shot_type[MAXBOMB];
+extern int slime_req[MAXSLIME];
diff --git a/games/hunt/huntd/shots.c b/games/hunt/huntd/shots.c
index 18305c845ee..9e06c95d585 100644
--- a/games/hunt/huntd/shots.c
+++ b/games/hunt/huntd/shots.c
@@ -1,18 +1,21 @@
+/* $OpenBSD: shots.c,v 1.3 1999/01/29 07:30:36 d Exp $ */
/* $NetBSD: shots.c,v 1.3 1997/10/11 08:13:50 lukem Exp $ */
-/* $OpenBSD: shots.c,v 1.2 1999/01/21 05:47:42 d Exp $ */
/*
* Hunt
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
* San Francisco, California
*/
-# include <err.h>
-# include <signal.h>
-# include <stdlib.h>
-# include "hunt.h"
+#include <err.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <syslog.h>
+#include "hunt.h"
+#include "conf.h"
+#include "server.h"
-# define PLUS_DELTA(x, max) if (x < max) x++; else x--
-# define MINUS_DELTA(x, min) if (x > min) x--; else x++
+#define PLUS_DELTA(x, max) if (x < max) x++; else x--
+#define MINUS_DELTA(x, min) if (x > min) x--; else x++
static void chkshot __P((BULLET *, BULLET *));
static void chkslime __P((BULLET *, BULLET *));
@@ -21,9 +24,7 @@ static void find_under __P((BULLET *, BULLET *));
static int iswall __P((int, int));
static void mark_boot __P((BULLET *));
static void mark_player __P((BULLET *));
-#ifdef DRONE
-static void move_drone __P((BULLET *));
-#endif
+static int move_drone __P((BULLET *));
static void move_flyer __P((PLAYER *));
static int move_normal_shot __P((BULLET *));
static void move_slime __P((BULLET *, int, BULLET *));
@@ -44,114 +45,130 @@ moveshots()
rollexpl();
if (Bullets == NULL)
- goto ret;
+ goto no_bullets;
/*
- * First we move through the bullet list BULSPD times, looking
+ * First we move through the bullet list conf_bulspd times, looking
* for things we may have run into. If we do run into
* something, we set up the explosion and disappear, checking
* for damage to any player who got in the way.
*/
+ /* Move the list to a working list */
blist = Bullets;
Bullets = NULL;
+
+ /* Work with bullets on the working list (blist) */
for (bp = blist; bp != NULL; bp = next) {
next = bp->b_next;
+
x = bp->b_x;
y = bp->b_y;
+
+ /* Un-draw the bullet on all screens: */
Maze[y][x] = bp->b_over;
- for (pp = Player; pp < End_player; pp++)
- check(pp, y, x);
-# ifdef MONITOR
- for (pp = Monitor; pp < End_monitor; pp++)
- check(pp, y, x);
-# endif
+ check(ALL_PLAYERS, y, x);
+ /* Decide how to move the bullet: */
switch (bp->b_type) {
+
+ /* Normal, atomic bullets: */
case SHOT:
case GRENADE:
case SATCHEL:
case BOMB:
if (move_normal_shot(bp)) {
+ /* Still there: put back on the active list */
bp->b_next = Bullets;
Bullets = bp;
}
break;
-# ifdef OOZE
+
+ /* Slime bullets that explode into slime on impact: */
case SLIME:
if (bp->b_expl || move_normal_shot(bp)) {
+ /* Still there: put back on the active list */
bp->b_next = Bullets;
Bullets = bp;
}
break;
-# endif
-# ifdef DRONE
+
+ /* Drones that wander about: */
case DSHOT:
if (move_drone(bp)) {
+ /* Still there: put back on the active list */
bp->b_next = Bullets;
Bullets = bp;
}
break;
-# endif
+
+ /* Other/unknown: */
default:
+ /* Place it back on the active list: */
bp->b_next = Bullets;
Bullets = bp;
break;
}
}
+ /* Again, hang the Bullets list off `blist' and work with that: */
blist = Bullets;
Bullets = NULL;
for (bp = blist; bp != NULL; bp = next) {
next = bp->b_next;
+ /* Is the bullet exploding? */
if (!bp->b_expl) {
+ /*
+ * Its still flying through the air.
+ * Put it back on the bullet list.
+ */
save_bullet(bp);
-# ifdef MONITOR
+
+ /* All the monitors can see the bullet: */
for (pp = Monitor; pp < End_monitor; pp++)
check(pp, bp->b_y, bp->b_x);
-# endif
-# ifdef DRONE
+
+ /* All the scanning players can see the drone: */
if (bp->b_type == DSHOT)
for (pp = Player; pp < End_player; pp++)
if (pp->p_scan >= 0)
check(pp, bp->b_y, bp->b_x);
-# endif
- continue;
+ } else {
+ /* It is exploding. Check what we hit: */
+ chkshot(bp, next);
+ /* Release storage for the destroyed bullet: */
+ free(bp);
}
-
- chkshot(bp, next);
- free((char *) bp);
}
+ /* Re-draw all the players: (in case a bullet wiped them out) */
for (pp = Player; pp < End_player; pp++)
Maze[pp->p_y][pp->p_x] = pp->p_face;
-ret:
-# ifdef BOOTS
+no_bullets:
+
+ /* Move flying boots through the air: */
for (pp = Boot; pp < &Boot[NBOOTS]; pp++)
if (pp->p_flying >= 0)
move_flyer(pp);
-# endif
+
+ /* Move flying players through the air: */
for (pp = Player; pp < End_player; pp++) {
-# ifdef FLY
if (pp->p_flying >= 0)
move_flyer(pp);
-# endif
- sendcom(pp, REFRESH); /* Flush out the explosions */
- look(pp);
+ /* Flush out the explosions: */
sendcom(pp, REFRESH);
+ look(pp);
}
-# ifdef MONITOR
- for (pp = Monitor; pp < End_monitor; pp++)
- sendcom(pp, REFRESH);
-# endif
- return;
+ /* Flush out and synchronise all the displays: */
+ sendcom(ALL_PLAYERS, REFRESH);
}
/*
* move_normal_shot:
- * Move a normal shot along its trajectory
+ * Move a normal shot along its trajectory.
+ * Returns false if the bullet no longer needs tracking.
*/
static int
move_normal_shot(bp)
@@ -160,13 +177,21 @@ move_normal_shot(bp)
int i, x, y;
PLAYER *pp;
- for (i = 0; i < BULSPD; i++) {
+ /*
+ * Walk an unexploded bullet along conf_bulspd times, moving it
+ * one unit along each step. We flag it as exploding if it
+ * meets something.
+ */
+
+ for (i = 0; i < conf_bulspd; i++) {
+
+ /* Stop if the bullet has already exploded: */
if (bp->b_expl)
break;
+ /* Adjust the bullet's co-ordinates: */
x = bp->b_x;
y = bp->b_y;
-
switch (bp->b_face) {
case LEFTS:
x--;
@@ -182,21 +207,25 @@ move_normal_shot(bp)
break;
}
+
+ /* Look at what the bullet is colliding with : */
switch (Maze[y][x]) {
+ /* Gun shots have a chance of collision: */
case SHOT:
- if (rand_num(100) < 5) {
+ if (rand_num(100) < conf_pshot_coll) {
zapshot(Bullets, bp);
zapshot(bp->b_next, bp);
}
break;
+ /* Grenades only have a chance of collision: */
case GRENADE:
- if (rand_num(100) < 10) {
+ if (rand_num(100) < conf_pgren_coll) {
zapshot(Bullets, bp);
zapshot(bp->b_next, bp);
}
break;
-# ifdef REFLECT
- case WALL4: /* reflecting walls */
+ /* Reflecting walls richochet the bullet: */
+ case WALL4:
switch (bp->b_face) {
case LEFTS:
bp->b_face = BELOW;
@@ -212,10 +241,8 @@ move_normal_shot(bp)
break;
}
Maze[y][x] = WALL5;
-# ifdef MONITOR
for (pp = Monitor; pp < End_monitor; pp++)
check(pp, y, x);
-# endif
break;
case WALL5:
switch (bp->b_face) {
@@ -233,13 +260,10 @@ move_normal_shot(bp)
break;
}
Maze[y][x] = WALL4;
-# ifdef MONITOR
for (pp = Monitor; pp < End_monitor; pp++)
check(pp, y, x);
-# endif
break;
-# endif
-# ifdef RANDOM
+ /* Dispersion doors randomly disperse bullets: */
case DOOR:
switch (rand_num(4)) {
case 0:
@@ -256,72 +280,103 @@ move_normal_shot(bp)
break;
}
break;
-# endif
-# ifdef FLY
+ /* Bullets zing past fliers: */
case FLYER:
pp = play_at(y, x);
message(pp, "Zing!");
break;
-# endif
+ /* Bullets encountering a player: */
case LEFTS:
case RIGHT:
case BELOW:
case ABOVE:
/*
- * give the person a chance to catch a
- * grenade if s/he is facing it
+ * Give the person a chance to catch a
+ * grenade if s/he is facing it:
*/
pp = play_at(y, x);
pp->p_ident->i_shot += bp->b_charge;
if (opposite(bp->b_face, Maze[y][x])) {
- if (rand_num(100) < 10) {
+ /* Give them a 10% chance: */
+ if (rand_num(100) < conf_pgren_catch) {
+ /* They caught it! */
if (bp->b_owner != NULL)
message(bp->b_owner,
"Your charge was absorbed!");
+
+ /*
+ * The target player stole from the bullet's
+ * owner. Charge stolen statistics:
+ */
if (bp->b_score != NULL)
bp->b_score->i_robbed += bp->b_charge;
+
+ /* They acquire more ammo: */
pp->p_ammo += bp->b_charge;
- if (pp->p_damage + bp->b_size * MINDAM
+
+ /* Check if it would have destroyed them: */
+ if (pp->p_damage + bp->b_size * conf_mindam
> pp->p_damcap)
+ /* Lucky escape statistics: */
pp->p_ident->i_saved++;
+
+ /* Tell them: */
message(pp, "Absorbed charge (good shield!)");
+
+ /* Absorbtion statistics: */
pp->p_ident->i_absorbed += bp->b_charge;
+
+ /* Deallocate storage: */
free((char *) bp);
- (void) sprintf(Buf, "%3d", pp->p_ammo);
- cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
- outstr(pp, Buf, 3);
+
+ /* Update ammo display: */
+ ammo_update(pp);
+
+ /* No need for caller to keep tracking it: */
return FALSE;
}
+
+ /* Bullets faced head-on (statistics): */
pp->p_ident->i_faced += bp->b_charge;
}
+
/*
* Small chance that the bullet just misses the
* person. If so, the bullet just goes on its
- * merry way without exploding.
+ * merry way without exploding. (5% chance)
*/
- if (rand_num(100) < 5) {
+ if (rand_num(100) < conf_pmiss) {
+ /* Ducked statistics: */
pp->p_ident->i_ducked += bp->b_charge;
- if (pp->p_damage + bp->b_size * MINDAM
+
+ /* Check if it would have killed them: */
+ if (pp->p_damage + bp->b_size * conf_mindam
> pp->p_damcap)
+ /* Lucky escape statistics: */
pp->p_ident->i_saved++;
+
+ /* Shooter missed statistics: */
if (bp->b_score != NULL)
bp->b_score->i_missed += bp->b_charge;
+
+ /* Tell target that they were missed: */
message(pp, "Zing!");
- if (bp->b_owner == NULL)
- break;
- message(bp->b_owner,
+
+ /* Tell the bullet owner they missed: */
+ if (bp->b_owner != NULL)
+ message(bp->b_owner,
((bp->b_score->i_missed & 0x7) == 0x7) ?
"My! What a bad shot you are!" :
"Missed him");
+
+ /* Don't fall through */
break;
+ } else {
+ /* The player is to be blown up: */
+ bp->b_expl = TRUE;
}
- /*
- * The shot hit that sucker! Blow it up.
- */
- /* FALLTHROUGH */
-# ifndef RANDOM
- case DOOR:
-# endif
+ break;
+ /* Bullet hits a wall, and always explodes: */
case WALL1:
case WALL2:
case WALL3:
@@ -329,28 +384,29 @@ move_normal_shot(bp)
break;
}
+ /* Update the bullet's new position: */
bp->b_x = x;
bp->b_y = y;
}
+
+ /* Caller should keep tracking the bullet: */
return TRUE;
}
-# ifdef DRONE
/*
* move_drone:
* Move the drone to the next square
+ * Returns FALSE if the drone need no longer be tracked.
*/
-static void
+static int
move_drone(bp)
BULLET *bp;
{
int mask, count;
- int n, dir;
+ int n, dir = -1;
PLAYER *pp;
- /*
- * See if we can give someone a blast
- */
+ /* See if we can give someone a blast: */
if (isplayer(Maze[bp->b_y][bp->b_x - 1])) {
dir = WEST;
goto drone_move;
@@ -368,9 +424,7 @@ move_drone(bp)
goto drone_move;
}
- /*
- * Find out what directions are clear
- */
+ /* Find out what directions are clear and move that way: */
mask = count = 0;
if (!iswall(bp->b_y, bp->b_x - 1))
mask |= WEST, count++;
@@ -381,23 +435,17 @@ move_drone(bp)
if (!iswall(bp->b_y, bp->b_x + 1))
mask |= EAST, count++;
- /*
- * All blocked up, just you wait
- */
+ /* All blocked up, just wait: */
if (count == 0)
return TRUE;
- /*
- * Only one way to go.
- */
+ /* Only one way to go: */
if (count == 1) {
dir = mask;
goto drone_move;
}
- /*
- * Get rid of the direction that we came from
- */
+ /* Avoid backtracking, and remove the direction we came from: */
switch (bp->b_face) {
case LEFTS:
if (mask & EAST)
@@ -417,9 +465,7 @@ move_drone(bp)
break;
}
- /*
- * Pick one of the remaining directions
- */
+ /* Pick one of the remaining directions: */
n = rand_num(count);
if (n >= 0 && mask & NORTH)
dir = NORTH, n--;
@@ -430,12 +476,11 @@ move_drone(bp)
if (n >= 0 && mask & WEST)
dir = WEST, n--;
- /*
- * Now that we know the direction of movement,
- * just update the position of the drone
- */
drone_move:
+ /* Move the drone: */
switch (dir) {
+ case -1:
+ /* no move */
case WEST:
bp->b_x--;
bp->b_face = LEFTS;
@@ -453,81 +498,91 @@ drone_move:
bp->b_face = BELOW;
break;
}
+
+ /* Look at what the drone moved onto: */
switch (Maze[bp->b_y][bp->b_x]) {
case LEFTS:
case RIGHT:
case BELOW:
case ABOVE:
/*
- * give the person a chance to catch a
- * drone if s/he is facing it
+ * Players have a 1% chance of absorbing a drone,
+ * if they are facing it.
*/
- if (rand_num(100) < 1 &&
- opposite(bp->b_face, Maze[bp->b_y][bp->b_x])) {
+ if (rand_num(100) < conf_pdroneabsorb && opposite(bp->b_face,
+ Maze[bp->b_y][bp->b_x])) {
+
+ /* Feel the power: */
pp = play_at(bp->b_y, bp->b_x);
pp->p_ammo += bp->b_charge;
message(pp, "**** Absorbed drone ****");
+
+ /* Release drone storage: */
free((char *) bp);
- (void) sprintf(Buf, "%3d", pp->p_ammo);
- cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
- outstr(pp, Buf, 3);
+
+ /* Update ammo: */
+ ammo_update(pp);
+
+ /* No need for caller to keep tracking drone: */
return FALSE;
}
+ /* Detonate the drone: */
bp->b_expl = TRUE;
break;
}
+
+ /* Keep tracking the drone. */
return TRUE;
}
-# endif
/*
* save_bullet:
- * Put this bullet back onto the bullet list
+ * Put a bullet back onto the bullet list
*/
static void
save_bullet(bp)
BULLET *bp;
{
+
+ /* Save what the bullet will be flying over: */
bp->b_over = Maze[bp->b_y][bp->b_x];
+
switch (bp->b_over) {
+ /* Bullets that can pass through each other: */
case SHOT:
case GRENADE:
case SATCHEL:
case BOMB:
-# ifdef OOZE
case SLIME:
-# ifdef VOLCANO
case LAVA:
-# endif
-# endif
-# ifdef DRONE
case DSHOT:
-# endif
find_under(Bullets, bp);
break;
}
switch (bp->b_over) {
+ /* A bullet hits a player: */
case LEFTS:
case RIGHT:
case ABOVE:
case BELOW:
-# ifdef FLY
case FLYER:
-# endif
mark_player(bp);
break;
-# ifdef BOOTS
+
+ /* A bullet passes a boot: */
case BOOT:
case BOOT_PAIR:
mark_boot(bp);
-# endif
+ /* FALLTHROUGH */
+ /* The bullet flies over everything else: */
default:
Maze[bp->b_y][bp->b_x] = bp->b_type;
break;
}
+ /* Insert the bullet into the Bullets list: */
bp->b_next = Bullets;
Bullets = bp;
}
@@ -546,9 +601,15 @@ move_flyer(pp)
fixshots(pp->p_y, pp->p_x, pp->p_over);
pp->p_undershot = FALSE;
}
+
+ /* Restore what the flier was flying over */
Maze[pp->p_y][pp->p_x] = pp->p_over;
+
+ /* Fly: */
x = pp->p_x + pp->p_flyx;
y = pp->p_y + pp->p_flyy;
+
+ /* Bouncing off the edges of the maze: */
if (x < 1) {
x = 1 - x;
pp->p_flyx = -pp->p_flyx;
@@ -565,9 +626,16 @@ move_flyer(pp)
y = (HEIGHT - 2) - (y - (HEIGHT - 2));
pp->p_flyy = -pp->p_flyy;
}
+
+ /* Make sure we don't land on something we can't: */
again:
switch (Maze[y][x]) {
default:
+ /*
+ * Flier is over something other than space, a wall
+ * or a door. Randomly move (drift) the flier a little bit
+ * and then try again:
+ */
switch (rand_num(4)) {
case 0:
PLUS_DELTA(x, WIDTH - 2);
@@ -583,42 +651,45 @@ again:
break;
}
goto again;
+ /* Give a little boost when about to land on a wall or door: */
case WALL1:
case WALL2:
case WALL3:
-# ifdef REFLECT
case WALL4:
case WALL5:
-# endif
-# ifdef RANDOM
case DOOR:
-# endif
if (pp->p_flying == 0)
pp->p_flying++;
break;
+ /* Spaces are okay: */
case SPACE:
break;
}
+
+ /* Update flier's coordinates: */
pp->p_y = y;
pp->p_x = x;
+
+ /* Consume 'flying' time: */
if (pp->p_flying-- == 0) {
-# ifdef BOOTS
+ /* Land: */
if (pp->p_face != BOOT && pp->p_face != BOOT_PAIR) {
-# endif
+ /* Land a player - they stustain a fall: */
checkdam(pp, (PLAYER *) NULL, (IDENT *) NULL,
- rand_num(pp->p_damage / 5), FALL);
+ rand_num(pp->p_damage / conf_fall_frac), FALL);
pp->p_face = rand_dir();
showstat(pp);
-# ifdef BOOTS
- }
- else {
+ } else {
+ /* Land boots: */
if (Maze[y][x] == BOOT)
pp->p_face = BOOT_PAIR;
Maze[y][x] = SPACE;
}
-# endif
}
+
+ /* Save under the flier: */
pp->p_over = Maze[y][x];
+ /* Draw in the flier: */
Maze[y][x] = pp->p_face;
showexpl(y, x, pp->p_face);
}
@@ -648,27 +719,24 @@ chkshot(bp, next)
case BOMB:
delta = bp->b_size - 1;
break;
-# ifdef OOZE
case SLIME:
-# ifdef VOLCANO
case LAVA:
-# endif
chkslime(bp, next);
return;
-# endif
-# ifdef DRONE
case DSHOT:
bp->b_type = SLIME;
chkslime(bp, next);
return;
-# endif
}
+
+ /* Draw the explosion square: */
for (y = bp->b_y - delta; y <= bp->b_y + delta; y++) {
if (y < 0 || y >= HEIGHT)
continue;
dy = y - bp->b_y;
absdy = (dy < 0) ? -dy : dy;
for (x = bp->b_x - delta; x <= bp->b_x + delta; x++) {
+ /* Draw a part of the explosion cloud: */
if (x < 0 || x >= WIDTH)
continue;
dx = x - bp->b_x;
@@ -683,26 +751,29 @@ chkshot(bp, next)
else
expl = '*';
showexpl(y, x, expl);
+
+ /* Check what poor bastard was in the explosion: */
switch (Maze[y][x]) {
case LEFTS:
case RIGHT:
case ABOVE:
case BELOW:
-# ifdef FLY
case FLYER:
-# endif
if (dx < 0)
dx = -dx;
if (absdy > dx)
damage = bp->b_size - absdy;
else
damage = bp->b_size - dx;
+
+ /* Everybody hurts, sometimes. */
pp = play_at(y, x);
checkdam(pp, bp->b_owner, bp->b_score,
- damage * MINDAM, bp->b_type);
+ damage * conf_mindam, bp->b_type);
break;
case GMINE:
case MINE:
+ /* Mines detonate in a chain reaction: */
add_shot((Maze[y][x] == GMINE) ?
GRENADE : SHOT,
y, x, LEFTS,
@@ -716,7 +787,6 @@ chkshot(bp, next)
}
}
-# ifdef OOZE
/*
* chkslime:
* handle slime shot exploding
@@ -729,16 +799,13 @@ chkslime(bp, next)
BULLET *nbp;
switch (Maze[bp->b_y][bp->b_x]) {
+ /* Slime explodes on walls and doors: */
case WALL1:
case WALL2:
case WALL3:
-# ifdef REFLECT
case WALL4:
case WALL5:
-# endif
-# ifdef RANDOM
case DOOR:
-# endif
switch (bp->b_face) {
case LEFTS:
bp->b_x++;
@@ -755,13 +822,18 @@ chkslime(bp, next)
}
break;
}
+
+ /* Duplicate the unit of slime: */
nbp = (BULLET *) malloc(sizeof (BULLET));
+ if (nbp == NULL) {
+ syslog(LOG_ERR, "malloc: %m");
+ return;
+ }
*nbp = *bp;
-# ifdef VOLCANO
- move_slime(nbp, nbp->b_type == SLIME ? SLIMESPEED : LAVASPEED, next);
-# else
- move_slime(nbp, SLIMESPEED, next);
-# endif
+
+ /* Move it around: */
+ move_slime(nbp, nbp->b_type == SLIME ? conf_slimespeed :
+ conf_lavaspeed, next);
}
/*
@@ -769,7 +841,7 @@ chkslime(bp, next)
* move the given slime shot speed times and add it back if
* it hasn't fizzled yet
*/
-void
+static void
move_slime(bp, speed, next)
BULLET *bp;
int speed;
@@ -787,40 +859,40 @@ move_slime(bp, speed, next)
return;
}
-# ifdef VOLCANO
+ /* Draw it: */
showexpl(bp->b_y, bp->b_x, bp->b_type == LAVA ? LAVA : '*');
-# else
- showexpl(bp->b_y, bp->b_x, '*');
-# endif
+
switch (Maze[bp->b_y][bp->b_x]) {
+ /* Someone got hit by slime or lava: */
case LEFTS:
case RIGHT:
case ABOVE:
case BELOW:
-# ifdef FLY
case FLYER:
-# endif
pp = play_at(bp->b_y, bp->b_x);
message(pp, "You've been slimed.");
- checkdam(pp, bp->b_owner, bp->b_score, MINDAM, bp->b_type);
+ checkdam(pp, bp->b_owner, bp->b_score, conf_mindam, bp->b_type);
break;
+ /* Bullets detonate in slime and lava: */
case SHOT:
case GRENADE:
case SATCHEL:
case BOMB:
-# ifdef DRONE
case DSHOT:
-# endif
explshot(next, bp->b_y, bp->b_x);
explshot(Bullets, bp->b_y, bp->b_x);
break;
}
+
+ /* Drain the slime/lava of some energy: */
if (--bp->b_charge <= 0) {
- free((char *) bp);
+ /* It fizzled: */
+ free(bp);
return;
}
+ /* Figure out which way the slime should flow: */
dirmask = 0;
count = 0;
switch (bp->b_face) {
@@ -892,6 +964,7 @@ move_slime(bp, speed, next)
}
}
+ /* Spawn little slimes off in every possible direction: */
i = bp->b_charge / count;
j = bp->b_charge % count;
if (dirmask & WEST) {
@@ -939,24 +1012,15 @@ iswall(y, x)
case WALL1:
case WALL2:
case WALL3:
-# ifdef REFLECT
case WALL4:
case WALL5:
-# endif
-# ifdef RANDOM
case DOOR:
-# endif
-# ifdef OOZE
case SLIME:
-# ifdef VOLCANO
case LAVA:
-# endif
-# endif
return TRUE;
}
return FALSE;
}
-# endif
/*
* zapshot:
@@ -967,27 +1031,24 @@ zapshot(blist, obp)
BULLET *blist, *obp;
{
BULLET *bp;
- FLAG explode;
- explode = FALSE;
for (bp = blist; bp != NULL; bp = bp->b_next) {
- if (bp->b_x != obp->b_x || bp->b_y != obp->b_y)
- continue;
- if (bp->b_face == obp->b_face)
- continue;
- explode = TRUE;
- break;
+ /* Find co-located bullets not facing the same way: */
+ if (bp->b_face != obp->b_face
+ && bp->b_x == obp->b_x && bp->b_y == obp->b_y)
+ {
+ /* Bullet collision: */
+ explshot(blist, obp->b_y, obp->b_x);
+ return;
+ }
}
- if (!explode)
- return;
- explshot(blist, obp->b_y, obp->b_x);
}
/*
* explshot -
* Make all shots at this location blow up
*/
-void
+static void
explshot(blist, y, x)
BULLET *blist;
int y, x;
@@ -998,7 +1059,7 @@ explshot(blist, y, x)
if (bp->b_x == x && bp->b_y == y) {
bp->b_expl = TRUE;
if (bp->b_owner != NULL)
- message(bp->b_owner, "Shot intercepted");
+ message(bp->b_owner, "Shot intercepted.");
}
}
@@ -1015,8 +1076,10 @@ play_at(y, x)
for (pp = Player; pp < End_player; pp++)
if (pp->p_x == x && pp->p_y == y)
return pp;
- errx(1, "driver: couldn't find player at (%d,%d)", x, y);
- /* NOTREACHED */
+
+ /* Internal fault: */
+ syslog(LOG_ERR, "play_at: not a player");
+ abort();
}
/*
@@ -1112,7 +1175,6 @@ mark_player(bp)
}
}
-# ifdef BOOTS
/*
* mark_boot:
* mark a boot as under a shot
@@ -1129,4 +1191,3 @@ mark_boot(bp)
break;
}
}
-# endif
diff --git a/games/hunt/huntd/talk_ctl.h b/games/hunt/huntd/talk_ctl.h
deleted file mode 100644
index abd2f484ea0..00000000000
--- a/games/hunt/huntd/talk_ctl.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* $NetBSD: talk_ctl.h,v 1.4 1998/01/09 08:03:42 perry Exp $ */
-/* $OpenBSD: talk_ctl.h,v 1.2 1999/01/21 05:47:42 d 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 *));
diff --git a/games/hunt/huntd/terminal.c b/games/hunt/huntd/terminal.c
index f1bab1368db..0b7efdd88b6 100644
--- a/games/hunt/huntd/terminal.c
+++ b/games/hunt/huntd/terminal.c
@@ -1,18 +1,16 @@
+/* $OpenBSD: terminal.c,v 1.3 1999/01/29 07:30:37 d Exp $ */
/* $NetBSD: terminal.c,v 1.2 1997/10/10 16:34:05 lukem Exp $ */
-/* $OpenBSD: terminal.c,v 1.2 1999/01/21 05:47:42 d Exp $ */
/*
* Hunt
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
* San Francisco, California
*/
-#if __STDC__
#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-# include "hunt.h"
-# define TERM_WIDTH 80 /* Assume terminals are 80-char wide */
+#include "hunt.h"
+#include "server.h"
+
+#define TERM_WIDTH 80 /* Assume terminals are 80-char wide */
/*
* cgoto:
@@ -24,8 +22,18 @@ cgoto(pp, y, x)
PLAYER *pp;
int y, x;
{
+
+ if (pp == ALL_PLAYERS) {
+ for (pp = Player; pp < End_player; pp++)
+ cgoto(pp, y, x);
+ for (pp = Monitor; pp < End_monitor; pp++)
+ cgoto(pp, y, x);
+ return;
+ }
+
if (x == pp->p_curx && y == pp->p_cury)
return;
+
sendcom(pp, MOVE, y, x);
pp->p_cury = y;
pp->p_curx = x;
@@ -40,6 +48,15 @@ outch(pp, ch)
PLAYER *pp;
char ch;
{
+
+ if (pp == ALL_PLAYERS) {
+ for (pp = Player; pp < End_player; pp++)
+ outch(pp, ch);
+ for (pp = Monitor; pp < End_monitor; pp++)
+ outch(pp, ch);
+ return;
+ }
+
if (++pp->p_curx >= TERM_WIDTH) {
pp->p_curx = 0;
pp->p_cury++;
@@ -57,6 +74,14 @@ outstr(pp, str, len)
char *str;
int len;
{
+ if (pp == ALL_PLAYERS) {
+ for (pp = Player; pp < End_player; pp++)
+ outstr(pp, str, len);
+ for (pp = Monitor; pp < End_monitor; pp++)
+ outstr(pp, str, len);
+ return;
+ }
+
pp->p_curx += len;
pp->p_cury += (pp->p_curx / TERM_WIDTH);
pp->p_curx %= TERM_WIDTH;
@@ -65,6 +90,30 @@ outstr(pp, str, len)
}
/*
+ * outat:
+ * draw a string at a location on the client.
+ * Cursor doesn't move if the location is invalid
+ */
+void
+outyx(pp, y, x, fmt)
+ PLAYER *pp;
+ int y;
+ int x;
+ const char *fmt;
+{
+ va_list ap;
+ char buf[BUFSIZ];
+ int len;
+
+ va_start(ap, fmt);
+ len = vsnprintf(buf, sizeof buf, fmt, ap);
+ if (y >= 0 && x >= 0)
+ cgoto(pp, y, x);
+ outstr(pp, buf, len);
+ va_end(ap);
+}
+
+/*
* clrscr:
* Clear the screen, and reset the current position on the screen.
*/
@@ -72,6 +121,15 @@ void
clrscr(pp)
PLAYER *pp;
{
+
+ if (pp == ALL_PLAYERS) {
+ for (pp = Player; pp < End_player; pp++)
+ clrscr(pp);
+ for (pp = Monitor; pp < End_monitor; pp++)
+ clrscr(pp);
+ return;
+ }
+
sendcom(pp, CLEAR);
pp->p_cury = 0;
pp->p_curx = 0;
@@ -88,54 +146,58 @@ ce(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
+sendcom(pp, command)
+ PLAYER *pp;
+ int command;
{
va_list ap;
- int arg1, arg2;
-#if __STDC__
+ char buf[3];
+ int len = 0;
+
va_start(ap, command);
-#else
- va_start(ap);
-#endif
- (void) putc(command, pp->p_output);
+ buf[len++] = command;
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);
+ buf[len++] = va_arg(ap, int);
+ buf[len++] = va_arg(ap, int);
break;
case ADDCH:
case READY:
- arg1 = va_arg(ap, int);
- (void) putc(arg1, pp->p_output);
+ case ENDWIN:
+ buf[len++] = va_arg(ap, int);
break;
}
+ va_end(ap);
- va_end(ap); /* No return needed for void functions. */
+ if (pp == ALL_PLAYERS) {
+ for (pp = Player; pp < End_player; pp++)
+ fwrite(buf, sizeof buf[0], len, pp->p_output);
+ for (pp = Monitor; pp < End_monitor; pp++)
+ fwrite(buf, sizeof buf[0], len, pp->p_output);
+ return;
+ } else
+ fwrite(buf, sizeof buf[0], len, pp->p_output);
+}
+
+/*
+ * sync:
+ * Flush the output buffer to the player
+ */
+void
+flush(pp)
+ PLAYER *pp;
+{
+ if (pp == ALL_PLAYERS) {
+ for (pp = Player; pp < End_player; pp++)
+ fflush(pp->p_output);
+ for (pp = Monitor; pp < End_monitor; pp++)
+ fflush(pp->p_output);
+ } else
+ fflush(pp->p_output);
}
+