mirror of
https://github.com/vattam/BSDGames.git
synced 2025-12-20 19:04:49 +00:00
Initial revision
git-svn-id: file:///srv/svn/joey/bsdgames-trunk@5086 a4a2c43b-8ac3-0310-8836-e0e880c912e2
This commit is contained in:
64
hunt/Makeconfig
Normal file
64
hunt/Makeconfig
Normal file
@@ -0,0 +1,64 @@
|
||||
# Makeconfig - configuration stuff for hunt and huntd.
|
||||
|
||||
ifneq ($(hunt_config_included),yes)
|
||||
|
||||
hunt_config_included := yes
|
||||
|
||||
# Originally from:
|
||||
#
|
||||
# Hunt
|
||||
# Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
# San Francisco, California
|
||||
#
|
||||
# Heavily modified for Linux - JSM 1997-04-26, 1997-12-19, 1998-09-05
|
||||
|
||||
#
|
||||
# Game parameter flags are:
|
||||
# RANDOM Include doors which disperse shots randomly
|
||||
# REFLECT Include diagonal walls that reflect shots
|
||||
# MONITOR Include code for watching the game from the sidelines
|
||||
# OOZE Include slime shots
|
||||
# FLY Make people fly when walls regenerate under them
|
||||
# VOLCANO Include occasional large slime explosions
|
||||
# DRONE Include occasional drone shots
|
||||
# BOOTS Include boots (which makes you immune to slime)
|
||||
# OTTO Reserved for CGL automatic player
|
||||
#
|
||||
hunt_GAME_PARAM := -DRANDOM -DREFLECT -DMONITOR -DOOZE -DFLY -DVOLCANO \
|
||||
-DBOOTS -DOTTO
|
||||
|
||||
#
|
||||
# System parameter flags are:
|
||||
# DEBUG Don't trust everything in the code
|
||||
# INTERNET Use the Internet domain IPC instead of UNIX domain
|
||||
# LOG Use syslog error-logging in driver (needs SYSLOG_42 or
|
||||
# or SYSLOG_43)
|
||||
# OLDIPC Use 4.1a internet system calls (must also define
|
||||
# INTERNET)
|
||||
# TERMINFO Use terminfo instead of termcap
|
||||
# SYSLOG_42 Use 4.2 BSD syslog(3)
|
||||
# SYSLOG_43 Use 4.2 BSD syslog(3)
|
||||
# LOG Use syslog(3) for logging errors
|
||||
# BSD_RELEASE Which version of BSD distribution
|
||||
# 42 is 4.2BSD (implies SYSLOG_42)
|
||||
# 43 is 4.3BSD (implies BROADCAST, SYSLOG_43)
|
||||
# USE_CURSES Use curses for everything (automatic w/TERMINFO)
|
||||
# SIGNAL_TYPE void or int
|
||||
# HPUX do special HPUX only hacks
|
||||
#
|
||||
# NOTE: if you change the domain (INTERNET vs UNIX) then "make newdomain"
|
||||
#
|
||||
hunt_DEFS_BSD43 := -DINTERNET -DLOG -DBSD_RELEASE=43 -DSIGNAL_TYPE=int
|
||||
hunt_DEFS_BSD44 := -DINTERNET -DLOG -DBSD_RELEASE=44 -DSIGNAL_TYPE=void
|
||||
hunt_DEFS_SUN := -DINTERNET -DLOG -DBSD_RELEASE=42 -DBROADCAST -DSIGNAL_TYPE=int
|
||||
hunt_DEFS_SUN4_0 := -DINTERNET -DLOG -DSYSLOG_43 -DBROADCAST -DSIGNAL_TYPE=void
|
||||
hunt_DEFS_ULTRIX := -DINTERNET -DLOG -DBSD_RELEASE=42 -DSIGNAL_TYPE=void
|
||||
hunt_DEFS_HPUX := -DHPUX -DINTERNET -DLOG -DSYSLOG_43 -DBROADCAST -DTERMINFO -DSIGNAL_TYPE=void
|
||||
hunt_DEFS_SGI := -DINTERNET -DLOG -DBSD_RELEASE=43 -DTERMINFO -DSIGNAL_TYPE=void
|
||||
hunt_DEFS_NEXT := $(DEFS_43) -bsd -traditional -Dconst= -DSIGNAL_TYPE=int
|
||||
hunt_DEFS_OSF1 := -DINTERNET -DLOG -DBSD_RELEASE=43 -DSIGNAL_TYPE=void -D_BSD
|
||||
hunt_DEFS_LINUX := -DINTERNET -DLOG -DBSD_RELEASE=44 -DUSE_CURSES -DSIGNAL_TYPE=void
|
||||
|
||||
hunt_DEFS := $(hunt_GAME_PARAM) $(hunt_DEFS_LINUX) -DHUNTD=\"$(SBINDIR)/huntd\"
|
||||
|
||||
endif
|
||||
5
hunt/Makefile.bsd
Normal file
5
hunt/Makefile.bsd
Normal file
@@ -0,0 +1,5 @@
|
||||
# $NetBSD: Makefile,v 1.1 1997/10/04 09:11:14 mrg Exp $
|
||||
|
||||
SUBDIR= hunt huntd
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
67
hunt/Makefile.inc.bsd
Normal file
67
hunt/Makefile.inc.bsd
Normal file
@@ -0,0 +1,67 @@
|
||||
# $NetBSD: Makefile.inc,v 1.3 1997/10/22 05:05:21 lukem Exp $
|
||||
#
|
||||
# Hunt
|
||||
# Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
# San Francisco, California
|
||||
|
||||
#
|
||||
# Game parameter flags are:
|
||||
# RANDOM Include doors which disperse shots randomly
|
||||
# REFLECT Include diagonal walls that reflect shots
|
||||
# MONITOR Include code for watching the game from the sidelines
|
||||
# OOZE Include slime shots
|
||||
# FLY Make people fly when walls regenerate under them
|
||||
# VOLCANO Include occasional large slime explosions
|
||||
# DRONE Include occasional drone shots
|
||||
# BOOTS Include boots (which makes you immune to slime)
|
||||
# OTTO Reserved for CGL automatic player
|
||||
#
|
||||
GAME_PARAM= -DRANDOM -DREFLECT -DMONITOR -DOOZE -DFLY -DVOLCANO -DBOOTS \
|
||||
-DOTTO
|
||||
|
||||
#
|
||||
# System parameter flags are:
|
||||
# DEBUG Don't trust everything in the code
|
||||
# INTERNET Use the Internet domain IPC instead of UNIX domain
|
||||
# LOG Use syslog error-logging in driver (needs SYSLOG_42 or
|
||||
# or SYSLOG_43)
|
||||
# OLDIPC Use 4.1a internet system calls (must also define
|
||||
# INTERNET)
|
||||
# TERMINFO Use terminfo instead of termcap
|
||||
# SYSLOG_42 Use 4.2 BSD syslog(3)
|
||||
# SYSLOG_43 Use 4.2 BSD syslog(3)
|
||||
# LOG Use syslog(3) for logging errors
|
||||
# BSD_RELEASE Which version of BSD distribution
|
||||
# 42 is 4.2BSD (implies SYSLOG_42)
|
||||
# 43 is 4.3BSD (implies BROADCAST, SYSLOG_43)
|
||||
# USE_CURSES Use curses for everything (automatic w/TERMINFO)
|
||||
# SIGNAL_TYPE void or int
|
||||
# HPUX do special HPUX only hacks
|
||||
#
|
||||
DEFS_BSD43= -DINTERNET -DLOG -DBSD_RELEASE=43 -DSIGNAL_TYPE=int
|
||||
DEFS_BSD44= -DINTERNET -DLOG -DBSD_RELEASE=44 -DSIGNAL_TYPE=void
|
||||
DEFS_SUN= -DINTERNET -DLOG -DBSD_RELEASE=42 -DBROADCAST -DSIGNAL_TYPE=int
|
||||
DEFS_SUN4_0= -DINTERNET -DLOG -DSYSLOG_43 -DBROADCAST -DSIGNAL_TYPE=void
|
||||
DEFS_ULTRIX= -DINTERNET -DLOG -DBSD_RELEASE=42 -DSIGNAL_TYPE=void
|
||||
DEFS_HPUX= -DHPUX -DINTERNET -DLOG -DSYSLOG_43 -DBROADCAST -DTERMINFO -DSIGNAL_TYPE=void
|
||||
DEFS_SGI= -DINTERNET -DLOG -DBSD_RELEASE=43 -DTERMINFO -DSIGNAL_TYPE=void
|
||||
DEFS_NEXT= $(DEFS_43) -bsd -traditional -Dconst= -DSIGNAL_TYPE=int
|
||||
DEFS_OSF1= -DINTERNET -DLOG -DBSD_RELEASE=43 -DSIGNAL_TYPE=void -D_BSD
|
||||
|
||||
#
|
||||
# The following flags are used for system specific compilation arguments.
|
||||
# Change them to include the appropriate arguments. For example, on SGI
|
||||
# machines, they should look like
|
||||
# SYSCFLAGS= -I/usr/include/bsd
|
||||
# SYSLIBS= -lbsd
|
||||
#
|
||||
SYSCFLAGS=
|
||||
SYSLIBS=
|
||||
|
||||
#
|
||||
# Generic definitions
|
||||
#
|
||||
DEFS= $(GAME_PARAM) $(DEFS_BSD44)
|
||||
CPPFLAGS+= $(SYSCFLAGS) $(DEFS) -DHUNTD=\"/usr/games/huntd\"
|
||||
|
||||
.include "../Makefile.inc"
|
||||
5
hunt/Makefrag
Normal file
5
hunt/Makefrag
Normal file
@@ -0,0 +1,5 @@
|
||||
# Makefrag - makefile fragment for hunt
|
||||
|
||||
hunt_all:
|
||||
|
||||
hunt_install:
|
||||
175
hunt/README
Normal file
175
hunt/README
Normal file
@@ -0,0 +1,175 @@
|
||||
What *is* hunt?
|
||||
|
||||
Hunt is a multi-player search-and-destroy game that takes place
|
||||
in a maze. The game may either be slow and strategic or fast
|
||||
and tactical, depending on how familiar the players are with the
|
||||
keyboard commands.
|
||||
|
||||
Distribution Policy:
|
||||
|
||||
Hunt is part of the user-contributed software distributed by
|
||||
Berkeley in 4BSD. The sources are copyrighted by the authors
|
||||
and the University of California. You may redistribute freely
|
||||
as long as the copyright notices are retained.
|
||||
|
||||
Words of Warning:
|
||||
|
||||
hunt uses the socket mechanism of 4BSD Unix, so if you are on
|
||||
System V (my sympathies), you're on your own.
|
||||
If your machine does not permit non-setuid-root processes to
|
||||
broadcast UDP packets, then hunt uses a *very* inefficient
|
||||
method for locating the hunt server: it sends a packet
|
||||
to every host on your network. If your machine falls
|
||||
into this category, we strongly recommend that you use
|
||||
either standalone or inetd mode *and* start hunt by
|
||||
specifying the hunt server host.
|
||||
hunt can be configured to use Unix-domain sockets, but that
|
||||
code has not been tested in recent memory. Also, since
|
||||
4.2BSD Unix-domain sockets are buggy, running hunt on
|
||||
4.2BSD with Unix-domain sockets will probably crash
|
||||
your system. If you want to experiment, feel free to
|
||||
do so. However, don't say I didn't warn you :-).
|
||||
hunt uses a fair amount of CPU time, both in user time (for
|
||||
computing interactions) and system time (for processing
|
||||
terminal interrupts). We found that a VAX 750 can
|
||||
support about three users before the system is
|
||||
noticeably impacted. The number goes up to about 8 or
|
||||
10 for a VAX 8650. On a network of Sun 3/50's with the
|
||||
server running on a 3/280, things work much more
|
||||
smoothly as the computing load is distributed across
|
||||
many machines.
|
||||
hunt may be dangerous to your health. "Arthritic pain" and
|
||||
"lack of circulation" in fingers have been reported by
|
||||
hunt abusers. Hunt may also be addictive, and the
|
||||
withdrawal symptoms are not pretty :-)
|
||||
|
||||
Installation:
|
||||
|
||||
1. Edit file "Makefile" and make sure the options selected are
|
||||
reasonable. There are four "make" variables that you
|
||||
should check: GAME_PARAM, SYSCFLAGS, SYSLDFLAGS, and DEFS.
|
||||
GAME_PARAM controls what features of the game will be
|
||||
compiled in (e.g. reflecting walls). The optional features
|
||||
are listed in comments above where GAME_PARAM is defined.
|
||||
If you want to try them, just add the ones you want to the
|
||||
GAME_PARAM definition.
|
||||
|
||||
DEFS is where most system configuration is described.
|
||||
If your system is 4.3BSD, Sun, Ultrix, Convex, HPUX
|
||||
v6.0.1, or SGI, you're in luck. We provide the
|
||||
appropriate definitions for these systems and you just
|
||||
need to select one of them (e.g. if you have an Ultrix
|
||||
system, just change the line
|
||||
DEFS= $(GAME_PARAM) $(DEFS_43)
|
||||
to
|
||||
DEFS= $(GAME_PARAM) $(DEFS_ULTRIX)
|
||||
). If your system is *not* listed above, then you may
|
||||
need to do some experiments. All of the options are
|
||||
documented in the Makefile, be brave.
|
||||
|
||||
SYSCFLAGS and SYSLDFLAGS are used for "unusual" systems
|
||||
and you probably won't need to deal with it. An
|
||||
example of an unusual system is the Silicon Graphics
|
||||
IRIS, which keeps the network socket code in a BSD
|
||||
emulation library that is in -lbsd. Edit these only if
|
||||
you *know* your system is "different."
|
||||
|
||||
2. Edit file "Makefile" and look at the "install:" target. By
|
||||
default, files are installed in /usr/games,
|
||||
/usr/games/lib, and /usr/man/man6, which are "standard"
|
||||
locations for games. If your system has a local games
|
||||
directory, you'll need to change these.
|
||||
3. Edit file "pathname.c" and make sure the file names and port
|
||||
numbers are reasonable. You can ignore the first set
|
||||
of variables as they are used only for debugging
|
||||
purposes. The second set is used in the installed
|
||||
version of hunt. The important variables are "Driver"
|
||||
(where the server is kept), "Test_port" (the Internet
|
||||
UDP port number that new players should use to contact
|
||||
the server), and "Stat_file" (where scoring statistics
|
||||
and body counts are written). The only tricky variable
|
||||
here is "Test_port". The default value is chosen so
|
||||
that it is unlikely to conflict with other service port
|
||||
numbers, but you can change it if you want to.
|
||||
4. Type "make install", which will compile and install the
|
||||
programs and manual pages. Now you're almost ready to
|
||||
go (see next section). There may be some warnings during
|
||||
compilation. Ignore them.
|
||||
|
||||
Setting up the network:
|
||||
|
||||
Hunt may be set up in one of three modes: standalone, inetd, or
|
||||
nothing. In "standalone" mode, there is always a hunt server
|
||||
running on a server machine. All players who enter the game
|
||||
will be talking to this server. This is the mode we use at
|
||||
UCSF. The cost is one entry in the process table on the server
|
||||
machine. In "inetd" mode, the server is started via inetd.
|
||||
Again, only one machine should be set up to answer game
|
||||
requests. The cost is having to edit a few system files. In
|
||||
"nothing" mode, no server is running when there is no one
|
||||
playing. The first person to enter hunt will automatically
|
||||
start up a server on his machine. This, of course, gives him
|
||||
an unfair advantage. Also, there may be race conditions such
|
||||
that players end up in different games. The choice of which
|
||||
mode to use depends on site configuration and politics. We
|
||||
recommend using "standalone" mode because it is simple to set
|
||||
up and starts up rapidly.
|
||||
|
||||
-----
|
||||
|
||||
FOR STANDALONE MODE, put these lines in /etc/rc.local on the
|
||||
server machine. THERE SHOULD ONLY BE ONE SERVER MACHINE!
|
||||
|
||||
# start up the hunt daemon if present
|
||||
if [ -f /usr/games/lib/huntd ]; then
|
||||
/usr/games/lib/huntd -s & (echo -n ' huntd') >/dev/console
|
||||
fi
|
||||
|
||||
Also, you should start one up (on the off chance that you will
|
||||
want to test this mess :-) by typing "/usr/games/lib/hunt -s".
|
||||
|
||||
-----
|
||||
|
||||
FOR INETD MODE, then things get more complicated. You need to
|
||||
edit both /etc/services and /etc/inetd.conf. In /etc/services,
|
||||
add the line
|
||||
|
||||
hunt 26740/udp
|
||||
|
||||
26740 corresponds to the default "Test_port". If you changed
|
||||
that variable, then you should put whatever value you used here
|
||||
as well. In /etc/inetd.conf, add the line
|
||||
|
||||
hunt dgram udp wait nobody /usr/games/lib/huntd huntd
|
||||
|
||||
This works for 4.3BSD. I don't remember the configuration file
|
||||
format for 4.2BSD inetd.
|
||||
|
||||
See the huntd.6 manual page for more details.
|
||||
|
||||
-----
|
||||
|
||||
FOR NOTHING MODE, do nothing.
|
||||
|
||||
Testing:
|
||||
Now you are ready to test the code. Type "/usr/games/hunt" or
|
||||
whatever you call the hunt executable. You should be prompted
|
||||
for your name and team. Then you should get the display of a
|
||||
maze. At this point, you should read the manual page :-).
|
||||
|
||||
======
|
||||
|
||||
Hunt is not officially supported by anyone anywhere (that I know of);
|
||||
however, bug reports will be read and bug fixes/enhancements may be
|
||||
sent out at irregular intervals. Send no flames, just money. Happy
|
||||
hunting.
|
||||
|
||||
Conrad Huang
|
||||
conrad@cgl.ucsf.edu
|
||||
Greg Couch
|
||||
gregc@cgl.ucsf.edu
|
||||
October 17, 1988
|
||||
|
||||
P.S. The authors of the game want to emphasize that this version of hunt
|
||||
was started over eight years ago, and the programming style exhibited here
|
||||
in no way reflects the current programming practices of the authors.
|
||||
31
hunt/README.linux
Normal file
31
hunt/README.linux
Normal file
@@ -0,0 +1,31 @@
|
||||
1997-12-19
|
||||
|
||||
I have replaced the old hunt port, which was rather a mess, with a version
|
||||
based on that in NetBSD-current. This version now uses internet domain
|
||||
sockets rather than Unix domain sockets, but is almost completely untested.
|
||||
The original README.linux is below.
|
||||
|
||||
Joseph S. Myers
|
||||
jsm28@cam.ac.uk
|
||||
|
||||
8/25/93
|
||||
|
||||
Finally, we have a version of hunt that appears to work!!!!!!
|
||||
It hasn't been extensively tested, and may contain many bugs. Note,
|
||||
any problems would most likely be due to my mangling/porting the code.
|
||||
The original authors have done a nice job.
|
||||
|
||||
Also, you can go through the Makefile and specify your desired game
|
||||
parameters. Be careful what you change, this Linux version is rather
|
||||
fragile. Any volunteers to sort out running over a network?
|
||||
|
||||
One hint for those who have never played hunt before ...
|
||||
1. Start the hunt driver: % /usr/sbin/huntd &
|
||||
2. Now start hunt: % /usr/games/hunt [options]
|
||||
In other words, for best results, get the driver running first.
|
||||
|
||||
Happy hunting! (And if you ever see "black tite" show up in one of your
|
||||
hunt games, RUN!!!!!)
|
||||
|
||||
Curt Olson
|
||||
curt@sledge.mn.org
|
||||
14
hunt/hunt/Makefile.bsd
Normal file
14
hunt/hunt/Makefile.bsd
Normal file
@@ -0,0 +1,14 @@
|
||||
# $NetBSD: Makefile,v 1.5 1998/02/18 22:37:31 jtc Exp $
|
||||
|
||||
PROG= hunt
|
||||
SRCS= connect.c hunt.c otto.c playit.c pathname.c
|
||||
MAN= hunt.6
|
||||
LDADD= -lcurses
|
||||
DPADD= ${LIBTERMCAP}
|
||||
HIDEGAME=hidegame
|
||||
|
||||
CPPFLAGS+=-I${.CURDIR}/../huntd
|
||||
|
||||
.PATH: ${.CURDIR}/../huntd
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
14
hunt/hunt/Makefrag
Normal file
14
hunt/hunt/Makefrag
Normal file
@@ -0,0 +1,14 @@
|
||||
# Makefrag - makefile fragment for hunt/hunt
|
||||
|
||||
include hunt/Makeconfig
|
||||
|
||||
hunt_hunt_DEFS := $(hunt_DEFS)
|
||||
hunt_hunt_DIRS := $(GAMESDIR) $(MAN6DIR)
|
||||
hunt_hunt_INCS := -Ihunt/huntd
|
||||
|
||||
hunt_hunt_all: hunt/hunt/hunt hunt/hunt/hunt.6
|
||||
|
||||
hunt_hunt_install: hunt_hunt_all
|
||||
$(INSTALL_BINARY) hunt/hunt/hunt $(INSTALL_PREFIX)$(GAMESDIR)/hunt
|
||||
$(HIDE_GAME) hunt
|
||||
$(INSTALL_MANUAL) hunt/hunt/hunt.6
|
||||
48
hunt/hunt/connect.c
Normal file
48
hunt/hunt/connect.c
Normal file
@@ -0,0 +1,48 @@
|
||||
/* $NetBSD: connect.c,v 1.3 1997/10/11 08:13:40 lukem Exp $ */
|
||||
/*
|
||||
* Hunt
|
||||
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
* San Francisco, California
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: connect.c,v 1.3 1997/10/11 08:13:40 lukem Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
# include "hunt.h"
|
||||
# include <signal.h>
|
||||
# include <unistd.h>
|
||||
|
||||
void
|
||||
do_connect(name, team, enter_status)
|
||||
const char *name;
|
||||
char team;
|
||||
long enter_status;
|
||||
{
|
||||
static long uid;
|
||||
static long mode;
|
||||
|
||||
if (uid == 0)
|
||||
uid = htonl(getuid());
|
||||
(void) write(Socket, (char *) &uid, LONGLEN);
|
||||
(void) write(Socket, name, NAMELEN);
|
||||
(void) write(Socket, &team, 1);
|
||||
enter_status = htonl(enter_status);
|
||||
(void) write(Socket, (char *) &enter_status, LONGLEN);
|
||||
(void) strcpy(Buf, ttyname(fileno(stderr)));
|
||||
(void) write(Socket, Buf, NAMELEN);
|
||||
# ifdef INTERNET
|
||||
if (Send_message != NULL)
|
||||
mode = C_MESSAGE;
|
||||
else
|
||||
# endif
|
||||
# ifdef MONITOR
|
||||
if (Am_monitor)
|
||||
mode = C_MONITOR;
|
||||
else
|
||||
# endif
|
||||
mode = C_PLAYER;
|
||||
mode = htonl(mode);
|
||||
(void) write(Socket, (char *) &mode, sizeof mode);
|
||||
}
|
||||
380
hunt/hunt/hunt.6.in
Normal file
380
hunt/hunt/hunt.6.in
Normal file
@@ -0,0 +1,380 @@
|
||||
.\" $NetBSD: hunt.6,v 1.3 1997/10/10 16:32:30 lukem Exp $
|
||||
.\"
|
||||
.\" hunt
|
||||
.\" Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
.\" San Francisco, California
|
||||
.\"
|
||||
.\" Copyright (c) 1985 Regents of the University of California.
|
||||
.\" All rights reserved. The Berkeley software License Agreement
|
||||
.\" specifies the terms and conditions for redistribution.
|
||||
.\"
|
||||
.TH HUNT 6 "21 August 1986"
|
||||
.UC 4
|
||||
.SH NAME
|
||||
hunt \- a multi-player multi-terminal game
|
||||
.SH SYNOPSIS
|
||||
\fB@gamesdir@/hunt\fP [ \fB\-qmcsfbS\fP ] [ \fB\-n\fP name ] [ \fB\-t\fP team ] [ \fB\-p\fP port ] [ \fB\-w\fP message ] [ host ]
|
||||
.SH DESCRIPTION
|
||||
The object of the game
|
||||
.I hunt
|
||||
is to kill off the other players.
|
||||
There are no rooms, no treasures, and no monsters.
|
||||
Instead, you wander around a maze, find grenades, trip mines, and shoot down
|
||||
walls and players.
|
||||
The more players you kill before you die, the better your score is.
|
||||
If the
|
||||
.B \-m
|
||||
flag is given,
|
||||
you enter the game as a monitor
|
||||
(you can see the action but you cannot play).
|
||||
.PP
|
||||
.I Hunt
|
||||
normally looks for an active game on the local network;
|
||||
if none is found, it starts one up on the local host.
|
||||
The location of the game may be specified by giving the
|
||||
.I host
|
||||
argument.
|
||||
This presupposes that a hunt game is already running on that host, see
|
||||
.IR huntd (6)
|
||||
for details on how to setup a game on a specific host.
|
||||
If more than one game if found,
|
||||
you may pick which game to play in.
|
||||
.PP
|
||||
If the
|
||||
.B \-q
|
||||
flag is given,
|
||||
.I hunt
|
||||
queries the local network (or specific host)
|
||||
and reports on all active games found.
|
||||
This is useful for shell startup scripts, \fIe.g.\fP csh's .login.
|
||||
.PP
|
||||
The player name may be specified on the command line by using the
|
||||
.B \-n
|
||||
option.
|
||||
.PP
|
||||
The
|
||||
.BR \-c ,
|
||||
.BR \-s ,
|
||||
and
|
||||
.B \-f
|
||||
options are for entering the game cloaked, scanning, or flying respectively.
|
||||
.PP
|
||||
The
|
||||
.B \-b
|
||||
option turns off beeping when you reach the typeahead limit.
|
||||
.PP
|
||||
The
|
||||
.B \-t
|
||||
option aids team playing by making everyone else on one's team
|
||||
appear as the team name.
|
||||
A team name is a single digit to avoid conflicting with other characters
|
||||
used in the game.
|
||||
.PP
|
||||
The
|
||||
.B \-p
|
||||
.I port
|
||||
option allows the rendezvous port number to be set.
|
||||
This is a useful way for people playing on dialup lines to avoid playing
|
||||
with people on 9600 baud terminals.
|
||||
.PP
|
||||
The
|
||||
.B \-w
|
||||
.I message
|
||||
option is the only way to send a message to everyone else's screen when
|
||||
you start up.
|
||||
It is most often used to say ``eat slime death - NickD's coming in''.
|
||||
.PP
|
||||
When you die and are asked if you wish to re-enter the game,
|
||||
there are other answers than just yes or no.
|
||||
You can also reply with a
|
||||
.B w
|
||||
for write a message before continuing or
|
||||
.B o
|
||||
to change how you enter the game (cloaked, scanning, or flying).
|
||||
.PP
|
||||
To be notified automatically when a
|
||||
.I hunt
|
||||
starts up, add your login to the
|
||||
.I hunt-players
|
||||
mailing list (see
|
||||
.IR huntd (6)).
|
||||
.SH "PLAYING HINTS"
|
||||
.I Hunt
|
||||
only works on crt (vdt) terminals with at least 24 lines, 80 columns, and
|
||||
cursor addressing.
|
||||
The screen is divided in to 3 areas.
|
||||
On the right hand side is the status area.
|
||||
It shows damage sustained,
|
||||
charges remaining,
|
||||
who's in the game,
|
||||
who's scanning (the
|
||||
.B ``*''
|
||||
in front of the name),
|
||||
who's cloaked (the
|
||||
.B ``+''
|
||||
in front of the name),
|
||||
and other players' scores.
|
||||
The rest of the screen is taken up by your map of the maze.
|
||||
The 24th line
|
||||
is used for longer messages that don't fit in the status area.
|
||||
.PP
|
||||
.I Hunt
|
||||
uses the same keys to move as
|
||||
.IR vi (1)
|
||||
does,
|
||||
.IR i.e. ,
|
||||
.BR h ,
|
||||
.BR j ,
|
||||
.BR k ,
|
||||
and
|
||||
.B l
|
||||
for left, down, up, right respectively.
|
||||
To change which direction you're facing in the maze,
|
||||
use the upper case version of the movement key (\c
|
||||
.IR i.e. ,
|
||||
.BR HJKL ).
|
||||
You can only fire or throw things in the direction you're facing.
|
||||
.TP
|
||||
Other commands are:
|
||||
.sp
|
||||
.nf
|
||||
.ta
|
||||
.ta \w'>\|<\|^\|v\ \ 'u
|
||||
f or 1 \- Fire a bullet (Takes 1 charge)
|
||||
g or 2 \- Throw grenade (Takes 9 charges)
|
||||
F or 3 \- Throw satchel charge (Takes 25 charges)
|
||||
G or 4 \- Throw bomb (Takes 49 charges)
|
||||
5 \- Throw big bomb (Takes 81 charges)
|
||||
6 \- Throw even bigger bomb (Takes 121 charges)
|
||||
7 \- Throw even more big bomb (Takes 169 charges)
|
||||
8 \- Throw even more bigger bomb (Takes 225 charges)
|
||||
9 \- Throw very big bomb (Takes 289 charges)
|
||||
0 \- Throw very, very big bomb (Takes 361 charges)
|
||||
@ \- Throw biggest bomb (Takes 441 charges)
|
||||
o \- Throw small slime (Takes 15 charges)
|
||||
O \- Throw big slime (Takes 30 charges)
|
||||
p \- Throw bigger slime (Takes 45 charges)
|
||||
P \- Throw biggest slime (Takes 60 charges)
|
||||
s \- Scan (show where other players are) (Takes 1 charge)
|
||||
c \- Cloak (hide from scanners) (Takes 1 charge)
|
||||
|
||||
^L \- Redraw screen
|
||||
q \- Quit
|
||||
.fi
|
||||
.TP
|
||||
The symbols on the screen are:
|
||||
.sp
|
||||
.nf
|
||||
.ta
|
||||
.ta \w'>\|<\|^\|v\ \ 'u
|
||||
\-\||\|+ \- walls
|
||||
/\|\\ \- diagonal (deflecting) walls
|
||||
# \- doors (dispersion walls)
|
||||
; \- small mine
|
||||
g \- large mine
|
||||
: \- bullet
|
||||
o \- grenade
|
||||
O \- satchel charge
|
||||
@ \- bomb
|
||||
s \- small slime
|
||||
$ \- big slime
|
||||
>\|<\|^\|v \- you facing right, left, up, or down
|
||||
}\|{\|i\|! \- other players facing right, left, up, or down
|
||||
\(** \- explosion
|
||||
.ne 3
|
||||
.cs R 24
|
||||
.cs I 24
|
||||
\fR\\|/\fP
|
||||
.cs R
|
||||
\fI\-\(**\-\fP \- grenade and large mine explosion
|
||||
.fl
|
||||
.cs R 24
|
||||
\fR/|\\\fP
|
||||
.cs R
|
||||
.cs I
|
||||
.fi
|
||||
.LP
|
||||
Other helpful hints:
|
||||
.sp
|
||||
.ie n .ds b []
|
||||
.el .ds b \(bu
|
||||
.ta
|
||||
.ta \w'\*b\ \|'u
|
||||
.nr In \n(.i
|
||||
.de MP
|
||||
.br
|
||||
.in \n(Inu+\w'\*b\ \|'u
|
||||
.ti \n(Inu
|
||||
\*b \c
|
||||
..
|
||||
.MP
|
||||
You can only fire in the direction you are facing.
|
||||
.MP
|
||||
You can only fire three shots in a row, then the gun must cool off.
|
||||
.MP
|
||||
Shots move 5 times faster than you do.
|
||||
.MP
|
||||
To stab someone,
|
||||
you face that player and move at them.
|
||||
.MP
|
||||
Stabbing does 2 points worth of damage and shooting does 5 points.
|
||||
.MP
|
||||
Slime does 5 points of damage each time it hits.
|
||||
.MP
|
||||
You start with 15 charges and get 5 more every time a player enters
|
||||
or re-enters.
|
||||
.MP
|
||||
Grenade explosions cover a 3 by 3 area, each larger bomb cover a
|
||||
correspondingly larger area (ranging from 5 by 5 to 21 by 21).
|
||||
All explosions are centered around the square the shot hits and
|
||||
do the most damage in the center.
|
||||
.MP
|
||||
Slime affects all squares it oozes over.
|
||||
The number of squares is equal to the number of charges used.
|
||||
.MP
|
||||
One small mine and one large mine is placed in the maze for every new player.
|
||||
A mine has a 2% probability of tripping when you walk forward on to it;
|
||||
50% when going sideways;
|
||||
95% when backing up.
|
||||
Tripping a mine costs you 5 points or 10 points respectively.
|
||||
Defusing a mine is worth 1 charge or 9 charges respectively.
|
||||
.MP
|
||||
You cannot see behind you.
|
||||
.MP
|
||||
Cloaking consumes 1 ammo charge per 20 of your moves.
|
||||
.MP
|
||||
Scanning consumes 1 ammo charge per (20 \(mu the number of players)
|
||||
of other player moves.
|
||||
.MP
|
||||
Turning on cloaking turns off scanning \(em turning on scanning turns off
|
||||
cloaking.
|
||||
.MP
|
||||
When you kill someone,
|
||||
you get 2 more damage capacity points and 2 damage points get taken away.
|
||||
.MP
|
||||
Maximum typeahead is 5 characters.
|
||||
.MP
|
||||
A shot destroys normal (\c
|
||||
.IR i.e.,
|
||||
non-diagonal, non-door) walls.
|
||||
.MP
|
||||
Diagonal walls deflect shots and change orientation.
|
||||
.MP
|
||||
Doors disperse shots in random directions (up, down, left, right).
|
||||
.MP
|
||||
Diagonal walls and doors cannot be destroyed by direct shots but may
|
||||
be destroyed by an adjacent grenade explosion.
|
||||
.MP
|
||||
Slime goes around walls, not through them.
|
||||
.MP
|
||||
Walls regenerate, reappearing in the order they were destroyed.
|
||||
One percent of the regenerated walls will be diagonal walls or doors.
|
||||
When a wall is generated directly beneath a player, he is thrown in
|
||||
a random direction for a random period of time. When he lands, he
|
||||
sustains damage (up to 20 percent of the amount of damage already
|
||||
sustained);
|
||||
.IR i.e. ,
|
||||
the less damage he had, the more nimble he is and
|
||||
therefore less likely to hurt himself on landing.
|
||||
.\"MP
|
||||
.\"There is a volcano close to the center of the maze which goes off
|
||||
.\"close to every 30 deaths.
|
||||
.MP
|
||||
Every 30 deaths or so, a
|
||||
.B ``?''
|
||||
will appear.
|
||||
It is a wandering bomb which will explode when it hits someone, or
|
||||
when it is slimed.
|
||||
.MP
|
||||
If no one moves, everything stands still.
|
||||
.MP
|
||||
The environment variable
|
||||
.B HUNT
|
||||
is checked to get the player name.
|
||||
If you don't have this variable set,
|
||||
.I hunt
|
||||
will ask you what name you want to play under.
|
||||
If you wish to set other options than just your name,
|
||||
you can enumerate the options as follows:
|
||||
.br
|
||||
.ti +1i
|
||||
setenv HUNT "name=Sneaky,team=1,cloak,mapkey=zoFfGg1f2g3F4G"
|
||||
.br
|
||||
sets the player name to Sneaky,
|
||||
sets the team to one,
|
||||
sets the enter game attribute to cloaked,
|
||||
and the maps \fBz\fP to \fBo\fP, \fBF\fP to \fBf\fP, \fBG\fP to \fBg\fP,
|
||||
\fB1\fP to \fBf\fP,
|
||||
\fB2\fP to \fBg\fP, \fB3\fP to \fBF\fP, and \fB4\fP to \fBG\fP.
|
||||
The \fImapkey\fP option must be last.
|
||||
Other options are: scan, fly, nobeep, port=string, host=string,
|
||||
and message=string \(em which correspond to the command line options.
|
||||
String options cannot contain commas since commas
|
||||
are used to separate options.
|
||||
.MP
|
||||
It's a boring game if you're the only one playing.
|
||||
.PP
|
||||
Your score is the decayed average of the ratio of number of kills to number
|
||||
of times you entered the game and is only kept for the duration
|
||||
of a single session of \fIhunt\fP.
|
||||
.PP
|
||||
.I Hunt
|
||||
normally drives up the load average to be approximately
|
||||
(number_of_players + 0.5) greater than it would be without a
|
||||
.I hunt
|
||||
game executing.
|
||||
.SH STATISTICS
|
||||
The
|
||||
.B \-S
|
||||
option fetches the current game statistics.
|
||||
The meaning of the column headings are as follows:
|
||||
.I score
|
||||
\(em the player's last score;
|
||||
.I ducked
|
||||
\(em
|
||||
how many shots a player ducked;
|
||||
.I absorb
|
||||
\(em how many shots a player absorbed;
|
||||
.I faced
|
||||
\(em how many shots were fired at player's face;
|
||||
.I shot
|
||||
\(em how many shots were fired at player;
|
||||
.I robbed
|
||||
\(em how many of player's shots were absorbed;
|
||||
.I missed
|
||||
\(em how many of player's shots were ducked;
|
||||
.I slimeK
|
||||
\(em how many slime kills player had;
|
||||
.I enemy
|
||||
\(em how many enemies were killed;
|
||||
.I friend
|
||||
\(em how many friends were killed (self and same team);
|
||||
.I deaths
|
||||
\(em how many times player died;
|
||||
.I still
|
||||
\(em how many times player died without typing in any commands;
|
||||
.I saved
|
||||
\(em how many times a shot/bomb would have killed player if he hadn't
|
||||
ducked or absorbed it.
|
||||
.SH FILES
|
||||
.nf
|
||||
.ta
|
||||
.ta \w'@sbindir@/huntd\ \ \ 'u
|
||||
@sbindir@/huntd game coordinator
|
||||
.DT
|
||||
.fi
|
||||
.SH "SEE ALSO"
|
||||
huntd(6)
|
||||
.SH AUTHORS
|
||||
Conrad Huang, Ken Arnold, and Greg Couch;
|
||||
.br
|
||||
University of California, San Francisco, Computer Graphics Lab
|
||||
.SH ACKNOWLEDGEMENTS
|
||||
We thank Don Kneller,
|
||||
John Thomason, Eric Pettersen, Mark Day,
|
||||
and Scott Weiner for providing
|
||||
endless hours of play-testing to improve the character of the game.
|
||||
We hope their significant others will forgive them;
|
||||
we certainly don't.
|
||||
.SH BUGS
|
||||
To keep up the pace, not everything is as realistic as possible.
|
||||
1104
hunt/hunt/hunt.c
Normal file
1104
hunt/hunt/hunt.c
Normal file
File diff suppressed because it is too large
Load Diff
602
hunt/hunt/otto.c
Normal file
602
hunt/hunt/otto.c
Normal file
@@ -0,0 +1,602 @@
|
||||
/* $NetBSD: otto.c,v 1.2 1997/10/10 16:32:39 lukem Exp $ */
|
||||
# ifdef OTTO
|
||||
/*
|
||||
* otto - a hunt otto-matic player
|
||||
*
|
||||
* This guy is buggy, unfair, stupid, and not extensible.
|
||||
* Future versions of hunt will have a subroutine library for
|
||||
* automatic players to link to. If you write your own "otto"
|
||||
* please let us know what subroutines you would expect in the
|
||||
* subroutine library.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: otto.c,v 1.2 1997/10/10 16:32:39 lukem Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
# include <sys/time.h>
|
||||
# include <curses.h>
|
||||
# include <ctype.h>
|
||||
# include <signal.h>
|
||||
# include <stdlib.h>
|
||||
# include <unistd.h>
|
||||
# include "hunt.h"
|
||||
|
||||
# undef WALL
|
||||
# undef NORTH
|
||||
# undef SOUTH
|
||||
# undef WEST
|
||||
# undef EAST
|
||||
# undef FRONT
|
||||
# undef LEFT
|
||||
# undef BACK
|
||||
# undef RIGHT
|
||||
|
||||
# ifdef HPUX
|
||||
# define random rand
|
||||
# endif
|
||||
|
||||
# ifndef USE_CURSES
|
||||
extern char screen[SCREEN_HEIGHT][SCREEN_WIDTH2];
|
||||
# define SCREEN(y, x) screen[y][x]
|
||||
# else
|
||||
# if defined(BSD_RELEASE) && BSD_RELEASE >= 44
|
||||
#ifndef NCURSES_VERSION
|
||||
# define SCREEN(y, x) stdscr->lines[y]->line[x].ch
|
||||
#else
|
||||
#define SCREEN(y, x) stdscr->_line[y].text[x]
|
||||
#endif
|
||||
# else
|
||||
# define SCREEN(y, x) stdscr->_y[y][x]
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# ifndef DEBUG
|
||||
# define STATIC static
|
||||
# else
|
||||
# define STATIC
|
||||
# endif
|
||||
|
||||
# define OPPONENT "{}i!"
|
||||
# define PROPONENT "^v<>"
|
||||
# define WALL "+\\/#*-|"
|
||||
# define PUSHOVER " bg;*#&"
|
||||
# define SHOTS "$@Oo:"
|
||||
|
||||
/* number of "directions" */
|
||||
# define NUMDIRECTIONS 4
|
||||
|
||||
/* absolute directions (facings) - counterclockwise */
|
||||
# define NORTH 0
|
||||
# define WEST 1
|
||||
# define SOUTH 2
|
||||
# define EAST 3
|
||||
# define ALLDIRS 0xf
|
||||
|
||||
/* relative directions - counterclockwise */
|
||||
# define FRONT 0
|
||||
# define LEFT 1
|
||||
# define BACK 2
|
||||
# define RIGHT 3
|
||||
|
||||
# define ABSCHARS "NWSE"
|
||||
# define RELCHARS "FLBR"
|
||||
# define DIRKEYS "khjl"
|
||||
|
||||
STATIC char command[BUFSIZ];
|
||||
STATIC int comlen;
|
||||
|
||||
# ifdef DEBUG
|
||||
STATIC FILE *debug = NULL;
|
||||
# endif
|
||||
|
||||
# define DEADEND 0x1
|
||||
# define ON_LEFT 0x2
|
||||
# define ON_RIGHT 0x4
|
||||
# define ON_SIDE (ON_LEFT|ON_RIGHT)
|
||||
# define BEEN 0x8
|
||||
# define BEEN_SAME 0x10
|
||||
|
||||
struct item {
|
||||
char what;
|
||||
int distance;
|
||||
int flags;
|
||||
};
|
||||
|
||||
STATIC struct item flbr[NUMDIRECTIONS];
|
||||
|
||||
# define fitem flbr[FRONT]
|
||||
# define litem flbr[LEFT]
|
||||
# define bitem flbr[BACK]
|
||||
# define ritem flbr[RIGHT]
|
||||
|
||||
STATIC int facing;
|
||||
STATIC int row, col;
|
||||
STATIC int num_turns; /* for wandering */
|
||||
STATIC char been_there[HEIGHT][WIDTH2];
|
||||
STATIC struct itimerval pause_time = { { 0, 0 }, { 0, 55000 }};
|
||||
|
||||
STATIC void attack __P((int, struct item *));
|
||||
STATIC void duck __P((int));
|
||||
STATIC void face_and_move_direction __P((int, int));
|
||||
STATIC int go_for_ammo __P((char));
|
||||
STATIC void ottolook __P((int, struct item *));
|
||||
STATIC void look_around __P((void));
|
||||
STATIC SIGNAL_TYPE nothing __P((int));
|
||||
STATIC int stop_look __P((struct item *, char, int, int));
|
||||
STATIC void wander __P((void));
|
||||
|
||||
STATIC SIGNAL_TYPE
|
||||
nothing(dummy)
|
||||
int dummy __attribute__((unused));
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
otto(y, x, face)
|
||||
int y, x;
|
||||
char face;
|
||||
{
|
||||
int i;
|
||||
extern int Otto_count;
|
||||
int old_mask;
|
||||
|
||||
# ifdef DEBUG
|
||||
if (debug == NULL) {
|
||||
debug = fopen("bug", "w");
|
||||
setbuf(debug, NULL);
|
||||
}
|
||||
fprintf(debug, "\n%c(%d,%d)", face, y, x);
|
||||
# endif
|
||||
(void) signal(SIGALRM, nothing);
|
||||
old_mask = sigblock(sigmask(SIGALRM));
|
||||
setitimer(ITIMER_REAL, &pause_time, NULL);
|
||||
sigpause(old_mask);
|
||||
sigsetmask(old_mask);
|
||||
|
||||
/* save away parameters so other functions may use/update info */
|
||||
switch (face) {
|
||||
case '^': facing = NORTH; break;
|
||||
case '<': facing = WEST; break;
|
||||
case 'v': facing = SOUTH; break;
|
||||
case '>': facing = EAST; break;
|
||||
default: abort();
|
||||
}
|
||||
row = y; col = x;
|
||||
been_there[row][col] |= 1 << facing;
|
||||
|
||||
/* initially no commands to be sent */
|
||||
comlen = 0;
|
||||
|
||||
/* find something to do */
|
||||
look_around();
|
||||
for (i = 0; i < NUMDIRECTIONS; i++) {
|
||||
if (strchr(OPPONENT, flbr[i].what) != NULL) {
|
||||
attack(i, &flbr[i]);
|
||||
memset(been_there, 0, sizeof been_there);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (strchr(SHOTS, bitem.what) != NULL && !(bitem.what & ON_SIDE)) {
|
||||
duck(BACK);
|
||||
memset(been_there, 0, sizeof been_there);
|
||||
# ifdef BOOTS
|
||||
} else if (go_for_ammo(BOOT_PAIR)) {
|
||||
memset(been_there, 0, sizeof been_there);
|
||||
} else if (go_for_ammo(BOOT)) {
|
||||
memset(been_there, 0, sizeof been_there);
|
||||
# endif
|
||||
} else if (go_for_ammo(GMINE))
|
||||
memset(been_there, 0, sizeof been_there);
|
||||
else if (go_for_ammo(MINE))
|
||||
memset(been_there, 0, sizeof been_there);
|
||||
else
|
||||
wander();
|
||||
|
||||
done:
|
||||
(void) write(Socket, command, comlen);
|
||||
Otto_count += comlen;
|
||||
# ifdef DEBUG
|
||||
(void) fwrite(command, 1, comlen, debug);
|
||||
# endif
|
||||
}
|
||||
|
||||
# define direction(abs,rel) (((abs) + (rel)) % NUMDIRECTIONS)
|
||||
|
||||
STATIC int
|
||||
stop_look(itemp, c, dist, side)
|
||||
struct item *itemp;
|
||||
char c;
|
||||
int dist;
|
||||
int side;
|
||||
{
|
||||
switch (c) {
|
||||
|
||||
case SPACE:
|
||||
if (side)
|
||||
itemp->flags &= ~DEADEND;
|
||||
return 0;
|
||||
|
||||
case MINE:
|
||||
case GMINE:
|
||||
# ifdef BOOTS
|
||||
case BOOT:
|
||||
case BOOT_PAIR:
|
||||
# endif
|
||||
if (itemp->distance == -1) {
|
||||
itemp->distance = dist;
|
||||
itemp->what = c;
|
||||
if (side < 0)
|
||||
itemp->flags |= ON_LEFT;
|
||||
else if (side > 0)
|
||||
itemp->flags |= ON_RIGHT;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case SHOT:
|
||||
case GRENADE:
|
||||
case SATCHEL:
|
||||
case BOMB:
|
||||
# ifdef OOZE
|
||||
case SLIME:
|
||||
# endif
|
||||
if (itemp->distance == -1 || (!side
|
||||
&& (itemp->flags & ON_SIDE
|
||||
|| itemp->what == GMINE || itemp->what == MINE))) {
|
||||
itemp->distance = dist;
|
||||
itemp->what = c;
|
||||
itemp->flags &= ~ON_SIDE;
|
||||
if (side < 0)
|
||||
itemp->flags |= ON_LEFT;
|
||||
else if (side > 0)
|
||||
itemp->flags |= ON_RIGHT;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case '{':
|
||||
case '}':
|
||||
case 'i':
|
||||
case '!':
|
||||
itemp->distance = dist;
|
||||
itemp->what = c;
|
||||
itemp->flags &= ~(ON_SIDE|DEADEND);
|
||||
if (side < 0)
|
||||
itemp->flags |= ON_LEFT;
|
||||
else if (side > 0)
|
||||
itemp->flags |= ON_RIGHT;
|
||||
return 1;
|
||||
|
||||
default:
|
||||
/* a wall or unknown object */
|
||||
if (side)
|
||||
return 0;
|
||||
if (itemp->distance == -1) {
|
||||
itemp->distance = dist;
|
||||
itemp->what = c;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void
|
||||
ottolook(rel_dir, itemp)
|
||||
int rel_dir;
|
||||
struct item *itemp;
|
||||
{
|
||||
int r, c;
|
||||
char ch;
|
||||
|
||||
r = 0;
|
||||
itemp->what = 0;
|
||||
itemp->distance = -1;
|
||||
itemp->flags = DEADEND|BEEN; /* true until proven false */
|
||||
|
||||
switch (direction(facing, rel_dir)) {
|
||||
|
||||
case NORTH:
|
||||
if (been_there[row - 1][col] & NORTH)
|
||||
itemp->flags |= BEEN_SAME;
|
||||
for (r = row - 1; r >= 0; r--)
|
||||
for (c = col - 1; c < col + 2; c++) {
|
||||
ch = SCREEN(r, c);
|
||||
if (stop_look(itemp, ch, row - r, c - col))
|
||||
goto cont_north;
|
||||
if (c == col && !been_there[r][c])
|
||||
itemp->flags &= ~BEEN;
|
||||
}
|
||||
cont_north:
|
||||
if (itemp->flags & DEADEND) {
|
||||
itemp->flags |= BEEN;
|
||||
been_there[r][col] |= NORTH;
|
||||
for (r = row - 1; r > row - itemp->distance; r--)
|
||||
been_there[r][col] = ALLDIRS;
|
||||
}
|
||||
break;
|
||||
|
||||
case SOUTH:
|
||||
if (been_there[row + 1][col] & SOUTH)
|
||||
itemp->flags |= BEEN_SAME;
|
||||
for (r = row + 1; r < HEIGHT; r++)
|
||||
for (c = col - 1; c < col + 2; c++) {
|
||||
ch = SCREEN(r, c);
|
||||
if (stop_look(itemp, ch, r - row, col - c))
|
||||
goto cont_south;
|
||||
if (c == col && !been_there[r][c])
|
||||
itemp->flags &= ~BEEN;
|
||||
}
|
||||
cont_south:
|
||||
if (itemp->flags & DEADEND) {
|
||||
itemp->flags |= BEEN;
|
||||
been_there[r][col] |= SOUTH;
|
||||
for (r = row + 1; r < row + itemp->distance; r++)
|
||||
been_there[r][col] = ALLDIRS;
|
||||
}
|
||||
break;
|
||||
|
||||
case WEST:
|
||||
if (been_there[row][col - 1] & WEST)
|
||||
itemp->flags |= BEEN_SAME;
|
||||
for (c = col - 1; c >= 0; c--)
|
||||
for (r = row - 1; r < row + 2; r++) {
|
||||
ch = SCREEN(r, c);
|
||||
if (stop_look(itemp, ch, col - c, row - r))
|
||||
goto cont_west;
|
||||
if (r == row && !been_there[r][c])
|
||||
itemp->flags &= ~BEEN;
|
||||
}
|
||||
cont_west:
|
||||
if (itemp->flags & DEADEND) {
|
||||
itemp->flags |= BEEN;
|
||||
been_there[r][col] |= WEST;
|
||||
for (c = col - 1; c > col - itemp->distance; c--)
|
||||
been_there[row][c] = ALLDIRS;
|
||||
}
|
||||
break;
|
||||
|
||||
case EAST:
|
||||
if (been_there[row][col + 1] & EAST)
|
||||
itemp->flags |= BEEN_SAME;
|
||||
for (c = col + 1; c < WIDTH; c++)
|
||||
for (r = row - 1; r < row + 2; r++) {
|
||||
ch = SCREEN(r, c);
|
||||
if (stop_look(itemp, ch, c - col, r - row))
|
||||
goto cont_east;
|
||||
if (r == row && !been_there[r][c])
|
||||
itemp->flags &= ~BEEN;
|
||||
}
|
||||
cont_east:
|
||||
if (itemp->flags & DEADEND) {
|
||||
itemp->flags |= BEEN;
|
||||
been_there[r][col] |= EAST;
|
||||
for (c = col + 1; c < col + itemp->distance; c++)
|
||||
been_there[row][c] = ALLDIRS;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void
|
||||
look_around()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUMDIRECTIONS; i++) {
|
||||
ottolook(i, &flbr[i]);
|
||||
# ifdef DEBUG
|
||||
fprintf(debug, " ottolook(%c)=%c(%d)(0x%x)",
|
||||
RELCHARS[i], flbr[i].what, flbr[i].distance, flbr[i].flags);
|
||||
# endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* as a side effect modifies facing and location (row, col)
|
||||
*/
|
||||
|
||||
STATIC void
|
||||
face_and_move_direction(rel_dir, distance)
|
||||
int rel_dir, distance;
|
||||
{
|
||||
int old_facing;
|
||||
char cmd;
|
||||
|
||||
old_facing = facing;
|
||||
cmd = DIRKEYS[facing = direction(facing, rel_dir)];
|
||||
|
||||
if (rel_dir != FRONT) {
|
||||
int i;
|
||||
struct item items[NUMDIRECTIONS];
|
||||
|
||||
command[comlen++] = toupper(cmd);
|
||||
if (distance == 0) {
|
||||
/* rotate ottolook's to be in right position */
|
||||
for (i = 0; i < NUMDIRECTIONS; i++)
|
||||
items[i] =
|
||||
flbr[(i + old_facing) % NUMDIRECTIONS];
|
||||
memcpy(flbr, items, sizeof flbr);
|
||||
}
|
||||
}
|
||||
while (distance--) {
|
||||
command[comlen++] = cmd;
|
||||
switch (facing) {
|
||||
|
||||
case NORTH: row--; break;
|
||||
case WEST: col--; break;
|
||||
case SOUTH: row++; break;
|
||||
case EAST: col++; break;
|
||||
}
|
||||
if (distance == 0)
|
||||
look_around();
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void
|
||||
attack(rel_dir, itemp)
|
||||
int rel_dir;
|
||||
struct item *itemp;
|
||||
{
|
||||
if (!(itemp->flags & ON_SIDE)) {
|
||||
face_and_move_direction(rel_dir, 0);
|
||||
command[comlen++] = 'o';
|
||||
command[comlen++] = 'o';
|
||||
duck(FRONT);
|
||||
command[comlen++] = ' ';
|
||||
} else if (itemp->distance > 1) {
|
||||
face_and_move_direction(rel_dir, 2);
|
||||
duck(FRONT);
|
||||
} else {
|
||||
face_and_move_direction(rel_dir, 1);
|
||||
if (itemp->flags & ON_LEFT)
|
||||
rel_dir = LEFT;
|
||||
else
|
||||
rel_dir = RIGHT;
|
||||
(void) face_and_move_direction(rel_dir, 0);
|
||||
command[comlen++] = 'f';
|
||||
command[comlen++] = 'f';
|
||||
duck(FRONT);
|
||||
command[comlen++] = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void
|
||||
duck(rel_dir)
|
||||
int rel_dir;
|
||||
{
|
||||
int dir;
|
||||
|
||||
switch (dir = direction(facing, rel_dir)) {
|
||||
|
||||
case NORTH:
|
||||
case SOUTH:
|
||||
if (strchr(PUSHOVER, SCREEN(row, col - 1)) != NULL)
|
||||
command[comlen++] = 'h';
|
||||
else if (strchr(PUSHOVER, SCREEN(row, col + 1)) != NULL)
|
||||
command[comlen++] = 'l';
|
||||
else if (dir == NORTH
|
||||
&& strchr(PUSHOVER, SCREEN(row + 1, col)) != NULL)
|
||||
command[comlen++] = 'j';
|
||||
else if (dir == SOUTH
|
||||
&& strchr(PUSHOVER, SCREEN(row - 1, col)) != NULL)
|
||||
command[comlen++] = 'k';
|
||||
else if (dir == NORTH)
|
||||
command[comlen++] = 'k';
|
||||
else
|
||||
command[comlen++] = 'j';
|
||||
break;
|
||||
|
||||
case WEST:
|
||||
case EAST:
|
||||
if (strchr(PUSHOVER, SCREEN(row - 1, col)) != NULL)
|
||||
command[comlen++] = 'k';
|
||||
else if (strchr(PUSHOVER, SCREEN(row + 1, col)) != NULL)
|
||||
command[comlen++] = 'j';
|
||||
else if (dir == WEST
|
||||
&& strchr(PUSHOVER, SCREEN(row, col + 1)) != NULL)
|
||||
command[comlen++] = 'l';
|
||||
else if (dir == EAST
|
||||
&& strchr(PUSHOVER, SCREEN(row, col - 1)) != NULL)
|
||||
command[comlen++] = 'h';
|
||||
else if (dir == WEST)
|
||||
command[comlen++] = 'h';
|
||||
else
|
||||
command[comlen++] = 'l';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* go for the closest mine if possible
|
||||
*/
|
||||
|
||||
STATIC int
|
||||
go_for_ammo(mine)
|
||||
char mine;
|
||||
{
|
||||
int i, rel_dir, dist;
|
||||
|
||||
rel_dir = -1;
|
||||
dist = WIDTH;
|
||||
for (i = 0; i < NUMDIRECTIONS; i++) {
|
||||
if (flbr[i].what == mine && flbr[i].distance < dist) {
|
||||
rel_dir = i;
|
||||
dist = flbr[i].distance;
|
||||
}
|
||||
}
|
||||
if (rel_dir == -1)
|
||||
return FALSE;
|
||||
|
||||
if (!(flbr[rel_dir].flags & ON_SIDE)
|
||||
|| flbr[rel_dir].distance > 1) {
|
||||
if (dist > 4)
|
||||
dist = 4;
|
||||
face_and_move_direction(rel_dir, dist);
|
||||
} else
|
||||
return FALSE; /* until it's done right */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
STATIC void
|
||||
wander()
|
||||
{
|
||||
int i, j, rel_dir, dir_mask, dir_count;
|
||||
|
||||
for (i = 0; i < NUMDIRECTIONS; i++)
|
||||
if (!(flbr[i].flags & BEEN) || flbr[i].distance <= 1)
|
||||
break;
|
||||
if (i == NUMDIRECTIONS)
|
||||
memset(been_there, 0, sizeof been_there);
|
||||
dir_mask = dir_count = 0;
|
||||
for (i = 0; i < NUMDIRECTIONS; i++) {
|
||||
j = (RIGHT + i) % NUMDIRECTIONS;
|
||||
if (flbr[j].distance <= 1 || flbr[j].flags & DEADEND)
|
||||
continue;
|
||||
if (!(flbr[j].flags & BEEN_SAME)) {
|
||||
dir_mask = 1 << j;
|
||||
dir_count = 1;
|
||||
break;
|
||||
}
|
||||
if (j == FRONT
|
||||
&& num_turns > 4 + (random() %
|
||||
((flbr[FRONT].flags & BEEN) ? 7 : HEIGHT)))
|
||||
continue;
|
||||
dir_mask |= 1 << j;
|
||||
# ifdef notdef
|
||||
dir_count++;
|
||||
# else
|
||||
dir_count = 1;
|
||||
break;
|
||||
# endif
|
||||
}
|
||||
if (dir_count == 0) {
|
||||
duck(random() % NUMDIRECTIONS);
|
||||
num_turns = 0;
|
||||
return;
|
||||
} else if (dir_count == 1)
|
||||
rel_dir = ffs(dir_mask) - 1;
|
||||
else {
|
||||
rel_dir = ffs(dir_mask) - 1;
|
||||
dir_mask &= ~(1 << rel_dir);
|
||||
while (dir_mask != 0) {
|
||||
i = ffs(dir_mask) - 1;
|
||||
if (random() % 5 == 0)
|
||||
rel_dir = i;
|
||||
dir_mask &= ~(1 << i);
|
||||
}
|
||||
}
|
||||
if (rel_dir == FRONT)
|
||||
num_turns++;
|
||||
else
|
||||
num_turns = 0;
|
||||
|
||||
# ifdef DEBUG
|
||||
fprintf(debug, " w(%c)", RELCHARS[rel_dir]);
|
||||
# endif
|
||||
face_and_move_direction(rel_dir, 1);
|
||||
}
|
||||
|
||||
# endif /* OTTO */
|
||||
640
hunt/hunt/playit.c
Normal file
640
hunt/hunt/playit.c
Normal file
@@ -0,0 +1,640 @@
|
||||
/* $NetBSD: playit.c,v 1.4 1997/10/20 00:37:15 lukem Exp $ */
|
||||
/*
|
||||
* Hunt
|
||||
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
* San Francisco, California
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: playit.c,v 1.4 1997/10/20 00:37:15 lukem Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
# include <sys/file.h>
|
||||
# include <err.h>
|
||||
# include <errno.h>
|
||||
# include <curses.h>
|
||||
# include <ctype.h>
|
||||
# include <signal.h>
|
||||
# include <sys/time.h>
|
||||
# if defined(HPUX) || (defined(BSD_RELEASE) && BSD_RELEASE >= 44)
|
||||
# include <termios.h>
|
||||
# include <unistd.h>
|
||||
# endif
|
||||
# include "hunt.h"
|
||||
|
||||
# ifndef FREAD
|
||||
# define FREAD 1
|
||||
# endif
|
||||
|
||||
# if !defined(USE_CURSES) || !defined(TERMINFO)
|
||||
# define beep() (void) putchar(CTRL('G'))
|
||||
# endif
|
||||
# if !defined(USE_CURSES)
|
||||
# undef refresh
|
||||
# define refresh() (void) fflush(stdout);
|
||||
# endif
|
||||
# ifdef USE_CURSES
|
||||
# define clear_eol() clrtoeol()
|
||||
# define put_ch addch
|
||||
# define put_str addstr
|
||||
# endif
|
||||
|
||||
static int nchar_send;
|
||||
# ifndef USE_CURSES
|
||||
char screen[SCREEN_HEIGHT][SCREEN_WIDTH2], blanks[SCREEN_WIDTH];
|
||||
int cur_row, cur_col;
|
||||
# endif
|
||||
# ifdef OTTO
|
||||
int Otto_count;
|
||||
int Otto_mode;
|
||||
static int otto_y, otto_x;
|
||||
static char otto_face;
|
||||
# endif
|
||||
|
||||
# define MAX_SEND 5
|
||||
# define STDIN 0
|
||||
|
||||
/*
|
||||
* ibuf is the input buffer used for the stream from the driver.
|
||||
* It is small because we do not check for user input when there
|
||||
* are characters in the input buffer.
|
||||
*/
|
||||
static int icnt = 0;
|
||||
static unsigned char ibuf[256], *iptr = ibuf;
|
||||
|
||||
#define GETCHR() (--icnt < 0 ? getchr() : *iptr++)
|
||||
|
||||
#if !defined(BSD_RELEASE) || BSD_RELEASE < 44
|
||||
extern int _putchar();
|
||||
#endif
|
||||
|
||||
static unsigned char getchr __P((void));
|
||||
static void send_stuff __P((void));
|
||||
|
||||
/*
|
||||
* playit:
|
||||
* Play a given game, handling all the curses commands from
|
||||
* the driver.
|
||||
*/
|
||||
void
|
||||
playit()
|
||||
{
|
||||
int ch;
|
||||
int y, x;
|
||||
long version;
|
||||
|
||||
if (read(Socket, (char *) &version, LONGLEN) != LONGLEN) {
|
||||
bad_con();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
if (ntohl(version) != (unsigned long)HUNT_VERSION) {
|
||||
bad_ver();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
errno = 0;
|
||||
# ifdef OTTO
|
||||
Otto_count = 0;
|
||||
# endif
|
||||
nchar_send = MAX_SEND;
|
||||
while ((ch = GETCHR()) != EOF) {
|
||||
# ifdef DEBUG
|
||||
fputc(ch, stderr);
|
||||
# endif
|
||||
switch (ch & 0377) {
|
||||
case MOVE:
|
||||
y = GETCHR();
|
||||
x = GETCHR();
|
||||
# ifdef USE_CURSES
|
||||
move(y, x);
|
||||
# else
|
||||
mvcur(cur_row, cur_col, y, x);
|
||||
cur_row = y;
|
||||
cur_col = x;
|
||||
# endif
|
||||
break;
|
||||
case ADDCH:
|
||||
ch = GETCHR();
|
||||
# ifdef OTTO
|
||||
switch (ch) {
|
||||
|
||||
case '<':
|
||||
case '>':
|
||||
case '^':
|
||||
case 'v':
|
||||
otto_face = ch;
|
||||
# ifdef USE_CURSES
|
||||
getyx(stdscr, otto_y, otto_x);
|
||||
# else
|
||||
otto_y = cur_row;
|
||||
otto_x = cur_col;
|
||||
# endif
|
||||
break;
|
||||
}
|
||||
# endif
|
||||
put_ch(ch);
|
||||
break;
|
||||
case CLRTOEOL:
|
||||
clear_eol();
|
||||
break;
|
||||
case CLEAR:
|
||||
clear_the_screen();
|
||||
break;
|
||||
case REFRESH:
|
||||
refresh();
|
||||
break;
|
||||
case REDRAW:
|
||||
redraw_screen();
|
||||
refresh();
|
||||
break;
|
||||
case ENDWIN:
|
||||
refresh();
|
||||
if ((ch = GETCHR()) == LAST_PLAYER)
|
||||
Last_player = TRUE;
|
||||
ch = EOF;
|
||||
goto out;
|
||||
case BELL:
|
||||
beep();
|
||||
break;
|
||||
case READY:
|
||||
refresh();
|
||||
if (nchar_send < 0)
|
||||
# if defined(HPUX) || (defined(BSD_RELEASE) && BSD_RELEASE >= 44)
|
||||
tcflush(STDIN, TCIFLUSH);
|
||||
# else
|
||||
# ifndef TCFLSH
|
||||
(void) ioctl(STDIN, TIOCFLUSH, &in);
|
||||
# else
|
||||
(void) ioctl(STDIN, TCFLSH, 0);
|
||||
# endif
|
||||
# endif
|
||||
nchar_send = MAX_SEND;
|
||||
# ifndef OTTO
|
||||
(void) GETCHR();
|
||||
# else
|
||||
Otto_count -= (GETCHR() & 0xff);
|
||||
if (!Am_monitor) {
|
||||
# ifdef DEBUG
|
||||
fputc('0' + Otto_count, stderr);
|
||||
# endif
|
||||
if (Otto_count == 0 && Otto_mode)
|
||||
otto(otto_y, otto_x, otto_face);
|
||||
}
|
||||
# endif
|
||||
break;
|
||||
default:
|
||||
# ifdef OTTO
|
||||
switch (ch) {
|
||||
|
||||
case '<':
|
||||
case '>':
|
||||
case '^':
|
||||
case 'v':
|
||||
otto_face = ch;
|
||||
# ifdef USE_CURSES
|
||||
getyx(stdscr, otto_y, otto_x);
|
||||
# else
|
||||
otto_y = cur_row;
|
||||
otto_x = cur_col;
|
||||
# endif
|
||||
break;
|
||||
}
|
||||
# endif
|
||||
put_ch(ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
out:
|
||||
(void) close(Socket);
|
||||
}
|
||||
|
||||
/*
|
||||
* getchr:
|
||||
* Grab input and pass it along to the driver
|
||||
* Return any characters from the driver
|
||||
* When this routine is called by GETCHR, we already know there are
|
||||
* no characters in the input buffer.
|
||||
*/
|
||||
static unsigned char
|
||||
getchr()
|
||||
{
|
||||
fd_set readfds, s_readfds;
|
||||
int nfds, s_nfds;
|
||||
|
||||
FD_ZERO(&s_readfds);
|
||||
FD_SET(Socket, &s_readfds);
|
||||
FD_SET(STDIN, &s_readfds);
|
||||
s_nfds = (Socket > STDIN) ? Socket : STDIN;
|
||||
s_nfds++;
|
||||
|
||||
one_more_time:
|
||||
do {
|
||||
errno = 0;
|
||||
readfds = s_readfds;
|
||||
nfds = s_nfds;
|
||||
nfds = select(nfds, &readfds, NULL, NULL, NULL);
|
||||
} while (nfds <= 0 && errno == EINTR);
|
||||
|
||||
if (FD_ISSET(STDIN, &readfds))
|
||||
send_stuff();
|
||||
if (! FD_ISSET(Socket, &readfds))
|
||||
goto one_more_time;
|
||||
icnt = read(Socket, ibuf, sizeof ibuf);
|
||||
if (icnt < 0) {
|
||||
bad_con();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
if (icnt == 0)
|
||||
goto one_more_time;
|
||||
iptr = ibuf;
|
||||
icnt--;
|
||||
return *iptr++;
|
||||
}
|
||||
|
||||
/*
|
||||
* send_stuff:
|
||||
* Send standard input characters to the driver
|
||||
*/
|
||||
static void
|
||||
send_stuff()
|
||||
{
|
||||
int count;
|
||||
char *sp, *nsp;
|
||||
static char inp[sizeof Buf];
|
||||
|
||||
count = read(STDIN, Buf, sizeof Buf);
|
||||
if (count <= 0)
|
||||
return;
|
||||
if (nchar_send <= 0 && !no_beep) {
|
||||
(void) write(1, "\7", 1); /* CTRL('G') */
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* look for 'q'uit commands; if we find one,
|
||||
* confirm it. If it is not confirmed, strip
|
||||
* it out of the input
|
||||
*/
|
||||
Buf[count] = '\0';
|
||||
nsp = inp;
|
||||
for (sp = Buf; *sp != '\0'; sp++)
|
||||
if ((*nsp = map_key[(int)*sp]) == 'q')
|
||||
intr(0);
|
||||
else
|
||||
nsp++;
|
||||
count = nsp - inp;
|
||||
if (count) {
|
||||
# ifdef OTTO
|
||||
Otto_count += count;
|
||||
# endif
|
||||
nchar_send -= count;
|
||||
if (nchar_send < 0)
|
||||
count += nchar_send;
|
||||
(void) write(Socket, inp, count);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* quit:
|
||||
* Handle the end of the game when the player dies
|
||||
*/
|
||||
int
|
||||
quit(old_status)
|
||||
int old_status;
|
||||
{
|
||||
int explain, ch;
|
||||
|
||||
if (Last_player)
|
||||
return Q_QUIT;
|
||||
# ifdef OTTO
|
||||
if (Otto_mode)
|
||||
return Q_CLOAK;
|
||||
# endif
|
||||
# ifdef USE_CURSES
|
||||
move(HEIGHT, 0);
|
||||
# else
|
||||
mvcur(cur_row, cur_col, HEIGHT, 0);
|
||||
cur_row = HEIGHT;
|
||||
cur_col = 0;
|
||||
# endif
|
||||
put_str("Re-enter game [ynwo]? ");
|
||||
clear_eol();
|
||||
explain = FALSE;
|
||||
for (;;) {
|
||||
refresh();
|
||||
if (isupper(ch = getchar()))
|
||||
ch = tolower(ch);
|
||||
if (ch == 'y')
|
||||
return old_status;
|
||||
else if (ch == 'o')
|
||||
break;
|
||||
else if (ch == 'n') {
|
||||
# ifndef INTERNET
|
||||
return Q_QUIT;
|
||||
# else
|
||||
# ifdef USE_CURSES
|
||||
move(HEIGHT, 0);
|
||||
# else
|
||||
mvcur(cur_row, cur_col, HEIGHT, 0);
|
||||
cur_row = HEIGHT;
|
||||
cur_col = 0;
|
||||
# endif
|
||||
put_str("Write a parting message [yn]? ");
|
||||
clear_eol();
|
||||
refresh();
|
||||
for (;;) {
|
||||
if (isupper(ch = getchar()))
|
||||
ch = tolower(ch);
|
||||
if (ch == 'y')
|
||||
goto get_message;
|
||||
if (ch == 'n')
|
||||
return Q_QUIT;
|
||||
}
|
||||
# endif
|
||||
}
|
||||
# ifdef INTERNET
|
||||
else if (ch == 'w') {
|
||||
static char buf[WIDTH + WIDTH % 2];
|
||||
char *cp, c;
|
||||
|
||||
get_message:
|
||||
c = ch; /* save how we got here */
|
||||
# ifdef USE_CURSES
|
||||
move(HEIGHT, 0);
|
||||
# else
|
||||
mvcur(cur_row, cur_col, HEIGHT, 0);
|
||||
cur_row = HEIGHT;
|
||||
cur_col = 0;
|
||||
# endif
|
||||
put_str("Message: ");
|
||||
clear_eol();
|
||||
refresh();
|
||||
cp = buf;
|
||||
for (;;) {
|
||||
refresh();
|
||||
if ((ch = getchar()) == '\n' || ch == '\r')
|
||||
break;
|
||||
# if defined(TERMINFO) || BSD_RELEASE >= 44
|
||||
if (ch == erasechar())
|
||||
# else
|
||||
if (ch == _tty.sg_erase)
|
||||
# endif
|
||||
{
|
||||
if (cp > buf) {
|
||||
# ifdef USE_CURSES
|
||||
int y, x;
|
||||
getyx(stdscr, y, x);
|
||||
move(y, x - 1);
|
||||
# else
|
||||
mvcur(cur_row, cur_col, cur_row,
|
||||
cur_col - 1);
|
||||
cur_col -= 1;
|
||||
# endif
|
||||
cp -= 1;
|
||||
clear_eol();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
# if defined(TERMINFO) || BSD_RELEASE >= 44
|
||||
else if (ch == killchar())
|
||||
# else
|
||||
else if (ch == _tty.sg_kill)
|
||||
# endif
|
||||
{
|
||||
# ifdef USE_CURSES
|
||||
int y, x;
|
||||
getyx(stdscr, y, x);
|
||||
move(y, x - (cp - buf));
|
||||
# else
|
||||
mvcur(cur_row, cur_col, cur_row,
|
||||
cur_col - (cp - buf));
|
||||
cur_col -= cp - buf;
|
||||
# endif
|
||||
cp = buf;
|
||||
clear_eol();
|
||||
continue;
|
||||
} else if (!isprint(ch)) {
|
||||
beep();
|
||||
continue;
|
||||
}
|
||||
put_ch(ch);
|
||||
*cp++ = ch;
|
||||
if (cp + 1 >= buf + sizeof buf)
|
||||
break;
|
||||
}
|
||||
*cp = '\0';
|
||||
Send_message = buf;
|
||||
return (c == 'w') ? old_status : Q_MESSAGE;
|
||||
}
|
||||
# endif
|
||||
beep();
|
||||
if (!explain) {
|
||||
put_str("(Yes, No, Write message, or Options) ");
|
||||
explain = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
# ifdef USE_CURSES
|
||||
move(HEIGHT, 0);
|
||||
# else
|
||||
mvcur(cur_row, cur_col, HEIGHT, 0);
|
||||
cur_row = HEIGHT;
|
||||
cur_col = 0;
|
||||
# endif
|
||||
# ifdef FLY
|
||||
put_str("Scan, Cloak, Flying, or Quit? ");
|
||||
# else
|
||||
put_str("Scan, Cloak, or Quit? ");
|
||||
# endif
|
||||
clear_eol();
|
||||
refresh();
|
||||
explain = FALSE;
|
||||
for (;;) {
|
||||
if (isupper(ch = getchar()))
|
||||
ch = tolower(ch);
|
||||
if (ch == 's')
|
||||
return Q_SCAN;
|
||||
else if (ch == 'c')
|
||||
return Q_CLOAK;
|
||||
# ifdef FLY
|
||||
else if (ch == 'f')
|
||||
return Q_FLY;
|
||||
# endif
|
||||
else if (ch == 'q')
|
||||
return Q_QUIT;
|
||||
beep();
|
||||
if (!explain) {
|
||||
# ifdef FLY
|
||||
put_str("[SCFQ] ");
|
||||
# else
|
||||
put_str("[SCQ] ");
|
||||
# endif
|
||||
explain = TRUE;
|
||||
}
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
||||
# ifndef USE_CURSES
|
||||
void
|
||||
put_ch(ch)
|
||||
char ch;
|
||||
{
|
||||
if (!isprint(ch)) {
|
||||
fprintf(stderr, "r,c,ch: %d,%d,%d", cur_row, cur_col, ch);
|
||||
return;
|
||||
}
|
||||
screen[cur_row][cur_col] = ch;
|
||||
putchar(ch);
|
||||
if (++cur_col >= COLS) {
|
||||
if (!AM || XN)
|
||||
putchar('\n');
|
||||
cur_col = 0;
|
||||
if (++cur_row >= LINES)
|
||||
cur_row = LINES;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
put_str(s)
|
||||
const char *s;
|
||||
{
|
||||
while (*s)
|
||||
put_ch(*s++);
|
||||
}
|
||||
# endif
|
||||
|
||||
void
|
||||
clear_the_screen()
|
||||
{
|
||||
# ifdef USE_CURSES
|
||||
clear();
|
||||
move(0, 0);
|
||||
refresh();
|
||||
# else
|
||||
int i;
|
||||
|
||||
if (blanks[0] == '\0')
|
||||
for (i = 0; i < SCREEN_WIDTH; i++)
|
||||
blanks[i] = ' ';
|
||||
|
||||
if (CL != NULL) {
|
||||
#if !defined(BSD_RELEASE) || BSD_RELEASE < 44
|
||||
tputs(CL, LINES, _putchar);
|
||||
#else
|
||||
tputs(CL, LINES, __cputchar);
|
||||
#endif
|
||||
for (i = 0; i < SCREEN_HEIGHT; i++)
|
||||
memcpy(screen[i], blanks, SCREEN_WIDTH);
|
||||
} else {
|
||||
for (i = 0; i < SCREEN_HEIGHT; i++) {
|
||||
mvcur(cur_row, cur_col, i, 0);
|
||||
cur_row = i;
|
||||
cur_col = 0;
|
||||
clear_eol();
|
||||
}
|
||||
mvcur(cur_row, cur_col, 0, 0);
|
||||
}
|
||||
cur_row = cur_col = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef USE_CURSES
|
||||
void
|
||||
clear_eol()
|
||||
{
|
||||
if (CE != NULL)
|
||||
#if !defined(BSD_RELEASE) || BSD_RELEASE < 44
|
||||
tputs(CE, 1, _putchar);
|
||||
#else
|
||||
tputs(CE, 1, __cputchar);
|
||||
#endif
|
||||
else {
|
||||
fwrite(blanks, sizeof (char), SCREEN_WIDTH - cur_col, stdout);
|
||||
if (COLS != SCREEN_WIDTH)
|
||||
mvcur(cur_row, SCREEN_WIDTH, cur_row, cur_col);
|
||||
else if (AM)
|
||||
mvcur(cur_row + 1, 0, cur_row, cur_col);
|
||||
else
|
||||
mvcur(cur_row, SCREEN_WIDTH - 1, cur_row, cur_col);
|
||||
}
|
||||
memcpy(&screen[cur_row][cur_col], blanks, SCREEN_WIDTH - cur_col);
|
||||
}
|
||||
# endif
|
||||
|
||||
void
|
||||
redraw_screen()
|
||||
{
|
||||
# ifdef USE_CURSES
|
||||
clearok(stdscr, TRUE);
|
||||
touchwin(stdscr);
|
||||
# else
|
||||
int i;
|
||||
# ifndef NOCURSES
|
||||
static int first = 1;
|
||||
|
||||
if (first) {
|
||||
curscr = newwin(SCREEN_HEIGHT, SCREEN_WIDTH, 0, 0);
|
||||
if (curscr == NULL)
|
||||
errx(1, "Can't create curscr");
|
||||
# if !defined(BSD_RELEASE) || BSD_RELEASE < 44
|
||||
for (i = 0; i < SCREEN_HEIGHT; i++)
|
||||
curscr->_y[i] = screen[i];
|
||||
# endif
|
||||
first = 0;
|
||||
}
|
||||
# if defined(BSD_RELEASE) && BSD_RELEASE >= 44
|
||||
for (i = 0; i < SCREEN_HEIGHT; i++) {
|
||||
int j;
|
||||
|
||||
for (j = 0; j < SCREEN_WIDTH; j++)
|
||||
curscr->lines[i]->line[j].ch = screen[i][j];
|
||||
}
|
||||
curscr->cury = cur_row;
|
||||
curscr->curx = cur_col;
|
||||
# else
|
||||
curscr->_cury = cur_row;
|
||||
curscr->_curx = cur_col;
|
||||
# endif
|
||||
clearok(curscr, TRUE);
|
||||
touchwin(curscr);
|
||||
wrefresh(curscr);
|
||||
#else
|
||||
mvcur(cur_row, cur_col, 0, 0);
|
||||
for (i = 0; i < SCREEN_HEIGHT - 1; i++) {
|
||||
fwrite(screen[i], sizeof (char), SCREEN_WIDTH, stdout);
|
||||
if (COLS > SCREEN_WIDTH || (COLS == SCREEN_WIDTH && !AM))
|
||||
putchar('\n');
|
||||
}
|
||||
fwrite(screen[SCREEN_HEIGHT - 1], sizeof (char), SCREEN_WIDTH - 1,
|
||||
stdout);
|
||||
mvcur(SCREEN_HEIGHT - 1, SCREEN_WIDTH - 1, cur_row, cur_col);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* do_message:
|
||||
* Send a message to the driver and return
|
||||
*/
|
||||
void
|
||||
do_message()
|
||||
{
|
||||
long version;
|
||||
|
||||
if (read(Socket, (char *) &version, LONGLEN) != LONGLEN) {
|
||||
bad_con();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
if (ntohl(version) != (unsigned long)HUNT_VERSION) {
|
||||
bad_ver();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
# ifdef INTERNET
|
||||
if (write(Socket, Send_message, strlen(Send_message)) < 0) {
|
||||
bad_con();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
# endif
|
||||
(void) close(Socket);
|
||||
}
|
||||
8
hunt/huntd/Makefile.bsd
Normal file
8
hunt/huntd/Makefile.bsd
Normal file
@@ -0,0 +1,8 @@
|
||||
# $NetBSD: Makefile,v 1.1 1997/10/04 09:11:21 mrg Exp $
|
||||
|
||||
PROG= huntd
|
||||
SRCS= answer.c ctl.c ctl_transact.c draw.c driver.c execute.c expl.c \
|
||||
extern.c faketalk.c get_names.c makemaze.c pathname.c shots.c terminal.c
|
||||
MAN= huntd.6
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
12
hunt/huntd/Makefrag
Normal file
12
hunt/huntd/Makefrag
Normal file
@@ -0,0 +1,12 @@
|
||||
# Makefrag - makefile fragment for hunt/huntd
|
||||
|
||||
include hunt/Makeconfig
|
||||
|
||||
hunt_huntd_DEFS := $(hunt_DEFS)
|
||||
hunt_huntd_DIRS := $(SBINDIR) $(MAN6DIR)
|
||||
|
||||
hunt_huntd_all: hunt/huntd/huntd hunt/huntd/huntd.6
|
||||
|
||||
hunt_huntd_install: hunt_huntd_all
|
||||
$(INSTALL_DAEMON) hunt/huntd/huntd $(INSTALL_PREFIX)$(SBINDIR)/huntd
|
||||
$(INSTALL_MANUAL) hunt/huntd/huntd.6
|
||||
402
hunt/huntd/answer.c
Normal file
402
hunt/huntd/answer.c
Normal file
@@ -0,0 +1,402 @@
|
||||
/* $NetBSD: answer.c,v 1.3 1997/10/10 16:32:50 lukem Exp $ */
|
||||
/*
|
||||
* Hunt
|
||||
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
* San Francisco, California
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: answer.c,v 1.3 1997/10/10 16:32:50 lukem Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
# include <ctype.h>
|
||||
# include <errno.h>
|
||||
# include <fcntl.h>
|
||||
# include <stdlib.h>
|
||||
# include <unistd.h>
|
||||
# include <sys/time.h>
|
||||
# include "hunt.h"
|
||||
|
||||
# define SCOREDECAY 15
|
||||
|
||||
static char Ttyname[NAMELEN];
|
||||
|
||||
int
|
||||
answer()
|
||||
{
|
||||
PLAYER *pp;
|
||||
int newsock;
|
||||
static u_long mode;
|
||||
static char name[NAMELEN];
|
||||
static char team;
|
||||
static int enter_status;
|
||||
static int socklen;
|
||||
static u_long machine;
|
||||
static u_long uid;
|
||||
static SOCKET sockstruct;
|
||||
char *cp1, *cp2;
|
||||
int flags;
|
||||
long version;
|
||||
|
||||
# ifdef INTERNET
|
||||
socklen = sizeof sockstruct;
|
||||
# else
|
||||
socklen = sizeof sockstruct - 1;
|
||||
# endif
|
||||
errno = 0;
|
||||
newsock = accept(Socket, (struct sockaddr *) &sockstruct, &socklen);
|
||||
if (newsock < 0)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
return FALSE;
|
||||
# ifdef LOG
|
||||
syslog(LOG_ERR, "accept: %m");
|
||||
# else
|
||||
perror("accept");
|
||||
# endif
|
||||
cleanup(1);
|
||||
}
|
||||
|
||||
# ifdef INTERNET
|
||||
machine = ntohl(((struct sockaddr_in *) &sockstruct)->sin_addr.s_addr);
|
||||
# else
|
||||
if (machine == 0)
|
||||
machine = gethostid();
|
||||
# endif
|
||||
version = htonl((u_int32_t) HUNT_VERSION);
|
||||
(void) write(newsock, (char *) &version, LONGLEN);
|
||||
(void) read(newsock, (char *) &uid, LONGLEN);
|
||||
uid = ntohl((unsigned long) uid);
|
||||
(void) read(newsock, name, NAMELEN);
|
||||
(void) read(newsock, &team, 1);
|
||||
(void) read(newsock, (char *) &enter_status, LONGLEN);
|
||||
enter_status = ntohl((unsigned long) enter_status);
|
||||
(void) read(newsock, Ttyname, NAMELEN);
|
||||
(void) read(newsock, (char *) &mode, sizeof mode);
|
||||
mode = ntohl(mode);
|
||||
|
||||
/*
|
||||
* Turn off blocking I/O, so a slow or dead terminal won't stop
|
||||
* the game. All subsequent reads check how many bytes they read.
|
||||
*/
|
||||
flags = fcntl(newsock, F_GETFL, 0);
|
||||
flags |= O_NDELAY;
|
||||
(void) fcntl(newsock, F_SETFL, flags);
|
||||
|
||||
/*
|
||||
* Make sure the name contains only printable characters
|
||||
* since we use control characters for cursor control
|
||||
* between driver and player processes
|
||||
*/
|
||||
for (cp1 = cp2 = name; *cp1 != '\0'; cp1++)
|
||||
if (isprint(*cp1) || *cp1 == ' ')
|
||||
*cp2++ = *cp1;
|
||||
*cp2 = '\0';
|
||||
|
||||
# ifdef INTERNET
|
||||
if (mode == C_MESSAGE) {
|
||||
char buf[BUFSIZ + 1];
|
||||
int n;
|
||||
|
||||
if (team == ' ')
|
||||
(void) sprintf(buf, "%s: ", name);
|
||||
else
|
||||
(void) sprintf(buf, "%s[%c]: ", name, team);
|
||||
n = strlen(buf);
|
||||
for (pp = Player; pp < End_player; pp++) {
|
||||
cgoto(pp, HEIGHT, 0);
|
||||
outstr(pp, buf, n);
|
||||
}
|
||||
while ((n = read(newsock, buf, BUFSIZ)) > 0)
|
||||
for (pp = Player; pp < End_player; pp++)
|
||||
outstr(pp, buf, n);
|
||||
for (pp = Player; pp < End_player; pp++) {
|
||||
ce(pp);
|
||||
sendcom(pp, REFRESH);
|
||||
sendcom(pp, READY, 0);
|
||||
(void) fflush(pp->p_output);
|
||||
}
|
||||
(void) close(newsock);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
# endif
|
||||
# ifdef MONITOR
|
||||
if (mode == C_MONITOR)
|
||||
if (End_monitor < &Monitor[MAXMON])
|
||||
pp = End_monitor++;
|
||||
else {
|
||||
socklen = 0;
|
||||
(void) write(newsock, (char *) &socklen,
|
||||
sizeof socklen);
|
||||
(void) close(newsock);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
# endif
|
||||
if (End_player < &Player[MAXPL])
|
||||
pp = End_player++;
|
||||
else {
|
||||
socklen = 0;
|
||||
(void) write(newsock, (char *) &socklen,
|
||||
sizeof socklen);
|
||||
(void) close(newsock);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef MONITOR
|
||||
if (mode == C_MONITOR && team == ' ')
|
||||
team = '*';
|
||||
#endif
|
||||
pp->p_ident = get_ident(machine, uid, name, team);
|
||||
pp->p_output = fdopen(newsock, "w");
|
||||
pp->p_death[0] = '\0';
|
||||
pp->p_fd = newsock;
|
||||
FD_SET(pp->p_fd, &Fds_mask);
|
||||
if (pp->p_fd >= Num_fds)
|
||||
Num_fds = pp->p_fd + 1;
|
||||
|
||||
pp->p_y = 0;
|
||||
pp->p_x = 0;
|
||||
|
||||
# ifdef MONITOR
|
||||
if (mode == C_MONITOR)
|
||||
stmonitor(pp);
|
||||
else
|
||||
# endif
|
||||
stplayer(pp, enter_status);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
# ifdef MONITOR
|
||||
void
|
||||
stmonitor(pp)
|
||||
PLAYER *pp;
|
||||
{
|
||||
int line;
|
||||
PLAYER *npp;
|
||||
|
||||
memcpy(pp->p_maze, Maze, sizeof Maze);
|
||||
|
||||
drawmaze(pp);
|
||||
|
||||
(void) sprintf(Buf, "%5.5s%c%-10.10s %c", " ", stat_char(pp),
|
||||
pp->p_ident->i_name, pp->p_ident->i_team);
|
||||
line = STAT_MON_ROW + 1 + (pp - Monitor);
|
||||
for (npp = Player; npp < End_player; npp++) {
|
||||
cgoto(npp, line, STAT_NAME_COL);
|
||||
outstr(npp, Buf, STAT_NAME_LEN);
|
||||
}
|
||||
for (npp = Monitor; npp < End_monitor; npp++) {
|
||||
cgoto(npp, line, STAT_NAME_COL);
|
||||
outstr(npp, Buf, STAT_NAME_LEN);
|
||||
}
|
||||
|
||||
sendcom(pp, REFRESH);
|
||||
sendcom(pp, READY, 0);
|
||||
(void) fflush(pp->p_output);
|
||||
}
|
||||
# endif
|
||||
|
||||
void
|
||||
stplayer(newpp, enter_status)
|
||||
PLAYER *newpp;
|
||||
int enter_status;
|
||||
{
|
||||
int x, y;
|
||||
PLAYER *pp;
|
||||
|
||||
Nplayer++;
|
||||
|
||||
for (y = 0; y < UBOUND; y++)
|
||||
for (x = 0; x < WIDTH; x++)
|
||||
newpp->p_maze[y][x] = Maze[y][x];
|
||||
for ( ; y < DBOUND; y++) {
|
||||
for (x = 0; x < LBOUND; x++)
|
||||
newpp->p_maze[y][x] = Maze[y][x];
|
||||
for ( ; x < RBOUND; x++)
|
||||
newpp->p_maze[y][x] = SPACE;
|
||||
for ( ; x < WIDTH; x++)
|
||||
newpp->p_maze[y][x] = Maze[y][x];
|
||||
}
|
||||
for ( ; y < HEIGHT; y++)
|
||||
for (x = 0; x < WIDTH; x++)
|
||||
newpp->p_maze[y][x] = Maze[y][x];
|
||||
|
||||
do {
|
||||
x = rand_num(WIDTH - 1) + 1;
|
||||
y = rand_num(HEIGHT - 1) + 1;
|
||||
} while (Maze[y][x] != SPACE);
|
||||
newpp->p_over = SPACE;
|
||||
newpp->p_x = x;
|
||||
newpp->p_y = y;
|
||||
newpp->p_undershot = FALSE;
|
||||
|
||||
# ifdef FLY
|
||||
if (enter_status == Q_FLY) {
|
||||
newpp->p_flying = rand_num(20);
|
||||
newpp->p_flyx = 2 * rand_num(6) - 5;
|
||||
newpp->p_flyy = 2 * rand_num(6) - 5;
|
||||
newpp->p_face = FLYER;
|
||||
}
|
||||
else
|
||||
# endif
|
||||
{
|
||||
newpp->p_flying = -1;
|
||||
newpp->p_face = rand_dir();
|
||||
}
|
||||
newpp->p_damage = 0;
|
||||
newpp->p_damcap = MAXDAM;
|
||||
newpp->p_nchar = 0;
|
||||
newpp->p_ncount = 0;
|
||||
newpp->p_nexec = 0;
|
||||
newpp->p_ammo = ISHOTS;
|
||||
# ifdef BOOTS
|
||||
newpp->p_nboots = 0;
|
||||
# endif
|
||||
if (enter_status == Q_SCAN) {
|
||||
newpp->p_scan = SCANLEN;
|
||||
newpp->p_cloak = 0;
|
||||
}
|
||||
else {
|
||||
newpp->p_scan = 0;
|
||||
newpp->p_cloak = CLOAKLEN;
|
||||
}
|
||||
newpp->p_ncshot = 0;
|
||||
|
||||
do {
|
||||
x = rand_num(WIDTH - 1) + 1;
|
||||
y = rand_num(HEIGHT - 1) + 1;
|
||||
} while (Maze[y][x] != SPACE);
|
||||
Maze[y][x] = GMINE;
|
||||
# ifdef MONITOR
|
||||
for (pp = Monitor; pp < End_monitor; pp++)
|
||||
check(pp, y, x);
|
||||
# endif
|
||||
|
||||
do {
|
||||
x = rand_num(WIDTH - 1) + 1;
|
||||
y = rand_num(HEIGHT - 1) + 1;
|
||||
} while (Maze[y][x] != SPACE);
|
||||
Maze[y][x] = MINE;
|
||||
# ifdef MONITOR
|
||||
for (pp = Monitor; pp < End_monitor; pp++)
|
||||
check(pp, y, x);
|
||||
# endif
|
||||
|
||||
(void) sprintf(Buf, "%5.2f%c%-10.10s %c", newpp->p_ident->i_score,
|
||||
stat_char(newpp), newpp->p_ident->i_name,
|
||||
newpp->p_ident->i_team);
|
||||
y = STAT_PLAY_ROW + 1 + (newpp - Player);
|
||||
for (pp = Player; pp < End_player; pp++) {
|
||||
if (pp != newpp) {
|
||||
char smallbuf[10];
|
||||
|
||||
pp->p_ammo += NSHOTS;
|
||||
newpp->p_ammo += NSHOTS;
|
||||
cgoto(pp, y, STAT_NAME_COL);
|
||||
outstr(pp, Buf, STAT_NAME_LEN);
|
||||
(void) sprintf(smallbuf, "%3d", pp->p_ammo);
|
||||
cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
|
||||
outstr(pp, smallbuf, 3);
|
||||
}
|
||||
}
|
||||
# ifdef MONITOR
|
||||
for (pp = Monitor; pp < End_monitor; pp++) {
|
||||
cgoto(pp, y, STAT_NAME_COL);
|
||||
outstr(pp, Buf, STAT_NAME_LEN);
|
||||
}
|
||||
# endif
|
||||
|
||||
drawmaze(newpp);
|
||||
drawplayer(newpp, TRUE);
|
||||
look(newpp);
|
||||
# ifdef FLY
|
||||
if (enter_status == Q_FLY)
|
||||
/* Make sure that the position you enter in will be erased */
|
||||
showexpl(newpp->p_y, newpp->p_x, FLYER);
|
||||
# endif
|
||||
sendcom(newpp, REFRESH);
|
||||
sendcom(newpp, READY, 0);
|
||||
(void) fflush(newpp->p_output);
|
||||
}
|
||||
|
||||
/*
|
||||
* rand_dir:
|
||||
* Return a random direction
|
||||
*/
|
||||
int
|
||||
rand_dir()
|
||||
{
|
||||
switch (rand_num(4)) {
|
||||
case 0:
|
||||
return LEFTS;
|
||||
case 1:
|
||||
return RIGHT;
|
||||
case 2:
|
||||
return BELOW;
|
||||
case 3:
|
||||
return ABOVE;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* get_ident:
|
||||
* Get the score structure of a player
|
||||
*/
|
||||
IDENT *
|
||||
get_ident(machine, uid, name, team)
|
||||
u_long machine;
|
||||
u_long uid;
|
||||
const char *name;
|
||||
char team;
|
||||
{
|
||||
IDENT *ip;
|
||||
static IDENT punt;
|
||||
|
||||
for (ip = Scores; ip != NULL; ip = ip->i_next)
|
||||
if ((unsigned long)ip->i_machine == machine
|
||||
&& (unsigned long)ip->i_uid == uid
|
||||
&& ip->i_team == team
|
||||
&& strncmp(ip->i_name, name, NAMELEN) == 0)
|
||||
break;
|
||||
|
||||
if (ip != NULL) {
|
||||
if (ip->i_entries < SCOREDECAY)
|
||||
ip->i_entries++;
|
||||
else
|
||||
ip->i_kills = (ip->i_kills * (SCOREDECAY - 1))
|
||||
/ SCOREDECAY;
|
||||
ip->i_score = ip->i_kills / (double) ip->i_entries;
|
||||
}
|
||||
else {
|
||||
ip = (IDENT *) malloc(sizeof (IDENT));
|
||||
if (ip == NULL) {
|
||||
/* Fourth down, time to punt */
|
||||
ip = &punt;
|
||||
}
|
||||
ip->i_machine = machine;
|
||||
ip->i_team = team;
|
||||
ip->i_uid = uid;
|
||||
strncpy(ip->i_name, name, NAMELEN);
|
||||
ip->i_kills = 0;
|
||||
ip->i_entries = 1;
|
||||
ip->i_score = 0;
|
||||
ip->i_absorbed = 0;
|
||||
ip->i_faced = 0;
|
||||
ip->i_shot = 0;
|
||||
ip->i_robbed = 0;
|
||||
ip->i_slime = 0;
|
||||
ip->i_missed = 0;
|
||||
ip->i_ducked = 0;
|
||||
ip->i_gkills = ip->i_bkills = ip->i_deaths = 0;
|
||||
ip->i_stillb = ip->i_saved = 0;
|
||||
ip->i_next = Scores;
|
||||
Scores = ip;
|
||||
}
|
||||
|
||||
return ip;
|
||||
}
|
||||
21
hunt/huntd/bsd.h
Normal file
21
hunt/huntd/bsd.h
Normal file
@@ -0,0 +1,21 @@
|
||||
/* $NetBSD: bsd.h,v 1.2 1998/01/09 08:03:40 perry Exp $ */
|
||||
|
||||
/*
|
||||
* Hunt
|
||||
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
* San Francisco, California
|
||||
*/
|
||||
|
||||
# if defined(BSD_RELEASE) && BSD_RELEASE >= 43
|
||||
# define BROADCAST
|
||||
# define SYSLOG_43
|
||||
#ifdef __linux__
|
||||
#define TALK_42 /* Kludge around broken <protocols/talkd.h> */
|
||||
#else
|
||||
# define TALK_43
|
||||
#endif
|
||||
# endif
|
||||
# if defined(BSD_RELEASE) && BSD_RELEASE == 42
|
||||
# define SYSLOG_42
|
||||
# define TALK_42
|
||||
# endif
|
||||
60
hunt/huntd/ctl.c
Normal file
60
hunt/huntd/ctl.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/* $NetBSD: ctl.c,v 1.2 1997/10/10 16:32:54 lukem Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1983 Regents of the University of California.
|
||||
* All rights reserved. The Berkeley software License Agreement
|
||||
* specifies the terms and conditions for redistribution.
|
||||
*/
|
||||
|
||||
#include "bsd.h"
|
||||
|
||||
#if defined(TALK_43) || defined(TALK_42)
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)ctl.c 5.2 (Berkeley) 3/13/86";
|
||||
#else
|
||||
__RCSID("$NetBSD: ctl.c,v 1.2 1997/10/10 16:32:54 lukem Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
* This file handles haggling with the various talk daemons to
|
||||
* get a socket to talk to. sockt is opened and connected in
|
||||
* the progress
|
||||
*/
|
||||
|
||||
#include "hunt.h"
|
||||
#include "talk_ctl.h"
|
||||
|
||||
struct sockaddr_in daemon_addr = { AF_INET };
|
||||
struct sockaddr_in ctl_addr = { AF_INET };
|
||||
|
||||
/* inet addresses of the two machines */
|
||||
struct in_addr my_machine_addr;
|
||||
struct in_addr his_machine_addr;
|
||||
|
||||
u_short daemon_port; /* port number of the talk daemon */
|
||||
|
||||
int ctl_sockt;
|
||||
|
||||
CTL_MSG msg;
|
||||
|
||||
/* open the ctl socket */
|
||||
void
|
||||
open_ctl()
|
||||
{
|
||||
int length;
|
||||
|
||||
ctl_addr.sin_port = 0;
|
||||
ctl_addr.sin_addr = my_machine_addr;
|
||||
ctl_sockt = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (ctl_sockt <= 0)
|
||||
p_error("Bad socket");
|
||||
if (bind(ctl_sockt, (struct sockaddr *)&ctl_addr, sizeof(ctl_addr)) != 0)
|
||||
p_error("Couldn't bind to control socket");
|
||||
length = sizeof(ctl_addr);
|
||||
if (getsockname(ctl_sockt, (struct sockaddr *) &ctl_addr, &length) < 0)
|
||||
p_error("Bad address for ctl socket");
|
||||
}
|
||||
#endif
|
||||
113
hunt/huntd/ctl_transact.c
Normal file
113
hunt/huntd/ctl_transact.c
Normal file
@@ -0,0 +1,113 @@
|
||||
/* $NetBSD: ctl_transact.c,v 1.3 1997/10/20 00:37:16 lukem Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1983 Regents of the University of California.
|
||||
* All rights reserved. The Berkeley software License Agreement
|
||||
* specifies the terms and conditions for redistribution.
|
||||
*/
|
||||
|
||||
#include "bsd.h"
|
||||
|
||||
#if defined(TALK_43) || defined(TALK_42)
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)ctl_transact.c 5.2 (Berkeley) 3/13/86";
|
||||
#else
|
||||
__RCSID("$NetBSD: ctl_transact.c,v 1.3 1997/10/20 00:37:16 lukem Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include "hunt.h"
|
||||
#include "talk_ctl.h"
|
||||
|
||||
#define CTL_WAIT 2 /* time to wait for a response, in seconds */
|
||||
#define MAX_RETRY 5
|
||||
|
||||
/*
|
||||
* SOCKDGRAM is unreliable, so we must repeat messages if we have
|
||||
* not recieved an acknowledgement within a reasonable amount
|
||||
* of time
|
||||
*/
|
||||
void
|
||||
ctl_transact(target, msg, type, rp)
|
||||
struct in_addr target;
|
||||
CTL_MSG msg;
|
||||
int type;
|
||||
CTL_RESPONSE *rp;
|
||||
{
|
||||
fd_set read_mask, ctl_mask;
|
||||
int nready, cc, retries;
|
||||
struct timeval wait;
|
||||
|
||||
nready = 0;
|
||||
msg.type = type;
|
||||
daemon_addr.sin_addr = target;
|
||||
daemon_addr.sin_port = daemon_port;
|
||||
FD_ZERO(&ctl_mask);
|
||||
FD_SET(ctl_sockt, &ctl_mask);
|
||||
|
||||
/*
|
||||
* Keep sending the message until a response of
|
||||
* the proper type is obtained.
|
||||
*/
|
||||
do {
|
||||
wait.tv_sec = CTL_WAIT;
|
||||
wait.tv_usec = 0;
|
||||
/* resend message until a response is obtained */
|
||||
for (retries = MAX_RETRY; retries > 0; retries -= 1) {
|
||||
cc = sendto(ctl_sockt, (char *)&msg, sizeof (msg), 0,
|
||||
(struct sockaddr *)&daemon_addr, sizeof (daemon_addr));
|
||||
if (cc != sizeof (msg)) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
p_error("Error on write to talk daemon");
|
||||
}
|
||||
read_mask = ctl_mask;
|
||||
nready = select(32, &read_mask, 0, 0, &wait);
|
||||
if (nready < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
p_error("Error waiting for daemon response");
|
||||
}
|
||||
if (nready != 0)
|
||||
break;
|
||||
}
|
||||
if (retries <= 0)
|
||||
break;
|
||||
/*
|
||||
* Keep reading while there are queued messages
|
||||
* (this is not necessary, it just saves extra
|
||||
* request/acknowledgements being sent)
|
||||
*/
|
||||
do {
|
||||
cc = recv(ctl_sockt, (char *)rp, sizeof (*rp), 0);
|
||||
if (cc < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
p_error("Error on read from talk daemon");
|
||||
}
|
||||
read_mask = ctl_mask;
|
||||
/* an immediate poll */
|
||||
timerclear(&wait);
|
||||
nready = select(32, &read_mask, 0, 0, &wait);
|
||||
} while (nready > 0 && (
|
||||
#ifdef TALK_43
|
||||
rp->vers != TALK_VERSION ||
|
||||
#endif
|
||||
rp->type != type));
|
||||
} while (
|
||||
#ifdef TALK_43
|
||||
rp->vers != TALK_VERSION ||
|
||||
#endif
|
||||
rp->type != type);
|
||||
rp->id_num = ntohl(rp->id_num);
|
||||
#ifdef TALK_43
|
||||
rp->addr.sa_family = ntohs(rp->addr.sa_family);
|
||||
# else
|
||||
rp->addr.sin_family = ntohs(rp->addr.sin_family);
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
381
hunt/huntd/draw.c
Normal file
381
hunt/huntd/draw.c
Normal file
@@ -0,0 +1,381 @@
|
||||
/* $NetBSD: draw.c,v 1.2 1997/10/10 16:33:04 lukem Exp $ */
|
||||
/*
|
||||
* Hunt
|
||||
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
* San Francisco, California
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: draw.c,v 1.2 1997/10/10 16:33:04 lukem Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
# include "hunt.h"
|
||||
|
||||
void
|
||||
drawmaze(pp)
|
||||
PLAYER *pp;
|
||||
{
|
||||
int x;
|
||||
char *sp;
|
||||
int y;
|
||||
char *endp;
|
||||
|
||||
clrscr(pp);
|
||||
outstr(pp, pp->p_maze[0], WIDTH);
|
||||
for (y = 1; y < HEIGHT - 1; y++) {
|
||||
endp = &pp->p_maze[y][WIDTH];
|
||||
for (x = 0, sp = pp->p_maze[y]; sp < endp; x++, sp++)
|
||||
if (*sp != SPACE) {
|
||||
cgoto(pp, y, x);
|
||||
if (pp->p_x == x && pp->p_y == y)
|
||||
outch(pp, translate(*sp));
|
||||
else if (is_player(*sp))
|
||||
outch(pp, player_sym(pp, y, x));
|
||||
else
|
||||
outch(pp, *sp);
|
||||
}
|
||||
}
|
||||
cgoto(pp, HEIGHT - 1, 0);
|
||||
outstr(pp, pp->p_maze[HEIGHT - 1], WIDTH);
|
||||
drawstatus(pp);
|
||||
}
|
||||
|
||||
/*
|
||||
* drawstatus - put up the status lines (this assumes the screen
|
||||
* size is 80x24 with the maze being 64x24)
|
||||
*/
|
||||
void
|
||||
drawstatus(pp)
|
||||
PLAYER *pp;
|
||||
{
|
||||
int i;
|
||||
PLAYER *np;
|
||||
|
||||
cgoto(pp, STAT_AMMO_ROW, STAT_LABEL_COL);
|
||||
outstr(pp, "Ammo:", 5);
|
||||
(void) sprintf(Buf, "%3d", pp->p_ammo);
|
||||
cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
|
||||
outstr(pp, Buf, 3);
|
||||
|
||||
cgoto(pp, STAT_GUN_ROW, STAT_LABEL_COL);
|
||||
outstr(pp, "Gun:", 4);
|
||||
cgoto(pp, STAT_GUN_ROW, STAT_VALUE_COL);
|
||||
outstr(pp, (pp->p_ncshot < MAXNCSHOT) ? " ok" : " ", 3);
|
||||
|
||||
cgoto(pp, STAT_DAM_ROW, STAT_LABEL_COL);
|
||||
outstr(pp, "Damage:", 7);
|
||||
(void) sprintf(Buf, "%2d/%2d", pp->p_damage, pp->p_damcap);
|
||||
cgoto(pp, STAT_DAM_ROW, STAT_VALUE_COL);
|
||||
outstr(pp, Buf, 5);
|
||||
|
||||
cgoto(pp, STAT_KILL_ROW, STAT_LABEL_COL);
|
||||
outstr(pp, "Kills:", 6);
|
||||
(void) sprintf(Buf, "%3d", (pp->p_damcap - MAXDAM) / 2);
|
||||
cgoto(pp, STAT_KILL_ROW, STAT_VALUE_COL);
|
||||
outstr(pp, Buf, 3);
|
||||
|
||||
cgoto(pp, STAT_PLAY_ROW, STAT_LABEL_COL);
|
||||
outstr(pp, "Player:", 7);
|
||||
for (i = STAT_PLAY_ROW + 1, np = Player; np < End_player; np++) {
|
||||
(void) sprintf(Buf, "%5.2f%c%-10.10s %c", np->p_ident->i_score,
|
||||
stat_char(np), np->p_ident->i_name,
|
||||
np->p_ident->i_team);
|
||||
cgoto(pp, i++, STAT_NAME_COL);
|
||||
outstr(pp, Buf, STAT_NAME_LEN);
|
||||
}
|
||||
|
||||
# ifdef MONITOR
|
||||
cgoto(pp, STAT_MON_ROW, STAT_LABEL_COL);
|
||||
outstr(pp, "Monitor:", 8);
|
||||
for (i = STAT_MON_ROW + 1, np = Monitor; np < End_monitor; np++) {
|
||||
(void) sprintf(Buf, "%5.5s %-10.10s %c", " ",
|
||||
np->p_ident->i_name, np->p_ident->i_team);
|
||||
cgoto(pp, i++, STAT_NAME_COL);
|
||||
outstr(pp, Buf, STAT_NAME_LEN);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
void
|
||||
look(pp)
|
||||
PLAYER *pp;
|
||||
{
|
||||
int x, y;
|
||||
|
||||
x = pp->p_x;
|
||||
y = pp->p_y;
|
||||
|
||||
check(pp, y - 1, x - 1);
|
||||
check(pp, y - 1, x );
|
||||
check(pp, y - 1, x + 1);
|
||||
check(pp, y , x - 1);
|
||||
check(pp, y , x );
|
||||
check(pp, y , x + 1);
|
||||
check(pp, y + 1, x - 1);
|
||||
check(pp, y + 1, x );
|
||||
check(pp, y + 1, x + 1);
|
||||
|
||||
switch (pp->p_face) {
|
||||
case LEFTS:
|
||||
see(pp, LEFTS);
|
||||
see(pp, ABOVE);
|
||||
see(pp, BELOW);
|
||||
break;
|
||||
case RIGHT:
|
||||
see(pp, RIGHT);
|
||||
see(pp, ABOVE);
|
||||
see(pp, BELOW);
|
||||
break;
|
||||
case ABOVE:
|
||||
see(pp, ABOVE);
|
||||
see(pp, LEFTS);
|
||||
see(pp, RIGHT);
|
||||
break;
|
||||
case BELOW:
|
||||
see(pp, BELOW);
|
||||
see(pp, LEFTS);
|
||||
see(pp, RIGHT);
|
||||
break;
|
||||
# ifdef FLY
|
||||
case FLYER:
|
||||
break;
|
||||
# endif
|
||||
}
|
||||
cgoto(pp, y, x);
|
||||
}
|
||||
|
||||
void
|
||||
see(pp, face)
|
||||
PLAYER *pp;
|
||||
int face;
|
||||
{
|
||||
char *sp;
|
||||
int y, x, i, cnt;
|
||||
|
||||
x = pp->p_x;
|
||||
y = pp->p_y;
|
||||
|
||||
switch (face) {
|
||||
case LEFTS:
|
||||
sp = &Maze[y][x];
|
||||
for (i = 0; See_over[(int)*--sp]; i++)
|
||||
continue;
|
||||
|
||||
if (i == 0)
|
||||
break;
|
||||
|
||||
cnt = i;
|
||||
x = pp->p_x - 1;
|
||||
--y;
|
||||
while (i--)
|
||||
check(pp, y, --x);
|
||||
i = cnt;
|
||||
x = pp->p_x - 1;
|
||||
++y;
|
||||
while (i--)
|
||||
check(pp, y, --x);
|
||||
i = cnt;
|
||||
x = pp->p_x - 1;
|
||||
++y;
|
||||
while (i--)
|
||||
check(pp, y, --x);
|
||||
break;
|
||||
case RIGHT:
|
||||
sp = &Maze[y][++x];
|
||||
for (i = 0; See_over[(int)*sp++]; i++)
|
||||
continue;
|
||||
|
||||
if (i == 0)
|
||||
break;
|
||||
|
||||
cnt = i;
|
||||
x = pp->p_x + 1;
|
||||
--y;
|
||||
while (i--)
|
||||
check(pp, y, ++x);
|
||||
i = cnt;
|
||||
x = pp->p_x + 1;
|
||||
++y;
|
||||
while (i--)
|
||||
check(pp, y, ++x);
|
||||
i = cnt;
|
||||
x = pp->p_x + 1;
|
||||
++y;
|
||||
while (i--)
|
||||
check(pp, y, ++x);
|
||||
break;
|
||||
case ABOVE:
|
||||
sp = &Maze[--y][x];
|
||||
if (!See_over[(int)*sp])
|
||||
break;
|
||||
do {
|
||||
--y;
|
||||
sp -= sizeof Maze[0];
|
||||
check(pp, y, x - 1);
|
||||
check(pp, y, x );
|
||||
check(pp, y, x + 1);
|
||||
} while (See_over[(int)*sp]);
|
||||
break;
|
||||
case BELOW:
|
||||
sp = &Maze[++y][x];
|
||||
if (!See_over[(int)*sp])
|
||||
break;
|
||||
do {
|
||||
y++;
|
||||
sp += sizeof Maze[0];
|
||||
check(pp, y, x - 1);
|
||||
check(pp, y, x );
|
||||
check(pp, y, x + 1);
|
||||
} while (See_over[(int)*sp]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
check(pp, y, x)
|
||||
PLAYER *pp;
|
||||
int y, x;
|
||||
{
|
||||
int index;
|
||||
int ch;
|
||||
PLAYER *rpp;
|
||||
|
||||
index = y * sizeof Maze[0] + x;
|
||||
ch = ((char *) Maze)[index];
|
||||
if (ch != ((char *) pp->p_maze)[index]) {
|
||||
rpp = pp;
|
||||
cgoto(rpp, y, x);
|
||||
if (x == rpp->p_x && y == rpp->p_y)
|
||||
outch(rpp, translate(ch));
|
||||
else if (is_player(ch))
|
||||
outch(rpp, player_sym(rpp, y, x));
|
||||
else
|
||||
outch(rpp, ch);
|
||||
((char *) rpp->p_maze)[index] = ch;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* showstat
|
||||
* Update the status of players
|
||||
*/
|
||||
void
|
||||
showstat(pp)
|
||||
PLAYER *pp;
|
||||
{
|
||||
PLAYER *np;
|
||||
int y;
|
||||
char c;
|
||||
|
||||
y = STAT_PLAY_ROW + 1 + (pp - Player);
|
||||
c = stat_char(pp);
|
||||
# ifdef MONITOR
|
||||
for (np = Monitor; np < End_monitor; np++) {
|
||||
cgoto(np, y, STAT_SCAN_COL);
|
||||
outch(np, c);
|
||||
}
|
||||
# endif
|
||||
for (np = Player; np < End_player; np++) {
|
||||
cgoto(np, y, STAT_SCAN_COL);
|
||||
outch(np, c);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* drawplayer:
|
||||
* Draw the player on the screen and show him to everyone who's scanning
|
||||
* unless he is cloaked.
|
||||
*/
|
||||
void
|
||||
drawplayer(pp, draw)
|
||||
PLAYER *pp;
|
||||
FLAG draw;
|
||||
{
|
||||
PLAYER *newp;
|
||||
int x, y;
|
||||
|
||||
x = pp->p_x;
|
||||
y = pp->p_y;
|
||||
Maze[y][x] = draw ? pp->p_face : pp->p_over;
|
||||
|
||||
# ifdef MONITOR
|
||||
for (newp = Monitor; newp < End_monitor; newp++)
|
||||
check(newp, y, x);
|
||||
# endif
|
||||
|
||||
for (newp = Player; newp < End_player; newp++) {
|
||||
if (!draw || newp == pp) {
|
||||
check(newp, y, x);
|
||||
continue;
|
||||
}
|
||||
if (newp->p_scan == 0) {
|
||||
newp->p_scan--;
|
||||
showstat(newp);
|
||||
}
|
||||
else if (newp->p_scan > 0) {
|
||||
if (pp->p_cloak < 0)
|
||||
check(newp, y, x);
|
||||
newp->p_scan--;
|
||||
}
|
||||
}
|
||||
if (!draw || pp->p_cloak < 0)
|
||||
return;
|
||||
if (pp->p_cloak-- == 0)
|
||||
showstat(pp);
|
||||
}
|
||||
|
||||
void
|
||||
message(pp, s)
|
||||
PLAYER *pp;
|
||||
const char *s;
|
||||
{
|
||||
cgoto(pp, HEIGHT, 0);
|
||||
outstr(pp, s, strlen(s));
|
||||
ce(pp);
|
||||
}
|
||||
|
||||
/*
|
||||
* translate:
|
||||
* Turn a character into the right direction character if we are
|
||||
* looking at the current player.
|
||||
*/
|
||||
char
|
||||
translate(ch)
|
||||
char ch;
|
||||
{
|
||||
switch (ch) {
|
||||
case LEFTS:
|
||||
return '<';
|
||||
case RIGHT:
|
||||
return '>';
|
||||
case ABOVE:
|
||||
return '^';
|
||||
case BELOW:
|
||||
return 'v';
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
|
||||
/*
|
||||
* player_sym:
|
||||
* Return the player symbol
|
||||
*/
|
||||
int
|
||||
player_sym(pp, y, x)
|
||||
const PLAYER *pp;
|
||||
int y, x;
|
||||
{
|
||||
PLAYER *npp;
|
||||
|
||||
npp = play_at(y, x);
|
||||
if (npp->p_ident->i_team == ' ')
|
||||
return Maze[y][x];
|
||||
#ifdef MONITOR
|
||||
if (pp->p_ident->i_team == '*')
|
||||
return npp->p_ident->i_team;
|
||||
#endif
|
||||
if (pp->p_ident->i_team != npp->p_ident->i_team)
|
||||
return Maze[y][x];
|
||||
return pp->p_ident->i_team;
|
||||
}
|
||||
976
hunt/huntd/driver.c
Normal file
976
hunt/huntd/driver.c
Normal file
@@ -0,0 +1,976 @@
|
||||
/* $NetBSD: driver.c,v 1.5 1997/10/20 00:37:16 lukem Exp $ */
|
||||
/*
|
||||
* Hunt
|
||||
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
* San Francisco, California
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: driver.c,v 1.5 1997/10/20 00:37:16 lukem Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
# include <sys/ioctl.h>
|
||||
# include <sys/stat.h>
|
||||
# include <sys/time.h>
|
||||
# include <err.h>
|
||||
# include <errno.h>
|
||||
# include <signal.h>
|
||||
# include <stdlib.h>
|
||||
# include <unistd.h>
|
||||
# include "hunt.h"
|
||||
|
||||
# ifndef pdp11
|
||||
# define RN (((Seed = Seed * 11109 + 13849) >> 16) & 0xffff)
|
||||
# else
|
||||
# define RN ((Seed = Seed * 11109 + 13849) & 0x7fff)
|
||||
# endif
|
||||
|
||||
int Seed = 0;
|
||||
|
||||
|
||||
SOCKET Daemon;
|
||||
char *First_arg; /* pointer to argv[0] */
|
||||
char *Last_arg; /* pointer to end of argv/environ */
|
||||
# ifdef INTERNET
|
||||
int Test_socket; /* test socket to answer datagrams */
|
||||
FLAG inetd_spawned; /* invoked via inetd */
|
||||
FLAG standard_port = TRUE; /* true if listening on standard port */
|
||||
u_short sock_port; /* port # of tcp listen socket */
|
||||
u_short stat_port; /* port # of statistics tcp socket */
|
||||
# define DAEMON_SIZE (sizeof Daemon)
|
||||
# else
|
||||
# define DAEMON_SIZE (sizeof Daemon - 1)
|
||||
# endif
|
||||
|
||||
static void clear_scores __P((void));
|
||||
static int havechar __P((PLAYER *));
|
||||
static void init __P((void));
|
||||
int main __P((int, char *[], char *[]));
|
||||
static void makeboots __P((void));
|
||||
static void send_stats __P((void));
|
||||
static void zap __P((PLAYER *, FLAG));
|
||||
|
||||
|
||||
/*
|
||||
* main:
|
||||
* The main program.
|
||||
*/
|
||||
int
|
||||
main(ac, av, ep)
|
||||
int ac;
|
||||
char **av, **ep;
|
||||
{
|
||||
PLAYER *pp;
|
||||
int had_char;
|
||||
# ifdef INTERNET
|
||||
u_short msg;
|
||||
short port_num, reply;
|
||||
int namelen;
|
||||
SOCKET test;
|
||||
# endif
|
||||
static fd_set read_fds;
|
||||
static FLAG first = TRUE;
|
||||
static FLAG server = FALSE;
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
int c;
|
||||
static struct timeval linger = { 90, 0 };
|
||||
|
||||
First_arg = av[0];
|
||||
if (ep == NULL || *ep == NULL)
|
||||
ep = av + ac;
|
||||
while (*ep)
|
||||
ep++;
|
||||
Last_arg = ep[-1] + strlen(ep[-1]);
|
||||
|
||||
while ((c = getopt(ac, av, "sp:")) != -1) {
|
||||
switch (c) {
|
||||
case 's':
|
||||
server = TRUE;
|
||||
break;
|
||||
# ifdef INTERNET
|
||||
case 'p':
|
||||
standard_port = FALSE;
|
||||
Test_port = atoi(optarg);
|
||||
break;
|
||||
# endif
|
||||
default:
|
||||
erred:
|
||||
fprintf(stderr, "Usage: %s [-s] [-p port]\n", av[0]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (optind < ac)
|
||||
goto erred;
|
||||
|
||||
init();
|
||||
|
||||
|
||||
again:
|
||||
do {
|
||||
read_fds = Fds_mask;
|
||||
errno = 0;
|
||||
while (select(Num_fds, &read_fds, NULL, NULL, NULL) < 0)
|
||||
{
|
||||
if (errno != EINTR)
|
||||
# ifdef LOG
|
||||
syslog(LOG_WARNING, "select: %m");
|
||||
# else
|
||||
warn("select");
|
||||
# endif
|
||||
errno = 0;
|
||||
}
|
||||
Have_inp = read_fds;
|
||||
# ifdef INTERNET
|
||||
if (FD_ISSET(Test_socket, &read_fds)) {
|
||||
namelen = DAEMON_SIZE;
|
||||
port_num = htons(sock_port);
|
||||
(void) recvfrom(Test_socket, (char *) &msg, sizeof msg,
|
||||
0, (struct sockaddr *) &test, &namelen);
|
||||
switch (ntohs(msg)) {
|
||||
case C_MESSAGE:
|
||||
if (Nplayer <= 0)
|
||||
break;
|
||||
reply = htons((u_short) Nplayer);
|
||||
(void) sendto(Test_socket, (char *) &reply,
|
||||
sizeof reply, 0,
|
||||
(struct sockaddr *) &test, DAEMON_SIZE);
|
||||
break;
|
||||
case C_SCORES:
|
||||
reply = htons(stat_port);
|
||||
(void) sendto(Test_socket, (char *) &reply,
|
||||
sizeof reply, 0,
|
||||
(struct sockaddr *) &test, DAEMON_SIZE);
|
||||
break;
|
||||
case C_PLAYER:
|
||||
case C_MONITOR:
|
||||
if (msg == C_MONITOR && Nplayer <= 0)
|
||||
break;
|
||||
reply = htons(sock_port);
|
||||
(void) sendto(Test_socket, (char *) &reply,
|
||||
sizeof reply, 0,
|
||||
(struct sockaddr *) &test, DAEMON_SIZE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
for (;;) {
|
||||
had_char = FALSE;
|
||||
for (pp = Player; pp < End_player; pp++)
|
||||
if (havechar(pp)) {
|
||||
execute(pp);
|
||||
pp->p_nexec++;
|
||||
had_char++;
|
||||
}
|
||||
# ifdef MONITOR
|
||||
for (pp = Monitor; pp < End_monitor; pp++)
|
||||
if (havechar(pp)) {
|
||||
mon_execute(pp);
|
||||
pp->p_nexec++;
|
||||
had_char++;
|
||||
}
|
||||
# endif
|
||||
if (!had_char)
|
||||
break;
|
||||
moveshots();
|
||||
for (pp = Player; pp < End_player; )
|
||||
if (pp->p_death[0] != '\0')
|
||||
zap(pp, TRUE);
|
||||
else
|
||||
pp++;
|
||||
# ifdef MONITOR
|
||||
for (pp = Monitor; pp < End_monitor; )
|
||||
if (pp->p_death[0] != '\0')
|
||||
zap(pp, FALSE);
|
||||
else
|
||||
pp++;
|
||||
# endif
|
||||
}
|
||||
if (FD_ISSET(Socket, &read_fds))
|
||||
if (answer()) {
|
||||
# ifdef INTERNET
|
||||
if (first && standard_port)
|
||||
faketalk();
|
||||
# endif
|
||||
first = FALSE;
|
||||
}
|
||||
if (FD_ISSET(Status, &read_fds))
|
||||
send_stats();
|
||||
for (pp = Player; pp < End_player; pp++) {
|
||||
if (FD_ISSET(pp->p_fd, &read_fds))
|
||||
sendcom(pp, READY, pp->p_nexec);
|
||||
pp->p_nexec = 0;
|
||||
(void) fflush(pp->p_output);
|
||||
}
|
||||
# ifdef MONITOR
|
||||
for (pp = Monitor; pp < End_monitor; pp++) {
|
||||
if (FD_ISSET(pp->p_fd, &read_fds))
|
||||
sendcom(pp, READY, pp->p_nexec);
|
||||
pp->p_nexec = 0;
|
||||
(void) fflush(pp->p_output);
|
||||
}
|
||||
# endif
|
||||
} while (Nplayer > 0);
|
||||
|
||||
read_fds = Fds_mask;
|
||||
if (select(Num_fds, &read_fds, NULL, NULL, &linger) > 0) {
|
||||
goto again;
|
||||
}
|
||||
if (server) {
|
||||
clear_scores();
|
||||
makemaze();
|
||||
clearwalls();
|
||||
# ifdef BOOTS
|
||||
makeboots();
|
||||
# endif
|
||||
first = TRUE;
|
||||
goto again;
|
||||
}
|
||||
|
||||
# ifdef MONITOR
|
||||
for (pp = Monitor; pp < End_monitor; )
|
||||
zap(pp, FALSE);
|
||||
# endif
|
||||
cleanup(0);
|
||||
/* NOTREACHED */
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* init:
|
||||
* Initialize the global parameters.
|
||||
*/
|
||||
static void
|
||||
init()
|
||||
{
|
||||
int i;
|
||||
# ifdef INTERNET
|
||||
SOCKET test_port;
|
||||
int msg;
|
||||
int len;
|
||||
# endif
|
||||
|
||||
# ifndef DEBUG
|
||||
if (setsid() == -1)
|
||||
err(1, "setsid");
|
||||
(void) signal(SIGHUP, SIG_IGN);
|
||||
(void) signal(SIGINT, SIG_IGN);
|
||||
(void) signal(SIGQUIT, SIG_IGN);
|
||||
(void) signal(SIGTERM, cleanup);
|
||||
# endif
|
||||
|
||||
(void) chdir("/var/tmp"); /* just in case it core dumps */
|
||||
(void) umask(0); /* No privacy at all! */
|
||||
(void) signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
# ifdef LOG
|
||||
# ifdef SYSLOG_43
|
||||
openlog("HUNT", LOG_PID, LOG_DAEMON);
|
||||
# endif
|
||||
# ifdef SYSLOG_42
|
||||
openlog("HUNT", LOG_PID);
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/*
|
||||
* Initialize statistics socket
|
||||
*/
|
||||
# ifdef INTERNET
|
||||
Daemon.sin_family = SOCK_FAMILY;
|
||||
Daemon.sin_addr.s_addr = INADDR_ANY;
|
||||
Daemon.sin_port = 0;
|
||||
# else
|
||||
Daemon.sun_family = SOCK_FAMILY;
|
||||
(void) strcpy(Daemon.sun_path, Stat_name);
|
||||
# endif
|
||||
|
||||
Status = socket(SOCK_FAMILY, SOCK_STREAM, 0);
|
||||
if (bind(Status, (struct sockaddr *) &Daemon, DAEMON_SIZE) < 0) {
|
||||
if (errno == EADDRINUSE)
|
||||
exit(0);
|
||||
else {
|
||||
# ifdef LOG
|
||||
syslog(LOG_ERR, "bind: %m");
|
||||
# else
|
||||
warn("bind");
|
||||
# endif
|
||||
cleanup(1);
|
||||
}
|
||||
}
|
||||
(void) listen(Status, 5);
|
||||
|
||||
# ifdef INTERNET
|
||||
len = sizeof (SOCKET);
|
||||
if (getsockname(Status, (struct sockaddr *) &Daemon, &len) < 0) {
|
||||
# ifdef LOG
|
||||
syslog(LOG_ERR, "getsockname: %m");
|
||||
# else
|
||||
warn("getsockname");
|
||||
# endif
|
||||
exit(1);
|
||||
}
|
||||
stat_port = ntohs(Daemon.sin_port);
|
||||
# endif
|
||||
|
||||
/*
|
||||
* Initialize main socket
|
||||
*/
|
||||
# ifdef INTERNET
|
||||
Daemon.sin_family = SOCK_FAMILY;
|
||||
Daemon.sin_addr.s_addr = INADDR_ANY;
|
||||
Daemon.sin_port = 0;
|
||||
# else
|
||||
Daemon.sun_family = SOCK_FAMILY;
|
||||
(void) strcpy(Daemon.sun_path, Sock_name);
|
||||
# endif
|
||||
|
||||
Socket = socket(SOCK_FAMILY, SOCK_STREAM, 0);
|
||||
# if defined(INTERNET)
|
||||
msg = 1;
|
||||
#ifdef SO_USELOOPBACK
|
||||
if (setsockopt(Socket, SOL_SOCKET, SO_USELOOPBACK, &msg, sizeof msg)<0)
|
||||
# ifdef LOG
|
||||
syslog(LOG_WARNING, "setsockopt loopback %m");
|
||||
# else
|
||||
warn("setsockopt loopback");
|
||||
# endif
|
||||
#endif
|
||||
# endif
|
||||
if (bind(Socket, (struct sockaddr *) &Daemon, DAEMON_SIZE) < 0) {
|
||||
if (errno == EADDRINUSE)
|
||||
exit(0);
|
||||
else {
|
||||
# ifdef LOG
|
||||
syslog(LOG_ERR, "bind: %m");
|
||||
# else
|
||||
warn("bind");
|
||||
# endif
|
||||
cleanup(1);
|
||||
}
|
||||
}
|
||||
(void) listen(Socket, 5);
|
||||
|
||||
# ifdef INTERNET
|
||||
len = sizeof (SOCKET);
|
||||
if (getsockname(Socket, (struct sockaddr *) &Daemon, &len) < 0) {
|
||||
# ifdef LOG
|
||||
syslog(LOG_ERR, "getsockname: %m");
|
||||
# else
|
||||
warn("getsockname");
|
||||
# endif
|
||||
exit(1);
|
||||
}
|
||||
sock_port = ntohs(Daemon.sin_port);
|
||||
# endif
|
||||
|
||||
/*
|
||||
* Initialize minimal select mask
|
||||
*/
|
||||
FD_ZERO(&Fds_mask);
|
||||
FD_SET(Socket, &Fds_mask);
|
||||
FD_SET(Status, &Fds_mask);
|
||||
Num_fds = ((Socket > Status) ? Socket : Status) + 1;
|
||||
|
||||
# ifdef INTERNET
|
||||
len = sizeof (SOCKET);
|
||||
if (getsockname(0, (struct sockaddr *) &test_port, &len) >= 0
|
||||
&& test_port.sin_family == AF_INET) {
|
||||
inetd_spawned = TRUE;
|
||||
Test_socket = 0;
|
||||
if (test_port.sin_port != htons((u_short) Test_port)) {
|
||||
standard_port = FALSE;
|
||||
Test_port = ntohs(test_port.sin_port);
|
||||
}
|
||||
} else {
|
||||
test_port = Daemon;
|
||||
test_port.sin_port = htons((u_short) Test_port);
|
||||
|
||||
Test_socket = socket(SOCK_FAMILY, SOCK_DGRAM, 0);
|
||||
if (bind(Test_socket, (struct sockaddr *) &test_port,
|
||||
DAEMON_SIZE) < 0) {
|
||||
# ifdef LOG
|
||||
syslog(LOG_ERR, "bind: %m");
|
||||
# else
|
||||
warn("bind");
|
||||
# endif
|
||||
exit(1);
|
||||
}
|
||||
(void) listen(Test_socket, 5);
|
||||
}
|
||||
|
||||
FD_SET(Test_socket, &Fds_mask);
|
||||
if (Test_socket + 1 > Num_fds)
|
||||
Num_fds = Test_socket + 1;
|
||||
# endif
|
||||
|
||||
Seed = getpid() + time((time_t *) NULL);
|
||||
makemaze();
|
||||
# ifdef BOOTS
|
||||
makeboots();
|
||||
# endif
|
||||
|
||||
for (i = 0; i < NASCII; i++)
|
||||
See_over[i] = TRUE;
|
||||
See_over[DOOR] = FALSE;
|
||||
See_over[WALL1] = FALSE;
|
||||
See_over[WALL2] = FALSE;
|
||||
See_over[WALL3] = FALSE;
|
||||
# ifdef REFLECT
|
||||
See_over[WALL4] = FALSE;
|
||||
See_over[WALL5] = FALSE;
|
||||
# endif
|
||||
|
||||
}
|
||||
|
||||
# ifdef BOOTS
|
||||
/*
|
||||
* makeboots:
|
||||
* Put the boots in the maze
|
||||
*/
|
||||
static void
|
||||
makeboots()
|
||||
{
|
||||
int x, y;
|
||||
PLAYER *pp;
|
||||
|
||||
do {
|
||||
x = rand_num(WIDTH - 1) + 1;
|
||||
y = rand_num(HEIGHT - 1) + 1;
|
||||
} while (Maze[y][x] != SPACE);
|
||||
Maze[y][x] = BOOT_PAIR;
|
||||
for (pp = Boot; pp < &Boot[NBOOTS]; pp++)
|
||||
pp->p_flying = -1;
|
||||
}
|
||||
# endif
|
||||
|
||||
|
||||
/*
|
||||
* checkdam:
|
||||
* Check the damage to the given player, and see if s/he is killed
|
||||
*/
|
||||
void
|
||||
checkdam(ouch, gotcha, credit, amt, shot_type)
|
||||
PLAYER *ouch, *gotcha;
|
||||
IDENT *credit;
|
||||
int amt;
|
||||
char shot_type;
|
||||
{
|
||||
const char *cp;
|
||||
|
||||
if (ouch->p_death[0] != '\0')
|
||||
return;
|
||||
# ifdef BOOTS
|
||||
if (shot_type == SLIME)
|
||||
switch (ouch->p_nboots) {
|
||||
default:
|
||||
break;
|
||||
case 1:
|
||||
amt = (amt + 1) / 2;
|
||||
break;
|
||||
case 2:
|
||||
if (gotcha != NULL)
|
||||
message(gotcha, "He has boots on!");
|
||||
return;
|
||||
}
|
||||
# endif
|
||||
ouch->p_damage += amt;
|
||||
if (ouch->p_damage <= ouch->p_damcap) {
|
||||
(void) sprintf(Buf, "%2d", ouch->p_damage);
|
||||
cgoto(ouch, STAT_DAM_ROW, STAT_VALUE_COL);
|
||||
outstr(ouch, Buf, 2);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Someone DIED */
|
||||
switch (shot_type) {
|
||||
default:
|
||||
cp = "Killed";
|
||||
break;
|
||||
# ifdef FLY
|
||||
case FALL:
|
||||
cp = "Killed on impact";
|
||||
break;
|
||||
# endif
|
||||
case KNIFE:
|
||||
cp = "Stabbed to death";
|
||||
ouch->p_ammo = 0; /* No exploding */
|
||||
break;
|
||||
case SHOT:
|
||||
cp = "Shot to death";
|
||||
break;
|
||||
case GRENADE:
|
||||
case SATCHEL:
|
||||
case BOMB:
|
||||
cp = "Bombed";
|
||||
break;
|
||||
case MINE:
|
||||
case GMINE:
|
||||
cp = "Blown apart";
|
||||
break;
|
||||
# ifdef OOZE
|
||||
case SLIME:
|
||||
cp = "Slimed";
|
||||
if (credit != NULL)
|
||||
credit->i_slime++;
|
||||
break;
|
||||
# endif
|
||||
# ifdef VOLCANO
|
||||
case LAVA:
|
||||
cp = "Baked";
|
||||
break;
|
||||
# endif
|
||||
# ifdef DRONE
|
||||
case DSHOT:
|
||||
cp = "Eliminated";
|
||||
break;
|
||||
# endif
|
||||
}
|
||||
if (credit == NULL) {
|
||||
(void) sprintf(ouch->p_death, "| %s by %s |", cp,
|
||||
(shot_type == MINE || shot_type == GMINE) ?
|
||||
"a mine" : "act of God");
|
||||
return;
|
||||
}
|
||||
|
||||
(void) sprintf(ouch->p_death, "| %s by %s |", cp, credit->i_name);
|
||||
|
||||
if (ouch == gotcha) { /* No use killing yourself */
|
||||
credit->i_kills--;
|
||||
credit->i_bkills++;
|
||||
}
|
||||
else if (ouch->p_ident->i_team == ' '
|
||||
|| ouch->p_ident->i_team != credit->i_team) {
|
||||
credit->i_kills++;
|
||||
credit->i_gkills++;
|
||||
}
|
||||
else {
|
||||
credit->i_kills--;
|
||||
credit->i_bkills++;
|
||||
}
|
||||
credit->i_score = credit->i_kills / (double) credit->i_entries;
|
||||
ouch->p_ident->i_deaths++;
|
||||
if (ouch->p_nchar == 0)
|
||||
ouch->p_ident->i_stillb++;
|
||||
if (gotcha == NULL)
|
||||
return;
|
||||
gotcha->p_damcap += STABDAM;
|
||||
gotcha->p_damage -= STABDAM;
|
||||
if (gotcha->p_damage < 0)
|
||||
gotcha->p_damage = 0;
|
||||
(void) sprintf(Buf, "%2d/%2d", gotcha->p_damage, gotcha->p_damcap);
|
||||
cgoto(gotcha, STAT_DAM_ROW, STAT_VALUE_COL);
|
||||
outstr(gotcha, Buf, 5);
|
||||
(void) sprintf(Buf, "%3d", (gotcha->p_damcap - MAXDAM) / 2);
|
||||
cgoto(gotcha, STAT_KILL_ROW, STAT_VALUE_COL);
|
||||
outstr(gotcha, Buf, 3);
|
||||
(void) sprintf(Buf, "%5.2f", gotcha->p_ident->i_score);
|
||||
for (ouch = Player; ouch < End_player; ouch++) {
|
||||
cgoto(ouch, STAT_PLAY_ROW + 1 + (gotcha - Player),
|
||||
STAT_NAME_COL);
|
||||
outstr(ouch, Buf, 5);
|
||||
}
|
||||
# ifdef MONITOR
|
||||
for (ouch = Monitor; ouch < End_monitor; ouch++) {
|
||||
cgoto(ouch, STAT_PLAY_ROW + 1 + (gotcha - Player),
|
||||
STAT_NAME_COL);
|
||||
outstr(ouch, Buf, 5);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
/*
|
||||
* zap:
|
||||
* Kill off a player and take him out of the game.
|
||||
*/
|
||||
static void
|
||||
zap(pp, was_player)
|
||||
PLAYER *pp;
|
||||
FLAG was_player;
|
||||
{
|
||||
int i, len;
|
||||
BULLET *bp;
|
||||
PLAYER *np;
|
||||
int x, y;
|
||||
int savefd;
|
||||
|
||||
if (was_player) {
|
||||
if (pp->p_undershot)
|
||||
fixshots(pp->p_y, pp->p_x, pp->p_over);
|
||||
drawplayer(pp, FALSE);
|
||||
Nplayer--;
|
||||
}
|
||||
|
||||
len = strlen(pp->p_death); /* Display the cause of death */
|
||||
x = (WIDTH - len) / 2;
|
||||
cgoto(pp, HEIGHT / 2, x);
|
||||
outstr(pp, pp->p_death, len);
|
||||
for (i = 1; i < len; i++)
|
||||
pp->p_death[i] = '-';
|
||||
pp->p_death[0] = '+';
|
||||
pp->p_death[len - 1] = '+';
|
||||
cgoto(pp, HEIGHT / 2 - 1, x);
|
||||
outstr(pp, pp->p_death, len);
|
||||
cgoto(pp, HEIGHT / 2 + 1, x);
|
||||
outstr(pp, pp->p_death, len);
|
||||
cgoto(pp, HEIGHT, 0);
|
||||
|
||||
savefd = pp->p_fd;
|
||||
|
||||
# ifdef MONITOR
|
||||
if (was_player) {
|
||||
# endif
|
||||
for (bp = Bullets; bp != NULL; bp = bp->b_next) {
|
||||
if (bp->b_owner == pp)
|
||||
bp->b_owner = NULL;
|
||||
if (bp->b_x == pp->p_x && bp->b_y == pp->p_y)
|
||||
bp->b_over = SPACE;
|
||||
}
|
||||
|
||||
i = rand_num(pp->p_ammo);
|
||||
x = rand_num(pp->p_ammo);
|
||||
if (x > i)
|
||||
i = x;
|
||||
if (pp->p_ammo == 0)
|
||||
x = 0;
|
||||
else if (i == pp->p_ammo - 1) {
|
||||
x = pp->p_ammo;
|
||||
len = SLIME;
|
||||
}
|
||||
else {
|
||||
for (x = MAXBOMB - 1; x > 0; x--)
|
||||
if (i >= shot_req[x])
|
||||
break;
|
||||
for (y = MAXSLIME - 1; y > 0; y--)
|
||||
if (i >= slime_req[y])
|
||||
break;
|
||||
if (y >= 0 && slime_req[y] > shot_req[x]) {
|
||||
x = slime_req[y];
|
||||
len = SLIME;
|
||||
}
|
||||
else if (x != 0) {
|
||||
len = shot_type[x];
|
||||
x = shot_req[x];
|
||||
}
|
||||
}
|
||||
if (x > 0) {
|
||||
(void) add_shot(len, pp->p_y, pp->p_x, pp->p_face, x,
|
||||
(PLAYER *) NULL, TRUE, SPACE);
|
||||
(void) sprintf(Buf, "%s detonated.",
|
||||
pp->p_ident->i_name);
|
||||
for (np = Player; np < End_player; np++)
|
||||
message(np, Buf);
|
||||
# ifdef MONITOR
|
||||
for (np = Monitor; np < End_monitor; np++)
|
||||
message(np, Buf);
|
||||
# endif
|
||||
# ifdef BOOTS
|
||||
while (pp->p_nboots-- > 0) {
|
||||
for (np = Boot; np < &Boot[NBOOTS]; np++)
|
||||
if (np->p_flying < 0)
|
||||
break;
|
||||
if (np >= &Boot[NBOOTS])
|
||||
err(1, "Too many boots");
|
||||
np->p_undershot = FALSE;
|
||||
np->p_x = pp->p_x;
|
||||
np->p_y = pp->p_y;
|
||||
np->p_flying = rand_num(20);
|
||||
np->p_flyx = 2 * rand_num(6) - 5;
|
||||
np->p_flyy = 2 * rand_num(6) - 5;
|
||||
np->p_over = SPACE;
|
||||
np->p_face = BOOT;
|
||||
showexpl(np->p_y, np->p_x, BOOT);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
# ifdef BOOTS
|
||||
else if (pp->p_nboots > 0) {
|
||||
if (pp->p_nboots == 2)
|
||||
Maze[pp->p_y][pp->p_x] = BOOT_PAIR;
|
||||
else
|
||||
Maze[pp->p_y][pp->p_x] = BOOT;
|
||||
if (pp->p_undershot)
|
||||
fixshots(pp->p_y, pp->p_x,
|
||||
Maze[pp->p_y][pp->p_x]);
|
||||
}
|
||||
# endif
|
||||
|
||||
# ifdef VOLCANO
|
||||
volcano += pp->p_ammo - x;
|
||||
if (rand_num(100) < volcano / 50) {
|
||||
do {
|
||||
x = rand_num(WIDTH / 2) + WIDTH / 4;
|
||||
y = rand_num(HEIGHT / 2) + HEIGHT / 4;
|
||||
} while (Maze[y][x] != SPACE);
|
||||
(void) add_shot(LAVA, y, x, LEFTS, volcano,
|
||||
(PLAYER *) NULL, TRUE, SPACE);
|
||||
for (np = Player; np < End_player; np++)
|
||||
message(np, "Volcano eruption.");
|
||||
volcano = 0;
|
||||
}
|
||||
# endif
|
||||
|
||||
# ifdef DRONE
|
||||
if (rand_num(100) < 2) {
|
||||
do {
|
||||
x = rand_num(WIDTH / 2) + WIDTH / 4;
|
||||
y = rand_num(HEIGHT / 2) + HEIGHT / 4;
|
||||
} while (Maze[y][x] != SPACE);
|
||||
add_shot(DSHOT, y, x, rand_dir(),
|
||||
shot_req[MINDSHOT +
|
||||
rand_num(MAXBOMB - MINDSHOT)],
|
||||
(PLAYER *) NULL, FALSE, SPACE);
|
||||
}
|
||||
# endif
|
||||
|
||||
sendcom(pp, ENDWIN);
|
||||
(void) putc(' ', pp->p_output);
|
||||
(void) fclose(pp->p_output);
|
||||
|
||||
End_player--;
|
||||
if (pp != End_player) {
|
||||
memcpy(pp, End_player, sizeof (PLAYER));
|
||||
(void) sprintf(Buf, "%5.2f%c%-10.10s %c",
|
||||
pp->p_ident->i_score, stat_char(pp),
|
||||
pp->p_ident->i_name, pp->p_ident->i_team);
|
||||
i = STAT_PLAY_ROW + 1 + (pp - Player);
|
||||
for (np = Player; np < End_player; np++) {
|
||||
cgoto(np, i, STAT_NAME_COL);
|
||||
outstr(np, Buf, STAT_NAME_LEN);
|
||||
}
|
||||
# ifdef MONITOR
|
||||
for (np = Monitor; np < End_monitor; np++) {
|
||||
cgoto(np, i, STAT_NAME_COL);
|
||||
outstr(np, Buf, STAT_NAME_LEN);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
/* Erase the last player */
|
||||
i = STAT_PLAY_ROW + 1 + Nplayer;
|
||||
for (np = Player; np < End_player; np++) {
|
||||
cgoto(np, i, STAT_NAME_COL);
|
||||
ce(np);
|
||||
}
|
||||
# ifdef MONITOR
|
||||
for (np = Monitor; np < End_monitor; np++) {
|
||||
cgoto(np, i, STAT_NAME_COL);
|
||||
ce(np);
|
||||
}
|
||||
}
|
||||
else {
|
||||
sendcom(pp, ENDWIN);
|
||||
(void) putc(LAST_PLAYER, pp->p_output);
|
||||
(void) fclose(pp->p_output);
|
||||
|
||||
End_monitor--;
|
||||
if (pp != End_monitor) {
|
||||
memcpy(pp, End_monitor, sizeof (PLAYER));
|
||||
(void) sprintf(Buf, "%5.5s %-10.10s %c", " ",
|
||||
pp->p_ident->i_name, pp->p_ident->i_team);
|
||||
i = STAT_MON_ROW + 1 + (pp - Player);
|
||||
for (np = Player; np < End_player; np++) {
|
||||
cgoto(np, i, STAT_NAME_COL);
|
||||
outstr(np, Buf, STAT_NAME_LEN);
|
||||
}
|
||||
for (np = Monitor; np < End_monitor; np++) {
|
||||
cgoto(np, i, STAT_NAME_COL);
|
||||
outstr(np, Buf, STAT_NAME_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
/* Erase the last monitor */
|
||||
i = STAT_MON_ROW + 1 + (End_monitor - Monitor);
|
||||
for (np = Player; np < End_player; np++) {
|
||||
cgoto(np, i, STAT_NAME_COL);
|
||||
ce(np);
|
||||
}
|
||||
for (np = Monitor; np < End_monitor; np++) {
|
||||
cgoto(np, i, STAT_NAME_COL);
|
||||
ce(np);
|
||||
}
|
||||
|
||||
}
|
||||
# endif
|
||||
|
||||
FD_CLR(savefd, &Fds_mask);
|
||||
if (Num_fds == savefd + 1) {
|
||||
Num_fds = Socket;
|
||||
# ifdef INTERNET
|
||||
if (Test_socket > Socket)
|
||||
Num_fds = Test_socket;
|
||||
# endif
|
||||
for (np = Player; np < End_player; np++)
|
||||
if (np->p_fd > Num_fds)
|
||||
Num_fds = np->p_fd;
|
||||
# ifdef MONITOR
|
||||
for (np = Monitor; np < End_monitor; np++)
|
||||
if (np->p_fd > Num_fds)
|
||||
Num_fds = np->p_fd;
|
||||
# endif
|
||||
Num_fds++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* rand_num:
|
||||
* Return a random number in a given range.
|
||||
*/
|
||||
int
|
||||
rand_num(range)
|
||||
int range;
|
||||
{
|
||||
return (range == 0 ? 0 : RN % range);
|
||||
}
|
||||
|
||||
/*
|
||||
* havechar:
|
||||
* Check to see if we have any characters in the input queue; if
|
||||
* we do, read them, stash them away, and return TRUE; else return
|
||||
* FALSE.
|
||||
*/
|
||||
static int
|
||||
havechar(pp)
|
||||
PLAYER *pp;
|
||||
{
|
||||
|
||||
if (pp->p_ncount < pp->p_nchar)
|
||||
return TRUE;
|
||||
if (!FD_ISSET(pp->p_fd, &Have_inp))
|
||||
return FALSE;
|
||||
FD_CLR(pp->p_fd, &Have_inp);
|
||||
check_again:
|
||||
errno = 0;
|
||||
if ((pp->p_nchar = read(pp->p_fd, pp->p_cbuf, sizeof pp->p_cbuf)) <= 0)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
goto check_again;
|
||||
pp->p_cbuf[0] = 'q';
|
||||
}
|
||||
pp->p_ncount = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* cleanup:
|
||||
* Exit with the given value, cleaning up any droppings lying around
|
||||
*/
|
||||
SIGNAL_TYPE
|
||||
cleanup(eval)
|
||||
int eval;
|
||||
{
|
||||
PLAYER *pp;
|
||||
|
||||
for (pp = Player; pp < End_player; pp++) {
|
||||
cgoto(pp, HEIGHT, 0);
|
||||
sendcom(pp, ENDWIN);
|
||||
(void) putc(LAST_PLAYER, pp->p_output);
|
||||
(void) fclose(pp->p_output);
|
||||
}
|
||||
# ifdef MONITOR
|
||||
for (pp = Monitor; pp < End_monitor; pp++) {
|
||||
cgoto(pp, HEIGHT, 0);
|
||||
sendcom(pp, ENDWIN);
|
||||
(void) putc(LAST_PLAYER, pp->p_output);
|
||||
(void) fclose(pp->p_output);
|
||||
}
|
||||
# endif
|
||||
(void) close(Socket);
|
||||
# ifdef AF_UNIX_HACK
|
||||
(void) unlink(Sock_name);
|
||||
# endif
|
||||
|
||||
exit(eval);
|
||||
}
|
||||
|
||||
/*
|
||||
* send_stats:
|
||||
* Print stats to requestor
|
||||
*/
|
||||
static void
|
||||
send_stats()
|
||||
{
|
||||
IDENT *ip;
|
||||
FILE *fp;
|
||||
int s;
|
||||
SOCKET sockstruct;
|
||||
int socklen;
|
||||
|
||||
/*
|
||||
* Get the output stream ready
|
||||
*/
|
||||
# ifdef INTERNET
|
||||
socklen = sizeof sockstruct;
|
||||
# else
|
||||
socklen = sizeof sockstruct - 1;
|
||||
# endif
|
||||
s = accept(Status, (struct sockaddr *) &sockstruct, &socklen);
|
||||
if (s < 0) {
|
||||
if (errno == EINTR)
|
||||
return;
|
||||
# ifdef LOG
|
||||
syslog(LOG_ERR, "accept: %m");
|
||||
# else
|
||||
warn("accept");
|
||||
# endif
|
||||
return;
|
||||
}
|
||||
fp = fdopen(s, "w");
|
||||
if (fp == NULL) {
|
||||
# ifdef LOG
|
||||
syslog(LOG_ERR, "fdopen: %m");
|
||||
# else
|
||||
warn("fdopen");
|
||||
# endif
|
||||
(void) close(s);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send output to requestor
|
||||
*/
|
||||
fputs("Name\t\tScore\tDucked\tAbsorb\tFaced\tShot\tRobbed\tMissed\tSlimeK\n", fp);
|
||||
for (ip = Scores; ip != NULL; ip = ip->i_next) {
|
||||
fprintf(fp, "%s\t", ip->i_name);
|
||||
if (strlen(ip->i_name) < 8)
|
||||
putc('\t', fp);
|
||||
fprintf(fp, "%.2f\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
|
||||
ip->i_score, ip->i_ducked, ip->i_absorbed,
|
||||
ip->i_faced, ip->i_shot, ip->i_robbed,
|
||||
ip->i_missed, ip->i_slime);
|
||||
}
|
||||
fputs("\n\nName\t\tEnemy\tFriend\tDeaths\tStill\tSaved\n", fp);
|
||||
for (ip = Scores; ip != NULL; ip = ip->i_next) {
|
||||
if (ip->i_team == ' ') {
|
||||
fprintf(fp, "%s\t", ip->i_name);
|
||||
if (strlen(ip->i_name) < 8)
|
||||
putc('\t', fp);
|
||||
}
|
||||
else {
|
||||
fprintf(fp, "%s[%c]\t", ip->i_name, ip->i_team);
|
||||
if (strlen(ip->i_name) + 3 < 8)
|
||||
putc('\t', fp);
|
||||
}
|
||||
fprintf(fp, "%d\t%d\t%d\t%d\t%d\n",
|
||||
ip->i_gkills, ip->i_bkills, ip->i_deaths,
|
||||
ip->i_stillb, ip->i_saved);
|
||||
}
|
||||
|
||||
(void) fclose(fp);
|
||||
}
|
||||
|
||||
/*
|
||||
* clear_scores:
|
||||
* Clear out the scores so the next session start clean
|
||||
*/
|
||||
static void
|
||||
clear_scores()
|
||||
{
|
||||
IDENT *ip, *nextip;
|
||||
|
||||
for (ip = Scores; ip != NULL; ip = nextip) {
|
||||
nextip = ip->i_next;
|
||||
(void) free((char *) ip);
|
||||
}
|
||||
Scores = NULL;
|
||||
}
|
||||
582
hunt/huntd/execute.c
Normal file
582
hunt/huntd/execute.c
Normal file
@@ -0,0 +1,582 @@
|
||||
/* $NetBSD: execute.c,v 1.2 1997/10/10 16:33:13 lukem Exp $ */
|
||||
/*
|
||||
* Hunt
|
||||
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
* San Francisco, California
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: execute.c,v 1.2 1997/10/10 16:33:13 lukem Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
# include <stdlib.h>
|
||||
# include "hunt.h"
|
||||
|
||||
static void cloak __P((PLAYER *));
|
||||
static void face __P((PLAYER *, int));
|
||||
static void fire __P((PLAYER *, int));
|
||||
static void fire_slime __P((PLAYER *, int));
|
||||
static void move_player __P((PLAYER *, int));
|
||||
static void pickup __P((PLAYER *, int, int, int, int));
|
||||
static void scan __P((PLAYER *));
|
||||
|
||||
|
||||
# ifdef MONITOR
|
||||
/*
|
||||
* mon_execute:
|
||||
* Execute a single monitor command
|
||||
*/
|
||||
void
|
||||
mon_execute(pp)
|
||||
PLAYER *pp;
|
||||
{
|
||||
char ch;
|
||||
|
||||
ch = pp->p_cbuf[pp->p_ncount++];
|
||||
switch (ch) {
|
||||
case CTRL('L'):
|
||||
sendcom(pp, REDRAW);
|
||||
break;
|
||||
case 'q':
|
||||
(void) strcpy(pp->p_death, "| Quit |");
|
||||
break;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
|
||||
/*
|
||||
* execute:
|
||||
* Execute a single command
|
||||
*/
|
||||
void
|
||||
execute(pp)
|
||||
PLAYER *pp;
|
||||
{
|
||||
char ch;
|
||||
|
||||
ch = pp->p_cbuf[pp->p_ncount++];
|
||||
|
||||
# ifdef FLY
|
||||
if (pp->p_flying >= 0) {
|
||||
switch (ch) {
|
||||
case CTRL('L'):
|
||||
sendcom(pp, REDRAW);
|
||||
break;
|
||||
case 'q':
|
||||
(void) strcpy(pp->p_death, "| Quit |");
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
# endif
|
||||
|
||||
switch (ch) {
|
||||
case CTRL('L'):
|
||||
sendcom(pp, REDRAW);
|
||||
break;
|
||||
case 'h':
|
||||
move_player(pp, LEFTS);
|
||||
break;
|
||||
case 'H':
|
||||
face(pp, LEFTS);
|
||||
break;
|
||||
case 'j':
|
||||
move_player(pp, BELOW);
|
||||
break;
|
||||
case 'J':
|
||||
face(pp, BELOW);
|
||||
break;
|
||||
case 'k':
|
||||
move_player(pp, ABOVE);
|
||||
break;
|
||||
case 'K':
|
||||
face(pp, ABOVE);
|
||||
break;
|
||||
case 'l':
|
||||
move_player(pp, RIGHT);
|
||||
break;
|
||||
case 'L':
|
||||
face(pp, RIGHT);
|
||||
break;
|
||||
case 'f':
|
||||
case '1':
|
||||
fire(pp, 0); /* SHOT */
|
||||
break;
|
||||
case 'g':
|
||||
case '2':
|
||||
fire(pp, 1); /* GRENADE */
|
||||
break;
|
||||
case 'F':
|
||||
case '3':
|
||||
fire(pp, 2); /* SATCHEL */
|
||||
break;
|
||||
case 'G':
|
||||
case '4':
|
||||
fire(pp, 3); /* 7x7 BOMB */
|
||||
break;
|
||||
case '5':
|
||||
fire(pp, 4); /* 9x9 BOMB */
|
||||
break;
|
||||
case '6':
|
||||
fire(pp, 5); /* 11x11 BOMB */
|
||||
break;
|
||||
case '7':
|
||||
fire(pp, 6); /* 13x13 BOMB */
|
||||
break;
|
||||
case '8':
|
||||
fire(pp, 7); /* 15x15 BOMB */
|
||||
break;
|
||||
case '9':
|
||||
fire(pp, 8); /* 17x17 BOMB */
|
||||
break;
|
||||
case '0':
|
||||
fire(pp, 9); /* 19x19 BOMB */
|
||||
break;
|
||||
case '@':
|
||||
fire(pp, 10); /* 21x21 BOMB */
|
||||
break;
|
||||
# ifdef OOZE
|
||||
case 'o':
|
||||
fire_slime(pp, 0); /* SLIME */
|
||||
break;
|
||||
case 'O':
|
||||
fire_slime(pp, 1); /* SSLIME */
|
||||
break;
|
||||
case 'p':
|
||||
fire_slime(pp, 2);
|
||||
break;
|
||||
case 'P':
|
||||
fire_slime(pp, 3);
|
||||
break;
|
||||
# endif
|
||||
case 's':
|
||||
scan(pp);
|
||||
break;
|
||||
case 'c':
|
||||
cloak(pp);
|
||||
break;
|
||||
case 'q':
|
||||
(void) strcpy(pp->p_death, "| Quit |");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* move_player:
|
||||
* Execute a move in the given direction
|
||||
*/
|
||||
static void
|
||||
move_player(pp, dir)
|
||||
PLAYER *pp;
|
||||
int dir;
|
||||
{
|
||||
PLAYER *newp;
|
||||
int x, y;
|
||||
FLAG moved;
|
||||
BULLET *bp;
|
||||
|
||||
y = pp->p_y;
|
||||
x = pp->p_x;
|
||||
|
||||
switch (dir) {
|
||||
case LEFTS:
|
||||
x--;
|
||||
break;
|
||||
case RIGHT:
|
||||
x++;
|
||||
break;
|
||||
case ABOVE:
|
||||
y--;
|
||||
break;
|
||||
case BELOW:
|
||||
y++;
|
||||
break;
|
||||
}
|
||||
|
||||
moved = FALSE;
|
||||
switch (Maze[y][x]) {
|
||||
case SPACE:
|
||||
# ifdef RANDOM
|
||||
case DOOR:
|
||||
# endif
|
||||
moved = TRUE;
|
||||
break;
|
||||
case WALL1:
|
||||
case WALL2:
|
||||
case WALL3:
|
||||
# ifdef REFLECT
|
||||
case WALL4:
|
||||
case WALL5:
|
||||
# endif
|
||||
break;
|
||||
case MINE:
|
||||
case GMINE:
|
||||
if (dir == pp->p_face)
|
||||
pickup(pp, y, x, 2, Maze[y][x]);
|
||||
else if (opposite(dir, pp->p_face))
|
||||
pickup(pp, y, x, 95, Maze[y][x]);
|
||||
else
|
||||
pickup(pp, y, x, 50, Maze[y][x]);
|
||||
Maze[y][x] = SPACE;
|
||||
moved = TRUE;
|
||||
break;
|
||||
case SHOT:
|
||||
case GRENADE:
|
||||
case SATCHEL:
|
||||
case BOMB:
|
||||
# ifdef OOZE
|
||||
case SLIME:
|
||||
# endif
|
||||
# ifdef DRONE
|
||||
case DSHOT:
|
||||
# endif
|
||||
bp = is_bullet(y, x);
|
||||
if (bp != NULL)
|
||||
bp->b_expl = TRUE;
|
||||
Maze[y][x] = SPACE;
|
||||
moved = TRUE;
|
||||
break;
|
||||
case LEFTS:
|
||||
case RIGHT:
|
||||
case ABOVE:
|
||||
case BELOW:
|
||||
if (dir != pp->p_face)
|
||||
sendcom(pp, BELL);
|
||||
else {
|
||||
newp = play_at(y, x);
|
||||
checkdam(newp, pp, pp->p_ident, STABDAM, KNIFE);
|
||||
}
|
||||
break;
|
||||
# ifdef FLY
|
||||
case FLYER:
|
||||
newp = play_at(y, x);
|
||||
message(newp, "Oooh, there's a short guy waving at you!");
|
||||
message(pp, "You couldn't quite reach him!");
|
||||
break;
|
||||
# endif
|
||||
# ifdef BOOTS
|
||||
case BOOT:
|
||||
case BOOT_PAIR:
|
||||
if (Maze[y][x] == BOOT)
|
||||
pp->p_nboots++;
|
||||
else
|
||||
pp->p_nboots += 2;
|
||||
for (newp = Boot; newp < &Boot[NBOOTS]; newp++) {
|
||||
if (newp->p_flying < 0)
|
||||
continue;
|
||||
if (newp->p_y == y && newp->p_x == x) {
|
||||
newp->p_flying = -1;
|
||||
if (newp->p_undershot)
|
||||
fixshots(y, x, newp->p_over);
|
||||
}
|
||||
}
|
||||
if (pp->p_nboots == 2)
|
||||
message(pp, "Wow! A pair of boots!");
|
||||
else
|
||||
message(pp, "You can hobble around on one boot.");
|
||||
Maze[y][x] = SPACE;
|
||||
moved = TRUE;
|
||||
break;
|
||||
# endif
|
||||
}
|
||||
if (moved) {
|
||||
if (pp->p_ncshot > 0)
|
||||
if (--pp->p_ncshot == MAXNCSHOT) {
|
||||
cgoto(pp, STAT_GUN_ROW, STAT_VALUE_COL);
|
||||
outstr(pp, " ok", 3);
|
||||
}
|
||||
if (pp->p_undershot) {
|
||||
fixshots(pp->p_y, pp->p_x, pp->p_over);
|
||||
pp->p_undershot = FALSE;
|
||||
}
|
||||
drawplayer(pp, FALSE);
|
||||
pp->p_over = Maze[y][x];
|
||||
pp->p_y = y;
|
||||
pp->p_x = x;
|
||||
drawplayer(pp, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* face:
|
||||
* Change the direction the player is facing
|
||||
*/
|
||||
static void
|
||||
face(pp, dir)
|
||||
PLAYER *pp;
|
||||
int dir;
|
||||
{
|
||||
if (pp->p_face != dir) {
|
||||
pp->p_face = dir;
|
||||
drawplayer(pp, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* fire:
|
||||
* Fire a shot of the given type in the given direction
|
||||
*/
|
||||
static void
|
||||
fire(pp, req_index)
|
||||
PLAYER *pp;
|
||||
int req_index;
|
||||
{
|
||||
if (pp == NULL)
|
||||
return;
|
||||
# ifdef DEBUG
|
||||
if (req_index < 0 || req_index >= MAXBOMB)
|
||||
message(pp, "What you do?");
|
||||
# endif
|
||||
while (req_index >= 0 && pp->p_ammo < shot_req[req_index])
|
||||
req_index--;
|
||||
if (req_index < 0) {
|
||||
message(pp, "Not enough charges.");
|
||||
return;
|
||||
}
|
||||
if (pp->p_ncshot > MAXNCSHOT)
|
||||
return;
|
||||
if (pp->p_ncshot++ == MAXNCSHOT) {
|
||||
cgoto(pp, STAT_GUN_ROW, STAT_VALUE_COL);
|
||||
outstr(pp, " ", 3);
|
||||
}
|
||||
pp->p_ammo -= shot_req[req_index];
|
||||
(void) sprintf(Buf, "%3d", pp->p_ammo);
|
||||
cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
|
||||
outstr(pp, Buf, 3);
|
||||
|
||||
add_shot(shot_type[req_index], pp->p_y, pp->p_x, pp->p_face,
|
||||
shot_req[req_index], pp, FALSE, pp->p_face);
|
||||
pp->p_undershot = TRUE;
|
||||
|
||||
/*
|
||||
* Show the object to everyone
|
||||
*/
|
||||
showexpl(pp->p_y, pp->p_x, shot_type[req_index]);
|
||||
for (pp = Player; pp < End_player; pp++)
|
||||
sendcom(pp, REFRESH);
|
||||
# ifdef MONITOR
|
||||
for (pp = Monitor; pp < End_monitor; pp++)
|
||||
sendcom(pp, REFRESH);
|
||||
# endif
|
||||
}
|
||||
|
||||
# ifdef OOZE
|
||||
/*
|
||||
* fire_slime:
|
||||
* Fire a slime shot in the given direction
|
||||
*/
|
||||
static void
|
||||
fire_slime(pp, req_index)
|
||||
PLAYER *pp;
|
||||
int req_index;
|
||||
{
|
||||
if (pp == NULL)
|
||||
return;
|
||||
# ifdef DEBUG
|
||||
if (req_index < 0 || req_index >= MAXSLIME)
|
||||
message(pp, "What you do?");
|
||||
# endif
|
||||
while (req_index >= 0 && pp->p_ammo < slime_req[req_index])
|
||||
req_index--;
|
||||
if (req_index < 0) {
|
||||
message(pp, "Not enough charges.");
|
||||
return;
|
||||
}
|
||||
if (pp->p_ncshot > MAXNCSHOT)
|
||||
return;
|
||||
if (pp->p_ncshot++ == MAXNCSHOT) {
|
||||
cgoto(pp, STAT_GUN_ROW, STAT_VALUE_COL);
|
||||
outstr(pp, " ", 3);
|
||||
}
|
||||
pp->p_ammo -= slime_req[req_index];
|
||||
(void) sprintf(Buf, "%3d", pp->p_ammo);
|
||||
cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
|
||||
outstr(pp, Buf, 3);
|
||||
|
||||
add_shot(SLIME, pp->p_y, pp->p_x, pp->p_face,
|
||||
slime_req[req_index] * SLIME_FACTOR, pp, FALSE, pp->p_face);
|
||||
pp->p_undershot = TRUE;
|
||||
|
||||
/*
|
||||
* Show the object to everyone
|
||||
*/
|
||||
showexpl(pp->p_y, pp->p_x, SLIME);
|
||||
for (pp = Player; pp < End_player; pp++)
|
||||
sendcom(pp, REFRESH);
|
||||
# ifdef MONITOR
|
||||
for (pp = Monitor; pp < End_monitor; pp++)
|
||||
sendcom(pp, REFRESH);
|
||||
# endif
|
||||
}
|
||||
# endif
|
||||
|
||||
/*
|
||||
* add_shot:
|
||||
* Create a shot with the given properties
|
||||
*/
|
||||
void
|
||||
add_shot(type, y, x, face, charge, owner, expl, over)
|
||||
int type;
|
||||
int y, x;
|
||||
char face;
|
||||
int charge;
|
||||
PLAYER *owner;
|
||||
int expl;
|
||||
char over;
|
||||
{
|
||||
BULLET *bp;
|
||||
int size;
|
||||
|
||||
switch (type) {
|
||||
case SHOT:
|
||||
case MINE:
|
||||
size = 1;
|
||||
break;
|
||||
case GRENADE:
|
||||
case GMINE:
|
||||
size = 2;
|
||||
break;
|
||||
case SATCHEL:
|
||||
size = 3;
|
||||
break;
|
||||
case BOMB:
|
||||
for (size = 3; size < MAXBOMB; size++)
|
||||
if (shot_req[size] >= charge)
|
||||
break;
|
||||
size++;
|
||||
break;
|
||||
default:
|
||||
size = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
bp = create_shot(type, y, x, face, charge, size, owner,
|
||||
(owner == NULL) ? NULL : owner->p_ident, expl, over);
|
||||
bp->b_next = Bullets;
|
||||
Bullets = bp;
|
||||
}
|
||||
|
||||
BULLET *
|
||||
create_shot(type, y, x, face, charge, size, owner, score, expl, over)
|
||||
int type;
|
||||
int y, x;
|
||||
char face;
|
||||
int charge;
|
||||
int size;
|
||||
PLAYER *owner;
|
||||
IDENT *score;
|
||||
int expl;
|
||||
char over;
|
||||
{
|
||||
BULLET *bp;
|
||||
|
||||
bp = (BULLET *) malloc(sizeof (BULLET)); /* NOSTRICT */
|
||||
if (bp == NULL) {
|
||||
if (owner != NULL)
|
||||
message(owner, "Out of memory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bp->b_face = face;
|
||||
bp->b_x = x;
|
||||
bp->b_y = y;
|
||||
bp->b_charge = charge;
|
||||
bp->b_owner = owner;
|
||||
bp->b_score = score;
|
||||
bp->b_type = type;
|
||||
bp->b_size = size;
|
||||
bp->b_expl = expl;
|
||||
bp->b_over = over;
|
||||
bp->b_next = NULL;
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
||||
/*
|
||||
* cloak:
|
||||
* Turn on or increase length of a cloak
|
||||
*/
|
||||
static void
|
||||
cloak(pp)
|
||||
PLAYER *pp;
|
||||
{
|
||||
if (pp->p_ammo <= 0) {
|
||||
message(pp, "No more charges");
|
||||
return;
|
||||
}
|
||||
# ifdef BOOTS
|
||||
if (pp->p_nboots > 0) {
|
||||
message(pp, "Boots are too noisy to cloak!");
|
||||
return;
|
||||
}
|
||||
# endif
|
||||
(void) sprintf(Buf, "%3d", --pp->p_ammo);
|
||||
cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
|
||||
outstr(pp, Buf, 3);
|
||||
|
||||
pp->p_cloak += CLOAKLEN;
|
||||
|
||||
if (pp->p_scan >= 0)
|
||||
pp->p_scan = -1;
|
||||
|
||||
showstat(pp);
|
||||
}
|
||||
|
||||
/*
|
||||
* scan:
|
||||
* Turn on or increase length of a scan
|
||||
*/
|
||||
static void
|
||||
scan(pp)
|
||||
PLAYER *pp;
|
||||
{
|
||||
if (pp->p_ammo <= 0) {
|
||||
message(pp, "No more charges");
|
||||
return;
|
||||
}
|
||||
(void) sprintf(Buf, "%3d", --pp->p_ammo);
|
||||
cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
|
||||
outstr(pp, Buf, 3);
|
||||
|
||||
pp->p_scan += SCANLEN;
|
||||
|
||||
if (pp->p_cloak >= 0)
|
||||
pp->p_cloak = -1;
|
||||
|
||||
showstat(pp);
|
||||
}
|
||||
|
||||
/*
|
||||
* pickup:
|
||||
* check whether the object blew up or whether he picked it up
|
||||
*/
|
||||
void
|
||||
pickup(pp, y, x, prob, obj)
|
||||
PLAYER *pp;
|
||||
int y, x;
|
||||
int prob;
|
||||
int obj;
|
||||
{
|
||||
int req;
|
||||
|
||||
switch (obj) {
|
||||
case MINE:
|
||||
req = BULREQ;
|
||||
break;
|
||||
case GMINE:
|
||||
req = GRENREQ;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
if (rand_num(100) < prob)
|
||||
add_shot(obj, y, x, LEFTS, req, (PLAYER *) NULL,
|
||||
TRUE, pp->p_face);
|
||||
else {
|
||||
pp->p_ammo += req;
|
||||
(void) sprintf(Buf, "%3d", pp->p_ammo);
|
||||
cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL);
|
||||
outstr(pp, Buf, 3);
|
||||
}
|
||||
}
|
||||
233
hunt/huntd/expl.c
Normal file
233
hunt/huntd/expl.c
Normal file
@@ -0,0 +1,233 @@
|
||||
/* $NetBSD: expl.c,v 1.2 1997/10/10 16:33:18 lukem Exp $ */
|
||||
/*
|
||||
* Hunt
|
||||
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
* San Francisco, California
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: expl.c,v 1.2 1997/10/10 16:33:18 lukem Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
# include <stdlib.h>
|
||||
# include "hunt.h"
|
||||
|
||||
static void remove_wall __P((int, int));
|
||||
|
||||
|
||||
/*
|
||||
* showexpl:
|
||||
* Show the explosions as they currently are
|
||||
*/
|
||||
void
|
||||
showexpl(y, x, type)
|
||||
int y, x;
|
||||
char type;
|
||||
{
|
||||
PLAYER *pp;
|
||||
EXPL *ep;
|
||||
|
||||
if (y < 0 || y >= HEIGHT)
|
||||
return;
|
||||
if (x < 0 || x >= WIDTH)
|
||||
return;
|
||||
ep = (EXPL *) malloc(sizeof (EXPL)); /* NOSTRICT */
|
||||
if (ep == NULL) {
|
||||
# ifdef LOG
|
||||
syslog(LOG_ERR, "Out of memory");
|
||||
# else
|
||||
warnx("Out of memory");
|
||||
# endif
|
||||
cleanup(1);
|
||||
}
|
||||
ep->e_y = y;
|
||||
ep->e_x = x;
|
||||
ep->e_char = type;
|
||||
ep->e_next = NULL;
|
||||
if (Last_expl == NULL)
|
||||
Expl[0] = ep;
|
||||
else
|
||||
Last_expl->e_next = ep;
|
||||
Last_expl = ep;
|
||||
for (pp = Player; pp < End_player; pp++) {
|
||||
if (pp->p_maze[y][x] == type)
|
||||
continue;
|
||||
pp->p_maze[y][x] = type;
|
||||
cgoto(pp, y, x);
|
||||
outch(pp, type);
|
||||
}
|
||||
# ifdef MONITOR
|
||||
for (pp = Monitor; pp < End_monitor; pp++) {
|
||||
if (pp->p_maze[y][x] == type)
|
||||
continue;
|
||||
pp->p_maze[y][x] = type;
|
||||
cgoto(pp, y, x);
|
||||
outch(pp, type);
|
||||
}
|
||||
# endif
|
||||
switch (Maze[y][x]) {
|
||||
case WALL1:
|
||||
case WALL2:
|
||||
case WALL3:
|
||||
# ifdef RANDOM
|
||||
case DOOR:
|
||||
# endif
|
||||
# ifdef REFLECT
|
||||
case WALL4:
|
||||
case WALL5:
|
||||
# endif
|
||||
if (y >= UBOUND && y < DBOUND && x >= LBOUND && x < RBOUND)
|
||||
remove_wall(y, x);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* rollexpl:
|
||||
* Roll the explosions over, so the next one in the list is at the
|
||||
* top
|
||||
*/
|
||||
void
|
||||
rollexpl()
|
||||
{
|
||||
EXPL *ep;
|
||||
PLAYER *pp;
|
||||
int y, x;
|
||||
char c;
|
||||
EXPL *nextep;
|
||||
|
||||
for (ep = Expl[EXPLEN - 1]; ep != NULL; ep = nextep) {
|
||||
nextep = ep->e_next;
|
||||
y = ep->e_y;
|
||||
x = ep->e_x;
|
||||
if (y < UBOUND || y >= DBOUND || x < LBOUND || x >= RBOUND)
|
||||
c = Maze[y][x];
|
||||
else
|
||||
c = SPACE;
|
||||
for (pp = Player; pp < End_player; pp++)
|
||||
if (pp->p_maze[y][x] == ep->e_char) {
|
||||
pp->p_maze[y][x] = c;
|
||||
cgoto(pp, y, x);
|
||||
outch(pp, c);
|
||||
}
|
||||
# ifdef MONITOR
|
||||
for (pp = Monitor; pp < End_monitor; pp++)
|
||||
check(pp, y, x);
|
||||
# endif
|
||||
free((char *) ep);
|
||||
}
|
||||
for (x = EXPLEN - 1; x > 0; x--)
|
||||
Expl[x] = Expl[x - 1];
|
||||
Last_expl = Expl[0] = NULL;
|
||||
}
|
||||
|
||||
/* There's about 700 walls in the initial maze. So we pick a number
|
||||
* that keeps the maze relatively full. */
|
||||
# define MAXREMOVE 40
|
||||
|
||||
static REGEN removed[MAXREMOVE];
|
||||
static REGEN *rem_index = removed;
|
||||
|
||||
/*
|
||||
* remove_wall - add a location where the wall was blown away.
|
||||
* if there is no space left over, put the a wall at
|
||||
* the location currently pointed at.
|
||||
*/
|
||||
static void
|
||||
remove_wall(y, x)
|
||||
int y, x;
|
||||
{
|
||||
REGEN *r;
|
||||
# if defined(MONITOR) || defined(FLY)
|
||||
PLAYER *pp;
|
||||
# endif
|
||||
# ifdef FLY
|
||||
char save_char = 0;
|
||||
# endif
|
||||
|
||||
r = rem_index;
|
||||
while (r->r_y != 0) {
|
||||
# ifdef FLY
|
||||
switch (Maze[r->r_y][r->r_x]) {
|
||||
case SPACE:
|
||||
case LEFTS:
|
||||
case RIGHT:
|
||||
case ABOVE:
|
||||
case BELOW:
|
||||
case FLYER:
|
||||
save_char = Maze[r->r_y][r->r_x];
|
||||
goto found;
|
||||
}
|
||||
# else
|
||||
if (Maze[r->r_y][r->r_x] == SPACE)
|
||||
break;
|
||||
# endif
|
||||
if (++r >= &removed[MAXREMOVE])
|
||||
r = removed;
|
||||
}
|
||||
|
||||
found:
|
||||
if (r->r_y != 0) {
|
||||
/* Slot being used, put back this wall */
|
||||
# ifdef FLY
|
||||
if (save_char == SPACE)
|
||||
Maze[r->r_y][r->r_x] = Orig_maze[r->r_y][r->r_x];
|
||||
else {
|
||||
pp = play_at(r->r_y, r->r_x);
|
||||
if (pp->p_flying >= 0)
|
||||
pp->p_flying += rand_num(10);
|
||||
else {
|
||||
pp->p_flying = rand_num(20);
|
||||
pp->p_flyx = 2 * rand_num(6) - 5;
|
||||
pp->p_flyy = 2 * rand_num(6) - 5;
|
||||
}
|
||||
pp->p_over = Orig_maze[r->r_y][r->r_x];
|
||||
pp->p_face = FLYER;
|
||||
Maze[r->r_y][r->r_x] = FLYER;
|
||||
showexpl(r->r_y, r->r_x, FLYER);
|
||||
}
|
||||
# else
|
||||
Maze[r->r_y][r->r_x] = Orig_maze[r->r_y][r->r_x];
|
||||
# endif
|
||||
# ifdef RANDOM
|
||||
if (rand_num(100) == 0)
|
||||
Maze[r->r_y][r->r_x] = DOOR;
|
||||
# endif
|
||||
# ifdef REFLECT
|
||||
if (rand_num(100) == 0) /* one percent of the time */
|
||||
Maze[r->r_y][r->r_x] = WALL4;
|
||||
# endif
|
||||
# ifdef MONITOR
|
||||
for (pp = Monitor; pp < End_monitor; pp++)
|
||||
check(pp, r->r_y, r->r_x);
|
||||
# endif
|
||||
}
|
||||
|
||||
r->r_y = y;
|
||||
r->r_x = x;
|
||||
if (++r >= &removed[MAXREMOVE])
|
||||
rem_index = removed;
|
||||
else
|
||||
rem_index = r;
|
||||
|
||||
Maze[y][x] = SPACE;
|
||||
# ifdef MONITOR
|
||||
for (pp = Monitor; pp < End_monitor; pp++)
|
||||
check(pp, y, x);
|
||||
# endif
|
||||
}
|
||||
|
||||
/*
|
||||
* clearwalls:
|
||||
* Clear out the walls array
|
||||
*/
|
||||
void
|
||||
clearwalls()
|
||||
{
|
||||
REGEN *rp;
|
||||
|
||||
for (rp = removed; rp < &removed[MAXREMOVE]; rp++)
|
||||
rp->r_y = 0;
|
||||
rem_index = removed;
|
||||
}
|
||||
68
hunt/huntd/extern.c
Normal file
68
hunt/huntd/extern.c
Normal file
@@ -0,0 +1,68 @@
|
||||
/* $NetBSD: extern.c,v 1.2 1997/10/10 16:33:24 lukem Exp $ */
|
||||
/*
|
||||
* Hunt
|
||||
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
* San Francisco, California
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: extern.c,v 1.2 1997/10/10 16:33:24 lukem Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
# include "hunt.h"
|
||||
|
||||
# ifdef MONITOR
|
||||
FLAG Am_monitor = FALSE; /* current process is a monitor */
|
||||
# endif
|
||||
|
||||
char Buf[BUFSIZ]; /* general scribbling buffer */
|
||||
char Maze[HEIGHT][WIDTH2]; /* the maze */
|
||||
char Orig_maze[HEIGHT][WIDTH2]; /* the original maze */
|
||||
|
||||
fd_set Fds_mask; /* mask for the file descriptors */
|
||||
fd_set Have_inp; /* which file descriptors have input */
|
||||
int Nplayer = 0; /* number of players */
|
||||
int Num_fds; /* number of maximum file descriptor */
|
||||
int Socket; /* main socket */
|
||||
int Status; /* stat socket */
|
||||
int See_over[NASCII]; /* lookup table for determining whether
|
||||
* character represents "transparent"
|
||||
* item */
|
||||
|
||||
BULLET *Bullets = NULL; /* linked list of bullets */
|
||||
|
||||
EXPL *Expl[EXPLEN]; /* explosion lists */
|
||||
EXPL *Last_expl; /* last explosion on Expl[0] */
|
||||
|
||||
PLAYER Player[MAXPL]; /* all the players */
|
||||
PLAYER *End_player = Player; /* last active player slot */
|
||||
# ifdef BOOTS
|
||||
PLAYER Boot[NBOOTS]; /* all the boots */
|
||||
# endif
|
||||
IDENT *Scores; /* score cache */
|
||||
# ifdef MONITOR
|
||||
PLAYER Monitor[MAXMON]; /* all the monitors */
|
||||
PLAYER *End_monitor = Monitor; /* last active monitor slot */
|
||||
# endif
|
||||
|
||||
# ifdef VOLCANO
|
||||
int volcano = 0; /* Explosion size */
|
||||
# endif
|
||||
|
||||
int shot_req[MAXBOMB] = {
|
||||
BULREQ, GRENREQ, SATREQ,
|
||||
BOMB7REQ, BOMB9REQ, BOMB11REQ,
|
||||
BOMB13REQ, BOMB15REQ, BOMB17REQ,
|
||||
BOMB19REQ, BOMB21REQ,
|
||||
};
|
||||
int shot_type[MAXBOMB] = {
|
||||
SHOT, GRENADE, SATCHEL,
|
||||
BOMB, BOMB, BOMB,
|
||||
BOMB, BOMB, BOMB,
|
||||
BOMB, BOMB,
|
||||
};
|
||||
|
||||
int slime_req[MAXSLIME] = {
|
||||
SLIMEREQ, SSLIMEREQ, SLIME2REQ, SLIME3REQ,
|
||||
};
|
||||
232
hunt/huntd/faketalk.c
Normal file
232
hunt/huntd/faketalk.c
Normal file
@@ -0,0 +1,232 @@
|
||||
/* $NetBSD: faketalk.c,v 1.4 1997/10/11 08:13:48 lukem Exp $ */
|
||||
/*
|
||||
* Hunt
|
||||
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
* San Francisco, California
|
||||
*
|
||||
* Copyright (c) 1985 Regents of the University of California.
|
||||
* All rights reserved. The Berkeley software License Agreement
|
||||
* specifies the terms and conditions for redistribution.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: faketalk.c,v 1.4 1997/10/11 08:13:48 lukem Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include "bsd.h"
|
||||
|
||||
#if defined(TALK_43) || defined(TALK_42)
|
||||
|
||||
# include <sys/time.h>
|
||||
# include <sys/wait.h>
|
||||
# include <ctype.h>
|
||||
# include <netdb.h>
|
||||
# include <signal.h>
|
||||
# include <stdio.h>
|
||||
# include <string.h>
|
||||
# include <unistd.h>
|
||||
# include "hunt.h"
|
||||
# include "talk_ctl.h"
|
||||
|
||||
# define TRUE 1
|
||||
# define FALSE 0
|
||||
|
||||
/* defines for fake talk message to announce start of game */
|
||||
# ifdef TALK_43
|
||||
# define MASQUERADE "\"Hunt Game\""
|
||||
# else
|
||||
# define MASQUERADE "HuntGame"
|
||||
# endif
|
||||
# define RENDEZVOUS "hunt-players"
|
||||
# define ARGV0 "HUNT-ANNOUNCE"
|
||||
|
||||
extern char *my_machine_name;
|
||||
extern char *First_arg, *Last_arg;
|
||||
|
||||
static void do_announce __P((char *));
|
||||
SIGNAL_TYPE exorcise __P((int));
|
||||
|
||||
/*
|
||||
* exorcise - disspell zombies
|
||||
*/
|
||||
|
||||
SIGNAL_TYPE
|
||||
exorcise(dummy)
|
||||
int dummy __attribute__((unused));
|
||||
{
|
||||
(void) wait(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* query the local SMTP daemon to expand the RENDEZVOUS mailing list
|
||||
* and fake a talk request to each address thus found.
|
||||
*/
|
||||
|
||||
void
|
||||
faketalk()
|
||||
{
|
||||
struct servent *sp;
|
||||
char buf[BUFSIZ];
|
||||
FILE *f;
|
||||
int service; /* socket of service */
|
||||
struct sockaddr_in des; /* address of destination */
|
||||
char *a;
|
||||
const char *b;
|
||||
extern char **environ;
|
||||
|
||||
(void) signal(SIGCHLD, exorcise);
|
||||
|
||||
if (fork() != 0)
|
||||
return;
|
||||
|
||||
(void) signal(SIGINT, SIG_IGN);
|
||||
(void) signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
/*
|
||||
* change argv so that a ps shows ARGV0
|
||||
*/
|
||||
*environ = NULL;
|
||||
for (a = First_arg, b = ARGV0; a < Last_arg; a++) {
|
||||
if (*b)
|
||||
*a = *b++;
|
||||
else
|
||||
*a = ' ';
|
||||
}
|
||||
|
||||
/*
|
||||
* initialize "talk"
|
||||
*/
|
||||
get_local_name(MASQUERADE);
|
||||
open_ctl();
|
||||
|
||||
/*
|
||||
* start fetching addresses
|
||||
*/
|
||||
|
||||
if ((sp = getservbyname("smtp", (char *) NULL)) == NULL) {
|
||||
# ifdef LOG
|
||||
syslog(LOG_ERR, "faketalk: smtp protocol not supported\n");
|
||||
# else
|
||||
warn("faketalk: smtp protocol not supported");
|
||||
# endif
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
memset(&des, 0, sizeof (des));
|
||||
des.sin_family = AF_INET;
|
||||
des.sin_addr = my_machine_addr;
|
||||
des.sin_port = sp->s_port;
|
||||
|
||||
if ((service = socket(des.sin_family, SOCK_STREAM, 0)) < 0) {
|
||||
# ifdef LOG
|
||||
syslog(LOG_ERR, "falktalk: socket");
|
||||
# else
|
||||
warn("falktalk: socket");
|
||||
# endif
|
||||
_exit(-1);
|
||||
}
|
||||
|
||||
if (connect(service, (struct sockaddr *) &des, sizeof(des)) != 0) {
|
||||
# ifdef LOG
|
||||
syslog(LOG_ERR, "faketalk: connect");
|
||||
# else
|
||||
warn("faketalk: connect");
|
||||
# endif
|
||||
_exit(-1);
|
||||
}
|
||||
if ((f = fdopen(service, "r")) == NULL) {
|
||||
# ifdef LOG
|
||||
syslog(LOG_ERR, "fdopen failed\n");
|
||||
# else
|
||||
warn("faketalk: fdopen");
|
||||
# endif
|
||||
_exit(-2);
|
||||
}
|
||||
|
||||
(void) fgets(buf, BUFSIZ, f);
|
||||
(void) sprintf(buf, "HELO HuntGame@%s\r\n", my_machine_name);
|
||||
(void) write(service, buf, strlen(buf));
|
||||
(void) fgets(buf, BUFSIZ, f);
|
||||
(void) sprintf(buf, "EXPN %s@%s\r\n", RENDEZVOUS, my_machine_name);
|
||||
(void) write(service, buf, strlen(buf));
|
||||
while (fgets(buf, BUFSIZ, f) != NULL) {
|
||||
char *s, *t;
|
||||
|
||||
if (buf[0] != '2' || buf[1] != '5' || buf[2] != '0')
|
||||
break;
|
||||
if ((s = strchr(buf + 4, '<')) == NULL)
|
||||
s = buf + 4, t = buf + strlen(buf) - 1;
|
||||
else {
|
||||
s += 1;
|
||||
if ((t = strrchr(s, '>')) == NULL)
|
||||
t = s + strlen(s) - 1;
|
||||
else
|
||||
t -= 1;
|
||||
}
|
||||
while (isspace(*s))
|
||||
s += 1;
|
||||
if (*s == '\\')
|
||||
s += 1;
|
||||
while (isspace(*t))
|
||||
t -= 1;
|
||||
*(t + 1) = '\0';
|
||||
do_announce(s); /* construct and send talk request */
|
||||
if (buf[3] == ' ')
|
||||
break;
|
||||
}
|
||||
(void) shutdown(service, 2);
|
||||
(void) close(service);
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* The msg.id's for the invitations on the local and remote machines.
|
||||
* These are used to delete the invitations.
|
||||
*/
|
||||
|
||||
static void
|
||||
do_announce(s)
|
||||
char *s;
|
||||
{
|
||||
CTL_RESPONSE response;
|
||||
extern struct sockaddr_in ctl_addr;
|
||||
|
||||
get_remote_name(s); /* setup his_machine_addr, msg.r_name */
|
||||
|
||||
# ifdef TALK_43
|
||||
# if BSD_RELEASE >= 44
|
||||
msg.ctl_addr = *(struct osockaddr *) &ctl_addr;
|
||||
# else
|
||||
msg.ctl_addr = *(struct sockaddr *) &ctl_addr;
|
||||
# endif
|
||||
msg.ctl_addr.sa_family = htons(msg.ctl_addr.sa_family);
|
||||
# else
|
||||
msg.ctl_addr = ctl_addr;
|
||||
msg.ctl_addr.sin_family = htons(msg.ctl_addr.sin_family);
|
||||
# endif
|
||||
msg.id_num = (int) htonl((u_int32_t) -1); /* an impossible id_num */
|
||||
ctl_transact(his_machine_addr, msg, ANNOUNCE, &response);
|
||||
if (response.answer != SUCCESS)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Have the daemons delete the invitations now that we
|
||||
* have announced.
|
||||
*/
|
||||
|
||||
/* we don't care if cleanup doesn't make it. */
|
||||
msg.type = DELETE;
|
||||
msg.id_num = (int) htonl(response.id_num);
|
||||
daemon_addr.sin_addr = his_machine_addr;
|
||||
if (sendto(ctl_sockt, (char *) &msg, sizeof (msg), 0,
|
||||
(struct sockaddr *) &daemon_addr, sizeof(daemon_addr))
|
||||
!= sizeof(msg))
|
||||
p_error("send delete remote");
|
||||
}
|
||||
#else
|
||||
faketalk()
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
133
hunt/huntd/get_names.c
Normal file
133
hunt/huntd/get_names.c
Normal file
@@ -0,0 +1,133 @@
|
||||
/* $NetBSD: get_names.c,v 1.3 1998/07/06 07:00:31 mrg Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1983 Regents of the University of California.
|
||||
* All rights reserved. The Berkeley software License Agreement
|
||||
* specifies the terms and conditions for redistribution.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: get_names.c,v 1.3 1998/07/06 07:00:31 mrg Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include "bsd.h"
|
||||
|
||||
#if defined(TALK_43) || defined(TALK_42)
|
||||
|
||||
# include <sys/param.h>
|
||||
# include <netdb.h>
|
||||
# include <stdio.h>
|
||||
# include <string.h>
|
||||
# include <unistd.h>
|
||||
# include "hunt.h"
|
||||
# include "talk_ctl.h"
|
||||
|
||||
extern CTL_MSG msg;
|
||||
|
||||
static char hostname[MAXHOSTNAMELEN + 1];
|
||||
char *my_machine_name;
|
||||
|
||||
/*
|
||||
* Determine the local user and machine
|
||||
*/
|
||||
void
|
||||
get_local_name(my_name)
|
||||
const char *my_name;
|
||||
{
|
||||
struct hostent *hp;
|
||||
struct servent *sp;
|
||||
|
||||
/* Load these useful values into the standard message header */
|
||||
msg.id_num = 0;
|
||||
(void) strncpy(msg.l_name, my_name, NAME_SIZE);
|
||||
msg.l_name[NAME_SIZE - 1] = '\0';
|
||||
msg.r_tty[0] = '\0';
|
||||
msg.pid = getpid();
|
||||
# ifdef TALK_43
|
||||
msg.vers = TALK_VERSION;
|
||||
msg.addr.sa_family = htons(AF_INET);
|
||||
msg.ctl_addr.sa_family = htons(AF_INET);
|
||||
# else
|
||||
msg.addr.sin_family = htons(AF_INET);
|
||||
msg.ctl_addr.sin_family = htons(AF_INET);
|
||||
# endif
|
||||
|
||||
(void)gethostname(hostname, sizeof (hostname));
|
||||
hostname[sizeof(hostname) - 1] = '\0';
|
||||
my_machine_name = hostname;
|
||||
/* look up the address of the local host */
|
||||
hp = gethostbyname(my_machine_name);
|
||||
if (hp == (struct hostent *) 0) {
|
||||
printf("This machine doesn't exist. Boy, am I confused!\n");
|
||||
exit(-1);
|
||||
}
|
||||
memcpy(&my_machine_addr, hp->h_addr, hp->h_length);
|
||||
/* find the daemon portal */
|
||||
# ifdef TALK_43
|
||||
sp = getservbyname("ntalk", "udp");
|
||||
# else
|
||||
sp = getservbyname("talk", "udp");
|
||||
# endif
|
||||
if (sp == 0) {
|
||||
# ifdef LOG
|
||||
syslog(LOG_ERR, "This machine doesn't support talk");
|
||||
# else
|
||||
perror("This machine doesn't support talk");
|
||||
# endif
|
||||
exit(-1);
|
||||
}
|
||||
daemon_port = sp->s_port;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine the remote user and machine
|
||||
*/
|
||||
int
|
||||
get_remote_name(his_address)
|
||||
char *his_address;
|
||||
{
|
||||
char *his_name;
|
||||
char *his_machine_name;
|
||||
char *ptr;
|
||||
struct hostent *hp;
|
||||
|
||||
|
||||
/* check for, and strip out, the machine name of the target */
|
||||
for (ptr = his_address; *ptr != '\0' && *ptr != '@' && *ptr != ':'
|
||||
&& *ptr != '!' && *ptr != '.'; ptr++)
|
||||
continue;
|
||||
if (*ptr == '\0') {
|
||||
/* this is a local to local talk */
|
||||
his_name = his_address;
|
||||
his_machine_name = my_machine_name;
|
||||
} else {
|
||||
if (*ptr == '@') {
|
||||
/* user@host */
|
||||
his_name = his_address;
|
||||
his_machine_name = ptr + 1;
|
||||
} else {
|
||||
/* host.user or host!user or host:user */
|
||||
his_name = ptr + 1;
|
||||
his_machine_name = his_address;
|
||||
}
|
||||
*ptr = '\0';
|
||||
}
|
||||
/* Load these useful values into the standard message header */
|
||||
(void) strncpy(msg.r_name, his_name, NAME_SIZE);
|
||||
msg.r_name[NAME_SIZE - 1] = '\0';
|
||||
|
||||
/* if he is on the same machine, then simply copy */
|
||||
if (memcmp((char *) &his_machine_name, (char *) &my_machine_name,
|
||||
sizeof(his_machine_name)) == 0)
|
||||
memcpy(&his_machine_addr, &my_machine_addr,
|
||||
sizeof(his_machine_name));
|
||||
else {
|
||||
/* look up the address of the recipient's machine */
|
||||
hp = gethostbyname(his_machine_name);
|
||||
if (hp == (struct hostent *) 0)
|
||||
return 0; /* unknown host */
|
||||
memcpy(&his_machine_addr, hp->h_addr, hp->h_length);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
458
hunt/huntd/hunt.h
Normal file
458
hunt/huntd/hunt.h
Normal file
@@ -0,0 +1,458 @@
|
||||
/* $NetBSD: hunt.h,v 1.5 1998/09/13 15:27:28 hubertf Exp $ */
|
||||
|
||||
/*
|
||||
* Hunt
|
||||
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
* San Francisco, California
|
||||
*/
|
||||
|
||||
# include "bsd.h"
|
||||
|
||||
# include <errno.h>
|
||||
# include <stdio.h>
|
||||
# include <string.h>
|
||||
# ifdef LOG
|
||||
# include <syslog.h>
|
||||
# endif
|
||||
# if !defined(TERMINFO) && BSD_RELEASE < 44
|
||||
# include <sgtty.h>
|
||||
# else
|
||||
# include <sys/ioctl.h>
|
||||
# endif
|
||||
# include <sys/types.h>
|
||||
# include <sys/uio.h>
|
||||
# include <sys/socket.h>
|
||||
# ifdef INTERNET
|
||||
# include <netinet/in.h>
|
||||
# include <netdb.h>
|
||||
# include <arpa/inet.h>
|
||||
# ifdef BROADCAST
|
||||
# include <net/if.h>
|
||||
# endif
|
||||
# else
|
||||
# include <sys/un.h>
|
||||
# endif
|
||||
|
||||
# ifdef INTERNET
|
||||
# define SOCK_FAMILY AF_INET
|
||||
# else
|
||||
# define SOCK_FAMILY AF_UNIX
|
||||
# define AF_UNIX_HACK /* 4.2 hack; leaves files around */
|
||||
# endif
|
||||
|
||||
/*
|
||||
* Preprocessor define dependencies
|
||||
*/
|
||||
# if defined(VOLCANO) && !defined(OOZE)
|
||||
# define OOZE
|
||||
# endif
|
||||
# if defined(BOOTS) && !defined(FLY)
|
||||
# define FLY
|
||||
# endif
|
||||
# if !defined(REFLECT) && !defined(RANDOM)
|
||||
# define RANDOM
|
||||
# endif
|
||||
# ifdef TERMINFO
|
||||
/* mvcur() in terminfo needs the curses library to be initialized to not
|
||||
* coredump, so give up and use it. */
|
||||
# define USE_CURSES
|
||||
# endif
|
||||
|
||||
/* decrement version number for each change in startup protocol */
|
||||
# define HUNT_VERSION -1
|
||||
|
||||
# define ADDCH ('a' | 0200)
|
||||
# define MOVE ('m' | 0200)
|
||||
# define REFRESH ('r' | 0200)
|
||||
# define CLRTOEOL ('c' | 0200)
|
||||
# define ENDWIN ('e' | 0200)
|
||||
# define CLEAR ('C' | 0200)
|
||||
# define REDRAW ('R' | 0200)
|
||||
# define LAST_PLAYER ('l' | 0200)
|
||||
# define BELL ('b' | 0200)
|
||||
# define READY ('g' | 0200)
|
||||
|
||||
/*
|
||||
* Choose MAXPL and MAXMON carefully. The screen is assumed to be
|
||||
* 23 lines high and will only tolerate (MAXPL == 17 && MAXMON == 0)
|
||||
* or (MAXPL + MAXMON <= 16).
|
||||
*/
|
||||
# ifdef MONITOR
|
||||
# define MAXPL 15
|
||||
# define MAXMON 1
|
||||
# else
|
||||
# define MAXPL 17
|
||||
# endif
|
||||
# define SHORTLEN 2 /* sizeof (network short) */
|
||||
# define LONGLEN 4 /* sizeof (network long) */
|
||||
# define NAMELEN 20
|
||||
# define MSGLEN SCREEN_WIDTH
|
||||
# define DECAY 50.0
|
||||
|
||||
# define NASCII 128
|
||||
|
||||
# define WIDTH 51
|
||||
# define WIDTH2 64 /* Next power of 2 >= WIDTH (for fast access) */
|
||||
# define HEIGHT 23
|
||||
# define UBOUND 1
|
||||
# define DBOUND (HEIGHT - 1)
|
||||
# define LBOUND 1
|
||||
# define RBOUND (WIDTH - 1)
|
||||
|
||||
# define SCREEN_HEIGHT 24
|
||||
# define SCREEN_WIDTH 80
|
||||
# define SCREEN_WIDTH2 128 /* Next power of 2 >= SCREEN_WIDTH */
|
||||
|
||||
# define STAT_LABEL_COL 60
|
||||
# define STAT_VALUE_COL 74
|
||||
# define STAT_NAME_COL 61
|
||||
# define STAT_SCAN_COL (STAT_NAME_COL + 5)
|
||||
# define STAT_AMMO_ROW 0
|
||||
# define STAT_GUN_ROW 1
|
||||
# define STAT_DAM_ROW 2
|
||||
# define STAT_KILL_ROW 3
|
||||
# define STAT_PLAY_ROW 5
|
||||
# ifdef MONITOR
|
||||
# define STAT_MON_ROW (STAT_PLAY_ROW + MAXPL + 1)
|
||||
# endif
|
||||
# define STAT_NAME_LEN 18
|
||||
|
||||
# define DOOR '#'
|
||||
# define WALL1 '-'
|
||||
# define WALL2 '|'
|
||||
# define WALL3 '+'
|
||||
# ifdef REFLECT
|
||||
# define WALL4 '/'
|
||||
# define WALL5 '\\'
|
||||
# endif
|
||||
# define KNIFE 'K'
|
||||
# define SHOT ':'
|
||||
# define GRENADE 'o'
|
||||
# define SATCHEL 'O'
|
||||
# define BOMB '@'
|
||||
# define MINE ';'
|
||||
# define GMINE 'g'
|
||||
# ifdef OOZE
|
||||
# define SLIME '$'
|
||||
# endif
|
||||
# ifdef VOLCANO
|
||||
# define LAVA '~'
|
||||
# endif
|
||||
# ifdef DRONE
|
||||
# define DSHOT '?'
|
||||
# endif
|
||||
# ifdef FLY
|
||||
# define FALL 'F'
|
||||
# endif
|
||||
# ifdef BOOTS
|
||||
# define NBOOTS 2
|
||||
# define BOOT 'b'
|
||||
# define BOOT_PAIR 'B'
|
||||
# endif
|
||||
# define SPACE ' '
|
||||
|
||||
# define ABOVE 'i'
|
||||
# define BELOW '!'
|
||||
# define RIGHT '}'
|
||||
# define LEFTS '{'
|
||||
# ifdef FLY
|
||||
# define FLYER '&'
|
||||
# define is_player(c) (c == LEFTS || c == RIGHT ||\
|
||||
c == ABOVE || c == BELOW || c == FLYER)
|
||||
# else
|
||||
# define is_player(c) (c == LEFTS || c == RIGHT ||\
|
||||
c == ABOVE || c == BELOW)
|
||||
# endif
|
||||
|
||||
# define NORTH 01
|
||||
# define SOUTH 02
|
||||
# define EAST 010
|
||||
# define WEST 020
|
||||
|
||||
# ifndef TRUE
|
||||
# define TRUE 1
|
||||
# define FALSE 0
|
||||
# endif
|
||||
# undef CTRL
|
||||
# define CTRL(x) ((x) & 037)
|
||||
|
||||
# define BULSPD 5 /* bullets movement speed */
|
||||
# define ISHOTS 15
|
||||
# define NSHOTS 5
|
||||
# define MAXNCSHOT 2
|
||||
# define MAXDAM 10
|
||||
# define MINDAM 5
|
||||
# define STABDAM 2
|
||||
|
||||
# define BULREQ 1
|
||||
# define GRENREQ 9
|
||||
# define SATREQ 25
|
||||
# define BOMB7REQ 49
|
||||
# define BOMB9REQ 81
|
||||
# define BOMB11REQ 121
|
||||
# define BOMB13REQ 169
|
||||
# define BOMB15REQ 225
|
||||
# define BOMB17REQ 289
|
||||
# define BOMB19REQ 361
|
||||
# define BOMB21REQ 441
|
||||
# define MAXBOMB 11
|
||||
# ifdef DRONE
|
||||
# define MINDSHOT 2 /* At least a satchel bomb */
|
||||
# endif
|
||||
extern int shot_req[];
|
||||
extern int shot_type[];
|
||||
# ifdef OOZE
|
||||
# define SLIME_FACTOR 3
|
||||
# define SLIMEREQ 5
|
||||
# define SSLIMEREQ 10
|
||||
# define SLIME2REQ 15
|
||||
# define SLIME3REQ 20
|
||||
# define MAXSLIME 4
|
||||
# define SLIMESPEED 5
|
||||
extern int slime_req[];
|
||||
# endif
|
||||
# ifdef VOLCANO
|
||||
# define LAVASPEED 1
|
||||
# endif
|
||||
|
||||
# define CLOAKLEN 20
|
||||
# define SCANLEN (Nplayer * 20)
|
||||
# define EXPLEN 4
|
||||
|
||||
# define Q_QUIT 0
|
||||
# define Q_CLOAK 1
|
||||
# define Q_FLY 2
|
||||
# define Q_SCAN 3
|
||||
# define Q_MESSAGE 4
|
||||
|
||||
# define C_PLAYER 0
|
||||
# define C_MONITOR 1
|
||||
# define C_MESSAGE 2
|
||||
# define C_SCORES 3
|
||||
|
||||
# ifdef MONITOR
|
||||
# define C_TESTMSG() (Query_driver ? C_MESSAGE :\
|
||||
(Show_scores ? C_SCORES :\
|
||||
(Am_monitor ? C_MONITOR :\
|
||||
C_PLAYER)))
|
||||
# else
|
||||
# define C_TESTMSG() (Show_scores ? C_SCORES :\
|
||||
(Query_driver ? C_MESSAGE :\
|
||||
C_PLAYER))
|
||||
# endif
|
||||
|
||||
# ifdef FLY
|
||||
# define _scan_char(pp) (((pp)->p_scan < 0) ? ' ' : '*')
|
||||
# define _cloak_char(pp) (((pp)->p_cloak < 0) ? _scan_char(pp) : '+')
|
||||
# define stat_char(pp) (((pp)->p_flying < 0) ? _cloak_char(pp) : FLYER)
|
||||
# else
|
||||
# define _scan_char(pp) (((pp)->p_scan < 0) ? ' ' : '*')
|
||||
# define stat_char(pp) (((pp)->p_cloak < 0) ? _scan_char(pp) : '+')
|
||||
# endif
|
||||
|
||||
typedef int FLAG;
|
||||
typedef struct bullet_def BULLET;
|
||||
typedef struct expl_def EXPL;
|
||||
typedef struct player_def PLAYER;
|
||||
typedef struct ident_def IDENT;
|
||||
typedef struct regen_def REGEN;
|
||||
# ifdef INTERNET
|
||||
typedef struct sockaddr_in SOCKET;
|
||||
# else
|
||||
typedef struct sockaddr_un SOCKET;
|
||||
# endif
|
||||
|
||||
struct ident_def {
|
||||
char i_name[NAMELEN];
|
||||
char i_team;
|
||||
long i_machine;
|
||||
long i_uid;
|
||||
float i_kills;
|
||||
int i_entries;
|
||||
float i_score;
|
||||
int i_absorbed;
|
||||
int i_faced;
|
||||
int i_shot;
|
||||
int i_robbed;
|
||||
int i_slime;
|
||||
int i_missed;
|
||||
int i_ducked;
|
||||
int i_gkills, i_bkills, i_deaths, i_stillb, i_saved;
|
||||
IDENT *i_next;
|
||||
};
|
||||
|
||||
struct player_def {
|
||||
IDENT *p_ident;
|
||||
char p_over;
|
||||
int p_face;
|
||||
int p_undershot;
|
||||
# ifdef FLY
|
||||
int p_flying;
|
||||
int p_flyx, p_flyy;
|
||||
# endif
|
||||
# ifdef BOOTS
|
||||
int p_nboots;
|
||||
# endif
|
||||
FILE *p_output;
|
||||
int p_fd;
|
||||
int p_mask;
|
||||
int p_damage;
|
||||
int p_damcap;
|
||||
int p_ammo;
|
||||
int p_ncshot;
|
||||
int p_scan;
|
||||
int p_cloak;
|
||||
int p_x, p_y;
|
||||
int p_ncount;
|
||||
int p_nexec;
|
||||
long p_nchar;
|
||||
char p_death[MSGLEN];
|
||||
char p_maze[HEIGHT][WIDTH2];
|
||||
int p_curx, p_cury;
|
||||
int p_lastx, p_lasty;
|
||||
char p_cbuf[BUFSIZ];
|
||||
};
|
||||
|
||||
struct bullet_def {
|
||||
int b_x, b_y;
|
||||
int b_face;
|
||||
int b_charge;
|
||||
char b_type;
|
||||
char b_size;
|
||||
char b_over;
|
||||
PLAYER *b_owner;
|
||||
IDENT *b_score;
|
||||
FLAG b_expl;
|
||||
BULLET *b_next;
|
||||
};
|
||||
|
||||
struct expl_def {
|
||||
int e_x, e_y;
|
||||
char e_char;
|
||||
EXPL *e_next;
|
||||
};
|
||||
|
||||
struct regen_def {
|
||||
int r_x, r_y;
|
||||
REGEN *r_next;
|
||||
};
|
||||
|
||||
/*
|
||||
* external variables
|
||||
*/
|
||||
|
||||
extern FLAG Last_player;
|
||||
|
||||
extern char Buf[BUFSIZ], Maze[HEIGHT][WIDTH2], Orig_maze[HEIGHT][WIDTH2];
|
||||
|
||||
extern char *Sock_name;
|
||||
extern const char *Driver;
|
||||
|
||||
extern int Nplayer, Num_fds, Socket, Status;
|
||||
extern fd_set Fds_mask, Have_inp;
|
||||
|
||||
# ifdef INTERNET
|
||||
extern u_short Test_port;
|
||||
# else
|
||||
extern char *Sock_name;
|
||||
# endif
|
||||
|
||||
# ifdef VOLCANO
|
||||
extern int volcano;
|
||||
# endif
|
||||
|
||||
extern int See_over[NASCII];
|
||||
|
||||
extern BULLET *Bullets;
|
||||
|
||||
extern EXPL *Expl[EXPLEN];
|
||||
extern EXPL *Last_expl;
|
||||
|
||||
extern IDENT *Scores;
|
||||
|
||||
extern PLAYER Player[MAXPL], *End_player;
|
||||
# ifdef BOOTS
|
||||
extern PLAYER Boot[NBOOTS];
|
||||
# endif
|
||||
|
||||
# ifdef MONITOR
|
||||
extern FLAG Am_monitor;
|
||||
extern PLAYER Monitor[MAXMON], *End_monitor;
|
||||
# endif
|
||||
|
||||
# ifdef INTERNET
|
||||
extern char *Send_message;
|
||||
# endif
|
||||
|
||||
extern char map_key[256];
|
||||
extern FLAG no_beep;
|
||||
|
||||
/*
|
||||
* function types
|
||||
*/
|
||||
|
||||
void add_shot __P((int, int, int, char, int, PLAYER *, int, char));
|
||||
int answer __P((void));
|
||||
void bad_con __P((void));
|
||||
void bad_ver __P((void));
|
||||
int broadcast_vec __P((int, struct sockaddr **));
|
||||
void ce __P((PLAYER *));
|
||||
void cgoto __P((PLAYER *, int, int));
|
||||
void check __P((PLAYER *, int, int));
|
||||
void checkdam __P((PLAYER *, PLAYER *, IDENT *, int, char));
|
||||
void clearwalls __P((void));
|
||||
void clear_eol __P((void));
|
||||
void clear_the_screen __P((void));
|
||||
void clrscr __P((PLAYER *));
|
||||
BULLET *create_shot __P((int, int, int, char, int, int, PLAYER *,
|
||||
IDENT *, int, char));
|
||||
void do_connect __P((const char *, char, long));
|
||||
void do_message __P((void));
|
||||
void drawmaze __P((PLAYER *));
|
||||
void drawplayer __P((PLAYER *, FLAG));
|
||||
void drawstatus __P((PLAYER *));
|
||||
void execute __P((PLAYER *));
|
||||
void faketalk __P((void));
|
||||
void find_driver __P((FLAG));
|
||||
void fixshots __P((int, int, char));
|
||||
IDENT *get_ident __P((u_long, u_long, const char *, char));
|
||||
void get_local_name __P((const char *));
|
||||
int get_remote_name __P((char *));
|
||||
BULLET *is_bullet __P((int, int));
|
||||
void look __P((PLAYER *));
|
||||
void makemaze __P((void));
|
||||
void message __P((PLAYER *, const char *));
|
||||
void mon_execute __P((PLAYER *));
|
||||
void moveshots __P((void));
|
||||
void open_ctl __P((void));
|
||||
int opposite __P((int, char));
|
||||
void otto __P((int, int, char));
|
||||
void outch __P((PLAYER *, int));
|
||||
void outstr __P((PLAYER *, const char *, int));
|
||||
int player_sym __P((const PLAYER *, int, int));
|
||||
PLAYER *play_at __P((int, int));
|
||||
void playit __P((void));
|
||||
void put_ch __P((char));
|
||||
# ifndef USE_CURSES
|
||||
void put_str __P((const char *));
|
||||
# endif
|
||||
int quit __P((int));
|
||||
int rand_dir __P((void));
|
||||
int rand_num __P((int));
|
||||
void redraw_screen __P((void));
|
||||
void rmnl __P((char *));
|
||||
void rollexpl __P((void));
|
||||
void see __P((PLAYER *, int));
|
||||
void sendcom __P((PLAYER *, int, ...));
|
||||
void showexpl __P((int, int, char));
|
||||
void showstat __P((PLAYER *));
|
||||
void start_driver __P((void));
|
||||
void stmonitor __P((PLAYER *));
|
||||
void stplayer __P((PLAYER *, int));
|
||||
char translate __P((char));
|
||||
SIGNAL_TYPE cleanup __P((int)) __attribute__((__noreturn__));
|
||||
SIGNAL_TYPE intr __P((int));
|
||||
SIGNAL_TYPE sigalrm __P((int));
|
||||
SIGNAL_TYPE sigemt __P((int));
|
||||
SIGNAL_TYPE sigterm __P((int));
|
||||
SIGNAL_TYPE tstp __P((int));
|
||||
100
hunt/huntd/huntd.6.in
Normal file
100
hunt/huntd/huntd.6.in
Normal file
@@ -0,0 +1,100 @@
|
||||
.\" $NetBSD: huntd.6,v 1.3 1998/01/09 08:03:42 perry Exp $
|
||||
.\"
|
||||
.\" Hunt
|
||||
.\" Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
.\" San Francisco, California
|
||||
.\"
|
||||
.\" Copyright (c) 1985 Regents of the University of California.
|
||||
.\" All rights reserved. The Berkeley software License Agreement
|
||||
.\" specifies the terms and conditions for redistribution.
|
||||
.\"
|
||||
.TH HUNTD 6 "21 August 1986"
|
||||
.UC 4
|
||||
.SH NAME
|
||||
huntd \- hunt daemon, back-end for hunt game
|
||||
.SH SYNOPSIS
|
||||
\fB@sbindir@/huntd\fP [ \fB\-s\fP ] [ \fB\-p\fP port ]
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
.I huntd
|
||||
controls the multi-player
|
||||
.IR hunt (6)
|
||||
game.
|
||||
When it starts up, it tries to notify all members of the
|
||||
.I hunt-players
|
||||
mailing list (see
|
||||
.IR sendmail (8))
|
||||
by faking a
|
||||
.IR talk (1)
|
||||
request from user ``Hunt Game''.
|
||||
.PP
|
||||
The
|
||||
.B \-s
|
||||
option is for running
|
||||
.I huntd
|
||||
forever (server mode).
|
||||
This is similar to running it under the control of
|
||||
.I inetd
|
||||
(see below),
|
||||
but it consumes a process table entry when no one is playing.
|
||||
.PP
|
||||
The
|
||||
.B \-p
|
||||
option changes the udp port number used to rendezvous with the player
|
||||
process and thus allows for private games of hunt.
|
||||
This option turns off the notification of players on the
|
||||
.I hunt-players
|
||||
mailing list.
|
||||
.SH INETD
|
||||
.PP
|
||||
To run
|
||||
.I huntd
|
||||
from
|
||||
.IR inetd ,
|
||||
you'll need to put the
|
||||
.I hunt
|
||||
service in
|
||||
.BR /etc/services :
|
||||
.IP
|
||||
hunt 26740/udp # multi-player/multi-host mazewars
|
||||
.LP
|
||||
and add a line in
|
||||
.BR /etc/inetd.conf :
|
||||
.IP
|
||||
hunt dgram udp wait nobody @sbindir@/huntd HUNT
|
||||
.LP
|
||||
except for Suns which use
|
||||
.BR /etc/servers :
|
||||
.IP
|
||||
hunt udp @sbindir@/huntd
|
||||
.LP
|
||||
Do not use any of the command line options \(em if you want
|
||||
.I inetd
|
||||
to start up
|
||||
.I huntd
|
||||
on a private port, change the port listed in
|
||||
.BR /etc/services .
|
||||
.SH "NETWORK RENDEZVOUS"
|
||||
When
|
||||
.IR hunt (6)
|
||||
starts up, it broadcasts on the local area net
|
||||
(using the broadcast address for each interface) to find a
|
||||
.I hunt
|
||||
game in progress.
|
||||
If a
|
||||
.I huntd
|
||||
hears the request, it sends back the port number for the
|
||||
.I hunt
|
||||
process to connect to.
|
||||
Otherwise, the
|
||||
.I hunt
|
||||
process starts up a
|
||||
.I huntd
|
||||
on the local machine and trys to rendezvous with it.
|
||||
.SH "SEE ALSO"
|
||||
hunt(6), talk(1), sendmail(8)
|
||||
.SH AUTHORS
|
||||
Conrad Huang, Ken Arnold, and Greg Couch;
|
||||
.br
|
||||
University of California, San Francisco, Computer Graphics Lab
|
||||
.\"SH BUGS
|
||||
208
hunt/huntd/makemaze.c
Normal file
208
hunt/huntd/makemaze.c
Normal file
@@ -0,0 +1,208 @@
|
||||
/* $NetBSD: makemaze.c,v 1.2 1997/10/10 16:33:43 lukem Exp $ */
|
||||
/*
|
||||
* Hunt
|
||||
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
* San Francisco, California
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: makemaze.c,v 1.2 1997/10/10 16:33:43 lukem Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
# include "hunt.h"
|
||||
|
||||
# define ISCLEAR(y,x) (Maze[y][x] == SPACE)
|
||||
# define ODD(n) ((n) & 01)
|
||||
|
||||
static int candig __P((int, int));
|
||||
static void dig __P((int, int));
|
||||
static void dig_maze __P((int, int));
|
||||
static void remap __P((void));
|
||||
|
||||
void
|
||||
makemaze()
|
||||
{
|
||||
char *sp;
|
||||
int y, x;
|
||||
|
||||
/*
|
||||
* fill maze with walls
|
||||
*/
|
||||
sp = &Maze[0][0];
|
||||
while (sp < &Maze[HEIGHT - 1][WIDTH])
|
||||
*sp++ = DOOR;
|
||||
|
||||
x = rand_num(WIDTH / 2) * 2 + 1;
|
||||
y = rand_num(HEIGHT / 2) * 2 + 1;
|
||||
dig_maze(x, y);
|
||||
remap();
|
||||
}
|
||||
|
||||
# define NPERM 24
|
||||
# define NDIR 4
|
||||
|
||||
int dirs[NPERM][NDIR] = {
|
||||
{0,1,2,3}, {3,0,1,2}, {0,2,3,1}, {0,3,2,1},
|
||||
{1,0,2,3}, {2,3,0,1}, {0,2,1,3}, {2,3,1,0},
|
||||
{1,0,3,2}, {1,2,0,3}, {3,1,2,0}, {2,0,3,1},
|
||||
{1,3,0,2}, {0,3,1,2}, {1,3,2,0}, {2,0,1,3},
|
||||
{0,1,3,2}, {3,1,0,2}, {2,1,0,3}, {1,2,3,0},
|
||||
{2,1,3,0}, {3,0,2,1}, {3,2,0,1}, {3,2,1,0}
|
||||
};
|
||||
|
||||
int incr[NDIR][2] = {
|
||||
{0, 1}, {1, 0}, {0, -1}, {-1, 0}
|
||||
};
|
||||
|
||||
static void
|
||||
dig(y, x)
|
||||
int y, x;
|
||||
{
|
||||
int *dp;
|
||||
int *ip;
|
||||
int ny, nx;
|
||||
int *endp;
|
||||
|
||||
Maze[y][x] = SPACE; /* Clear this spot */
|
||||
dp = dirs[rand_num(NPERM)];
|
||||
endp = &dp[NDIR];
|
||||
while (dp < endp) {
|
||||
ip = &incr[*dp++][0];
|
||||
ny = y + *ip++;
|
||||
nx = x + *ip;
|
||||
if (candig(ny, nx))
|
||||
dig(ny, nx);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* candig:
|
||||
* Is it legal to clear this spot?
|
||||
*/
|
||||
static int
|
||||
candig(y, x)
|
||||
int y, x;
|
||||
{
|
||||
int i;
|
||||
|
||||
if (ODD(x) && ODD(y))
|
||||
return FALSE; /* can't touch ODD spots */
|
||||
|
||||
if (y < UBOUND || y >= DBOUND)
|
||||
return FALSE; /* Beyond vertical bounds, NO */
|
||||
if (x < LBOUND || x >= RBOUND)
|
||||
return FALSE; /* Beyond horizontal bounds, NO */
|
||||
|
||||
if (ISCLEAR(y, x))
|
||||
return FALSE; /* Already clear, NO */
|
||||
|
||||
i = ISCLEAR(y, x + 1);
|
||||
i += ISCLEAR(y, x - 1);
|
||||
if (i > 1)
|
||||
return FALSE; /* Introduces cycle, NO */
|
||||
i += ISCLEAR(y + 1, x);
|
||||
if (i > 1)
|
||||
return FALSE; /* Introduces cycle, NO */
|
||||
i += ISCLEAR(y - 1, x);
|
||||
if (i > 1)
|
||||
return FALSE; /* Introduces cycle, NO */
|
||||
|
||||
return TRUE; /* OK */
|
||||
}
|
||||
|
||||
void
|
||||
dig_maze(x, y)
|
||||
int x, y;
|
||||
{
|
||||
int tx, ty;
|
||||
int i, j;
|
||||
int order[4];
|
||||
#define MNORTH 0x1
|
||||
#define MSOUTH 0x2
|
||||
#define MEAST 0x4
|
||||
#define MWEST 0x8
|
||||
|
||||
tx = ty = 0;
|
||||
Maze[y][x] = SPACE;
|
||||
order[0] = MNORTH;
|
||||
for (i = 1; i < 4; i++) {
|
||||
j = rand_num(i + 1);
|
||||
order[i] = order[j];
|
||||
order[j] = 0x1 << i;
|
||||
}
|
||||
for (i = 0; i < 4; i++) {
|
||||
switch (order[i]) {
|
||||
case MNORTH:
|
||||
tx = x;
|
||||
ty = y - 2;
|
||||
break;
|
||||
case MSOUTH:
|
||||
tx = x;
|
||||
ty = y + 2;
|
||||
break;
|
||||
case MEAST:
|
||||
tx = x + 2;
|
||||
ty = y;
|
||||
break;
|
||||
case MWEST:
|
||||
tx = x - 2;
|
||||
ty = y;
|
||||
break;
|
||||
}
|
||||
if (tx < 0 || ty < 0 || tx >= WIDTH || ty >= HEIGHT)
|
||||
continue;
|
||||
if (Maze[ty][tx] == SPACE)
|
||||
continue;
|
||||
Maze[(y + ty) / 2][(x + tx) / 2] = SPACE;
|
||||
dig_maze(tx, ty);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
remap()
|
||||
{
|
||||
int y, x;
|
||||
char *sp;
|
||||
int stat;
|
||||
|
||||
for (y = 0; y < HEIGHT; y++)
|
||||
for (x = 0; x < WIDTH; x++) {
|
||||
sp = &Maze[y][x];
|
||||
if (*sp == SPACE)
|
||||
continue;
|
||||
stat = 0;
|
||||
if (y - 1 >= 0 && Maze[y - 1][x] != SPACE)
|
||||
stat |= NORTH;
|
||||
if (y + 1 < HEIGHT && Maze[y + 1][x] != SPACE)
|
||||
stat |= SOUTH;
|
||||
if (x + 1 < WIDTH && Maze[y][x + 1] != SPACE)
|
||||
stat |= EAST;
|
||||
if (x - 1 >= 0 && Maze[y][x - 1] != SPACE)
|
||||
stat |= WEST;
|
||||
switch (stat) {
|
||||
case WEST | EAST:
|
||||
case EAST:
|
||||
case WEST:
|
||||
*sp = WALL1;
|
||||
break;
|
||||
case NORTH | SOUTH:
|
||||
case NORTH:
|
||||
case SOUTH:
|
||||
*sp = WALL2;
|
||||
break;
|
||||
case 0:
|
||||
# ifdef RANDOM
|
||||
*sp = DOOR;
|
||||
# endif
|
||||
# ifdef REFLECT
|
||||
*sp = rand_num(2) ? WALL4 : WALL5;
|
||||
# endif
|
||||
break;
|
||||
default:
|
||||
*sp = WALL3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
memcpy(Orig_maze, Maze, sizeof Maze);
|
||||
}
|
||||
41
hunt/huntd/pathname.c
Normal file
41
hunt/huntd/pathname.c
Normal file
@@ -0,0 +1,41 @@
|
||||
/* $NetBSD: pathname.c,v 1.2 1997/10/10 16:33:49 lukem Exp $ */
|
||||
/*
|
||||
* Hunt
|
||||
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
* San Francisco, California
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: pathname.c,v 1.2 1997/10/10 16:33:49 lukem Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
* There is no particular significance to the numbers assigned
|
||||
* to Test_port. They're just random numbers greater than the
|
||||
* range reserved for privileged sockets.
|
||||
*/
|
||||
|
||||
# include <sys/types.h>
|
||||
|
||||
# ifdef DEBUG
|
||||
|
||||
char *Driver = "/home/socr/a/conrad/games/src/hunt/huntd.dbg";
|
||||
# ifdef INTERNET
|
||||
u_short Test_port = ('h' << 8) | 't';
|
||||
# else
|
||||
char *Sock_name = "/tmp/hunt";
|
||||
char *Stat_name = "/tmp/hunt.stats";
|
||||
# endif
|
||||
|
||||
# else
|
||||
|
||||
const char *Driver = HUNTD;
|
||||
# ifdef INTERNET
|
||||
u_short Test_port = ('h' << 8) | 't';
|
||||
# else
|
||||
char *Sock_name = "/tmp/hunt";
|
||||
char *Stat_name = "/tmp/hunt.stats";
|
||||
# endif
|
||||
|
||||
# endif
|
||||
1144
hunt/huntd/shots.c
Normal file
1144
hunt/huntd/shots.c
Normal file
File diff suppressed because it is too large
Load Diff
82
hunt/huntd/talk_ctl.h
Normal file
82
hunt/huntd/talk_ctl.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/* $NetBSD: talk_ctl.h,v 1.4 1998/01/09 08:03:42 perry Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1983 Regents of the University of California.
|
||||
* All rights reserved. The Berkeley software License Agreement
|
||||
* specifies the terms and conditions for redistribution.
|
||||
*
|
||||
* @(#)talk_ctl.h 5.2 (Berkeley) 3/13/86
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#ifdef TALK_43
|
||||
#include <protocols/talkd.h>
|
||||
#else
|
||||
|
||||
#define NAME_SIZE 9
|
||||
#define TTY_SIZE 16
|
||||
#ifndef MAXHOSTNAMELEN
|
||||
#define MAXHOSTNAMELEN 256
|
||||
#endif
|
||||
|
||||
#define MAX_LIFE 60 /* max time daemon saves invitations */
|
||||
/* RING_WAIT should be 10's of seconds less than MAX_LIFE */
|
||||
#define RING_WAIT 30 /* time to wait before refreshing invitation */
|
||||
|
||||
/* type values */
|
||||
#define LEAVE_INVITE 0
|
||||
#define LOOK_UP 1
|
||||
#define DELETE 2
|
||||
#define ANNOUNCE 3
|
||||
|
||||
/* answer values */
|
||||
#define SUCCESS 0
|
||||
#define NOT_HERE 1
|
||||
#define FAILED 2
|
||||
#define MACHINE_UNKNOWN 3
|
||||
#define PERMISSION_DENIED 4
|
||||
#define UNKNOWN_REQUEST 5
|
||||
|
||||
typedef struct ctl_response {
|
||||
char type;
|
||||
char answer;
|
||||
int id_num;
|
||||
struct sockaddr_in addr;
|
||||
} CTL_RESPONSE;
|
||||
|
||||
typedef struct ctl_msg {
|
||||
char type;
|
||||
char l_name[NAME_SIZE];
|
||||
char r_name[NAME_SIZE];
|
||||
int id_num;
|
||||
int pid;
|
||||
char r_tty[TTY_SIZE];
|
||||
struct sockaddr_in addr;
|
||||
struct sockaddr_in ctl_addr;
|
||||
} CTL_MSG;
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#ifdef LOG
|
||||
#include <syslog.h>
|
||||
#endif
|
||||
|
||||
extern struct sockaddr_in daemon_addr;
|
||||
extern struct sockaddr_in ctl_addr;
|
||||
extern struct sockaddr_in my_addr;
|
||||
extern struct in_addr my_machine_addr;
|
||||
extern struct in_addr his_machine_addr;
|
||||
extern u_short daemon_port;
|
||||
extern int ctl_sockt;
|
||||
extern CTL_MSG msg;
|
||||
|
||||
#ifdef LOG
|
||||
#define p_error(str) syslog(LOG_WARNING, "faketalk %s: %m", str)
|
||||
#else
|
||||
#define p_error(str) warn(str)
|
||||
#endif
|
||||
|
||||
void ctl_transact __P((struct in_addr, CTL_MSG, int, CTL_RESPONSE *));
|
||||
145
hunt/huntd/terminal.c
Normal file
145
hunt/huntd/terminal.c
Normal file
@@ -0,0 +1,145 @@
|
||||
/* $NetBSD: terminal.c,v 1.2 1997/10/10 16:34:05 lukem Exp $ */
|
||||
/*
|
||||
* Hunt
|
||||
* Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold
|
||||
* San Francisco, California
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: terminal.c,v 1.2 1997/10/10 16:34:05 lukem Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#if __STDC__
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
# include "hunt.h"
|
||||
# define TERM_WIDTH 80 /* Assume terminals are 80-char wide */
|
||||
|
||||
/*
|
||||
* cgoto:
|
||||
* Move the cursor to the given position on the given player's
|
||||
* terminal.
|
||||
*/
|
||||
void
|
||||
cgoto(pp, y, x)
|
||||
PLAYER *pp;
|
||||
int y, x;
|
||||
{
|
||||
if (x == pp->p_curx && y == pp->p_cury)
|
||||
return;
|
||||
sendcom(pp, MOVE, y, x);
|
||||
pp->p_cury = y;
|
||||
pp->p_curx = x;
|
||||
}
|
||||
|
||||
/*
|
||||
* outch:
|
||||
* Put out a single character.
|
||||
*/
|
||||
void
|
||||
outch(pp, ch)
|
||||
PLAYER *pp;
|
||||
char ch;
|
||||
{
|
||||
if (++pp->p_curx >= TERM_WIDTH) {
|
||||
pp->p_curx = 0;
|
||||
pp->p_cury++;
|
||||
}
|
||||
(void) putc(ch, pp->p_output);
|
||||
}
|
||||
|
||||
/*
|
||||
* outstr:
|
||||
* Put out a string of the given length.
|
||||
*/
|
||||
void
|
||||
outstr(pp, str, len)
|
||||
PLAYER *pp;
|
||||
const char *str;
|
||||
int len;
|
||||
{
|
||||
pp->p_curx += len;
|
||||
pp->p_cury += (pp->p_curx / TERM_WIDTH);
|
||||
pp->p_curx %= TERM_WIDTH;
|
||||
while (len--)
|
||||
(void) putc(*str++, pp->p_output);
|
||||
}
|
||||
|
||||
/*
|
||||
* clrscr:
|
||||
* Clear the screen, and reset the current position on the screen.
|
||||
*/
|
||||
void
|
||||
clrscr(pp)
|
||||
PLAYER *pp;
|
||||
{
|
||||
sendcom(pp, CLEAR);
|
||||
pp->p_cury = 0;
|
||||
pp->p_curx = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ce:
|
||||
* Clear to the end of the line
|
||||
*/
|
||||
void
|
||||
ce(pp)
|
||||
PLAYER *pp;
|
||||
{
|
||||
sendcom(pp, CLRTOEOL);
|
||||
}
|
||||
|
||||
#if 0 /* XXX lukem*/
|
||||
/*
|
||||
* ref;
|
||||
* Refresh the screen
|
||||
*/
|
||||
void
|
||||
ref(pp)
|
||||
PLAYER *pp;
|
||||
{
|
||||
sendcom(pp, REFRESH);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* sendcom:
|
||||
* Send a command to the given user
|
||||
*/
|
||||
void
|
||||
#if __STDC__
|
||||
sendcom(PLAYER *pp, int command, ...)
|
||||
#else
|
||||
sendcom(pp, command, va_alist)
|
||||
PLAYER *pp;
|
||||
int command;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list ap;
|
||||
int arg1, arg2;
|
||||
#if __STDC__
|
||||
va_start(ap, command);
|
||||
#else
|
||||
va_start(ap);
|
||||
#endif
|
||||
(void) putc(command, pp->p_output);
|
||||
switch (command & 0377) {
|
||||
case MOVE:
|
||||
arg1 = va_arg(ap, int);
|
||||
arg2 = va_arg(ap, int);
|
||||
(void) putc(arg1, pp->p_output);
|
||||
(void) putc(arg2, pp->p_output);
|
||||
break;
|
||||
case ADDCH:
|
||||
case READY:
|
||||
arg1 = va_arg(ap, int);
|
||||
(void) putc(arg1, pp->p_output);
|
||||
break;
|
||||
}
|
||||
|
||||
va_end(ap); /* No return needed for void functions. */
|
||||
}
|
||||
Reference in New Issue
Block a user