Import Rogue 5.4 from the Roguelike Restoration Project (r1490)
This commit is contained in:
parent
8d570c89a5
commit
3741c4867d
61 changed files with 32413 additions and 0 deletions
3
rogue5/.svnignore
Normal file
3
rogue5/.svnignore
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
config.status
|
||||||
|
config.log
|
||||||
|
rogue.scr
|
||||||
93
rogue5/LICENSE.TXT
Normal file
93
rogue5/LICENSE.TXT
Normal file
|
|
@ -0,0 +1,93 @@
|
||||||
|
Rogue: Exploring the Dungeons of Doom
|
||||||
|
Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
3. Neither the name(s) of the author(s) nor the names of other contributors
|
||||||
|
may be used to endorse or promote products derived from this software
|
||||||
|
without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGE.
|
||||||
|
|
||||||
|
===========================================================================
|
||||||
|
|
||||||
|
Portions of this software (state.c, mdport.c) are based on the work
|
||||||
|
of Nicholas J. Kisseberth. Used under license:
|
||||||
|
|
||||||
|
Copyright (C) 1999, 2000, 2005 Nicholas J. Kisseberth
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
3. Neither the name(s) of the author(s) nor the names of other contributors
|
||||||
|
may be used to endorse or promote products derived from this software
|
||||||
|
without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGE.
|
||||||
|
|
||||||
|
===========================================================================
|
||||||
|
|
||||||
|
Portions of this software (xcrypt.c) are based on the work
|
||||||
|
of David Burren. Used under license:
|
||||||
|
|
||||||
|
FreeSec: libcrypt
|
||||||
|
|
||||||
|
Copyright (C) 1994 David Burren
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
3. Neither the name(s) of the author(s) nor the names of other contributors
|
||||||
|
may be used to endorse or promote products derived from this software
|
||||||
|
without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
|
||||||
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGE.
|
||||||
220
rogue5/Makefile.in
Normal file
220
rogue5/Makefile.in
Normal file
|
|
@ -0,0 +1,220 @@
|
||||||
|
###############################################################################
|
||||||
|
#
|
||||||
|
# Makefile for rogue
|
||||||
|
#
|
||||||
|
# Rogue: Exploring the Dungeons of Doom
|
||||||
|
# Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
#
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Site configuration occurs beneath this comment
|
||||||
|
# Typically ./configure (autoconf tools) configures this section
|
||||||
|
# This section could be manually configured if autoconf/configure fails
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
DISTNAME=@PACKAGE_TARNAME@@PACKAGE_VERSION@
|
||||||
|
PACKAGE_TARNAME = @PACKAGE_TARNAME@-@PACKAGE_VERSION@
|
||||||
|
PROGRAM=@PROGRAM@
|
||||||
|
|
||||||
|
O=o
|
||||||
|
|
||||||
|
#CC=gcc
|
||||||
|
CC = @CC@
|
||||||
|
|
||||||
|
#CFLAGS=-O2
|
||||||
|
CFLAGS= @CFLAGS@
|
||||||
|
|
||||||
|
#LIBS=-lcurses
|
||||||
|
LIBS = @LIBS@
|
||||||
|
|
||||||
|
#RM=rm -f
|
||||||
|
RM = rm -f
|
||||||
|
|
||||||
|
#GROFF=groff
|
||||||
|
GROFF = @GROFF@
|
||||||
|
|
||||||
|
#NROFF=nroff
|
||||||
|
NROFF = @NROFF@
|
||||||
|
|
||||||
|
#TBL=tbl
|
||||||
|
TBL = @TBL@
|
||||||
|
|
||||||
|
#COLCRT=colcrt
|
||||||
|
COLCRT = @COLCRT@
|
||||||
|
|
||||||
|
#SED=sed
|
||||||
|
SED = @SED@
|
||||||
|
|
||||||
|
#SCOREFILE=rogue54.scr
|
||||||
|
SCOREFILE = @SCOREFILE@
|
||||||
|
|
||||||
|
#LOCKFILE=rogue54.lck
|
||||||
|
LOCKFILE = @LOCKFILE@
|
||||||
|
|
||||||
|
#GROUPOWNER=games
|
||||||
|
GROUPOWNER = @GROUPOWNER@
|
||||||
|
|
||||||
|
#CPPFLAGS=-DHAVE_CONFIG_H
|
||||||
|
CPPFLAGS =@DEFS@ @CPPFLAGS@
|
||||||
|
|
||||||
|
#DISTFILE = $(PROGRAM)
|
||||||
|
DISTFILE = $(DISTNAME)-@TARGET@
|
||||||
|
|
||||||
|
INSTALL=./install-sh
|
||||||
|
|
||||||
|
#INSTGROUP=-g games
|
||||||
|
INSTGROUP=
|
||||||
|
#INSTOWNER=-u root
|
||||||
|
INSTOWNER=
|
||||||
|
|
||||||
|
CHGRP=chgrp
|
||||||
|
|
||||||
|
MKDIR=mkdir
|
||||||
|
|
||||||
|
TOUCH=touch
|
||||||
|
|
||||||
|
RMDIR=rmdir
|
||||||
|
|
||||||
|
CHMOD=chmod
|
||||||
|
|
||||||
|
DESTDIR=
|
||||||
|
|
||||||
|
prefix=@prefix@
|
||||||
|
exec_prefix=@exec_prefix@
|
||||||
|
datarootdir=@datarootdir@
|
||||||
|
datadir=@datadir@
|
||||||
|
bindir=@bindir@
|
||||||
|
mandir=@mandir@
|
||||||
|
docdir=@docdir@
|
||||||
|
man6dir = $(mandir)/man6
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Site configuration occurs above this comment
|
||||||
|
# It should not be necessary to change anything below this comment
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
HDRS = rogue.h extern.h score.h
|
||||||
|
OBJS1 = vers.$(O) extern.$(O) armor.$(O) chase.$(O) command.$(O) \
|
||||||
|
daemon.$(O) daemons.$(O) fight.$(O) init.$(O) io.$(O) list.$(O) \
|
||||||
|
mach_dep.$(O) main.$(O) mdport.$(O) misc.$(O) monsters.$(O) \
|
||||||
|
move.$(O) new_level.$(O)
|
||||||
|
OBJS2 = options.$(O) pack.$(O) passages.$(O) potions.$(O) rings.$(O) \
|
||||||
|
rip.$(O) rooms.$(O) save.$(O) scrolls.$(O) state.$(O) sticks.$(O) \
|
||||||
|
things.$(O) weapons.$(O) wizard.$(O) xcrypt.$(O)
|
||||||
|
OBJS = $(OBJS1) $(OBJS2)
|
||||||
|
CFILES = vers.c extern.c armor.c chase.c command.c daemon.c \
|
||||||
|
daemons.c fight.c init.c io.c list.c mach_dep.c \
|
||||||
|
main.c mdport.c misc.c monsters.c move.c new_level.c \
|
||||||
|
options.c pack.c passages.c potions.c rings.c rip.c \
|
||||||
|
rooms.c save.c scrolls.c state.c sticks.c things.c \
|
||||||
|
weapons.c wizard.c xcrypt.c
|
||||||
|
MISC_C = findpw.c scedit.c scmisc.c
|
||||||
|
DOCSRC = rogue.me.in rogue.6.in rogue.doc.in rogue.html.in rogue.cat.in
|
||||||
|
DOCS = $(PROGRAM).doc $(PROGRAM).html $(PROGRAM).cat $(PROGRAM).me \
|
||||||
|
$(PROGRAM).6
|
||||||
|
AFILES = configure Makefile.in configure.ac config.h.in config.sub config.guess \
|
||||||
|
install-sh rogue.6.in rogue.me.in rogue.html.in rogue.doc.in rogue.cat.in
|
||||||
|
MISC = Makefile.std LICENSE.TXT rogue54.sln rogue54.vcproj rogue.spec \
|
||||||
|
rogue.png rogue.desktop
|
||||||
|
|
||||||
|
.SUFFIXES: .obj
|
||||||
|
|
||||||
|
.c.obj:
|
||||||
|
$(CC) $(CFLAGS) $(CPPFLAGS) /c $*.c
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CC) $(CFLAGS) $(CPPFLAGS) -c $*.c
|
||||||
|
|
||||||
|
$(PROGRAM): $(HDRS) $(OBJS)
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) $(OBJS1)
|
||||||
|
$(RM) $(OBJS2)
|
||||||
|
$(RM) core a.exe a.out a.exe.stackdump $(PROGRAM) $(PROGRAM).exe
|
||||||
|
$(RM) $(PROGRAM).tar $(PROGRAM).tar.gz $(PROGRAM).zip
|
||||||
|
$(RM) $(DISTNAME)/*
|
||||||
|
-rmdir $(DISTNAME)
|
||||||
|
|
||||||
|
maintainer-clean:
|
||||||
|
$(RM) config.h
|
||||||
|
$(RM) Makefile
|
||||||
|
$(RM) config.status
|
||||||
|
$(RM) -r autom4te.cache
|
||||||
|
$(RM) config.log
|
||||||
|
$(RM) $(PROGRAM).scr $(PROGRAM).lck
|
||||||
|
|
||||||
|
stddocs:
|
||||||
|
sed -e 's/@PROGRAM@/rogue/' -e 's/@SCOREFILE@/rogue.scr/' rogue.6.in > rogue.6
|
||||||
|
sed -e 's/@PROGRAM@/rogue/' -e 's/@SCOREFILE@/rogue.scr/' rogue.me.in > rogue.me
|
||||||
|
sed -e 's/@PROGRAM@/rogue/' -e 's/@SCOREFILE@/rogue.scr/' rogue.html.in > rogue,html
|
||||||
|
sed -e 's/@PROGRAM@/rogue/' -e 's/@SCOREFILE@/rogue.scr/' rogue.doc.in > rogue.doc
|
||||||
|
sed -e 's/@PROGRAM@/rogue/' -e 's/@SCOREFILE@/rogue.scr/' rogue.cat.in > rogue.cat
|
||||||
|
|
||||||
|
dist.src:
|
||||||
|
$(MAKE) $(MAKEFILE) clean
|
||||||
|
mkdir $(DISTNAME)
|
||||||
|
cp $(CFILES) $(HDRS) $(MISC) $(AFILES) $(DISTNAME)
|
||||||
|
tar cf $(DISTNAME)-src.tar $(DISTNAME)
|
||||||
|
gzip -f $(DISTNAME)-src.tar
|
||||||
|
rm -fr $(DISTNAME)
|
||||||
|
|
||||||
|
findpw: findpw.c xcrypt.o mdport.o xcrypt.o
|
||||||
|
$(CC) -s -o findpw findpw.c xcrypt.o mdport.o -lcurses
|
||||||
|
|
||||||
|
scedit: scedit.o scmisc.o vers.o mdport.o xcrypt.o
|
||||||
|
$(CC) -s -o scedit vers.o scedit.o scmisc.o mdport.o xcrypt.o -lcurses
|
||||||
|
|
||||||
|
scmisc.o scedit.o:
|
||||||
|
$(CC) -O -c $(SF) $*.c
|
||||||
|
|
||||||
|
$(PROGRAM).doc: rogue.me
|
||||||
|
if test "x$(GROFF)" != "x" -a "x$(SED)" != "x" ; then \
|
||||||
|
$(GROFF) -P-c -t -me -Tascii rogue.me | $(SED) -e 's/.\x08//g' > $(PROGRAM).doc ;\
|
||||||
|
elif test "x$(NROFF)" != "x" -a "x$(TBL)" != "x" -a "x$(COLCRT)" != "x" ; then \
|
||||||
|
tbl rogue.me | $(NROFF) -me | colcrt - > $(PROGRAM).doc ;\
|
||||||
|
fi
|
||||||
|
|
||||||
|
$(PROGRAM).cat: rogue.6
|
||||||
|
if test "x$(GROFF)" != "x" -a "x$(SED)" != "x" ; then \
|
||||||
|
$(GROFF) -Tascii -man rogue.6 | $(SED) -e 's/.\x08//g' > $(PROGRAM).cat ;\
|
||||||
|
elif test "x$(NROFF)" != "x" -a "x$(TBL)" != "x" -a "x$(COLCRT)" != "x" ; then \
|
||||||
|
$(NROFF) -man rogue.6 | $(COLCRT) - > $(PROGRAM).cat ;\
|
||||||
|
fi
|
||||||
|
|
||||||
|
dist: clean $(PROGRAM)
|
||||||
|
tar cf $(DISTFILE).tar $(PROGRAM) LICENSE.TXT $(DOCS)
|
||||||
|
gzip -f $(DISTFILE).tar
|
||||||
|
|
||||||
|
install: $(PROGRAM)
|
||||||
|
-$(TOUCH) test
|
||||||
|
-if test ! -f $(DESTDIR)$(SCOREFILE) ; then $(INSTALL) -m 0664 test $(DESTDIR)$(SCOREFILE) ; fi
|
||||||
|
-$(INSTALL) -m 0755 $(PROGRAM) $(DESTDIR)$(bindir)/$(PROGRAM)
|
||||||
|
-if test "x$(GROUPOWNER)" != "x" ; then \
|
||||||
|
$(CHGRP) $(GROUPOWNER) $(DESTDIR)$(SCOREFILE) ; \
|
||||||
|
$(CHGRP) $(GROUPOWNER) $(DESTDIR)$(bindir)/$(PROGRAM) ; \
|
||||||
|
$(CHMOD) 02755 $(DESTDIR)$(bindir)/$(PROGRAM) ; \
|
||||||
|
$(CHMOD) 0464 $(DESTDIR)$(SCOREFILE) ; \
|
||||||
|
fi
|
||||||
|
-if test -d $(man6dir) ; then $(INSTALL) -m 0644 rogue.6 $(DESTDIR)$(man6dir)/$(PROGRAM).6 ; fi
|
||||||
|
-if test ! -d $(man6dir) ; then $(INSTALL) -m 0644 rogue.6 $(DESTDIR)$(mandir)/$(PROGRAM).6 ; fi
|
||||||
|
-$(INSTALL) -m 0644 rogue.doc $(DESTDIR)$(docdir)/$(PROGRAM).doc
|
||||||
|
-$(INSTALL) -m 0644 rogue.html $(DESTDIR)$(docdir)/$(PROGRAM).html
|
||||||
|
-$(INSTALL) -m 0644 rogue.cat $(DESTDIR)$(docdir)/$(PROGRAM).cat
|
||||||
|
-$(INSTALL) -m 0644 LICENSE.TXT $(DESTDIR)$(docdir)/LICENSE.TXT
|
||||||
|
-$(INSTALL) -m 0644 rogue.me $(DESTDIR)$(docdir)/$(PROGRAM).me
|
||||||
|
-if test ! -f $(DESTDIR)$(LOCKFILE) ; then $(INSTALL) -m 0666 test $(DESTDIR)$(LOCKFILE) ; $(RM) $(DESTDIR)$(LOCKFILE) ; fi
|
||||||
|
-$(RM) test
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
-$(RM) $(DESTDIR)$(bindir)/$(PROGRAM)
|
||||||
|
-$(RM) $(DESTDIR)$(man6dir)/$(PROGRAM).6
|
||||||
|
-$(RM) $(DESTDIR)$(docdir)$(PROGRAM)/$(PROGRAM).doc
|
||||||
|
-$(RM) $(DESTDIR)$(LOCKFILE)
|
||||||
|
-$(RMDIR) $(DESTDIR)$(docdir)$(PROGRAM)
|
||||||
|
|
||||||
|
reinstall: uninstall install
|
||||||
158
rogue5/Makefile.std
Executable file
158
rogue5/Makefile.std
Executable file
|
|
@ -0,0 +1,158 @@
|
||||||
|
#
|
||||||
|
# Makefile for rogue
|
||||||
|
# @(#)Makefile 4.21 (Berkeley) 02/04/99
|
||||||
|
#
|
||||||
|
# Rogue: Exploring the Dungeons of Doom
|
||||||
|
# Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
#
|
||||||
|
|
||||||
|
DISTNAME = rogue5.4.5
|
||||||
|
PROGRAM = rogue54
|
||||||
|
O = o
|
||||||
|
HDRS = rogue.h extern.h score.h
|
||||||
|
OBJS1 = vers.$(O) extern.$(O) armor.$(O) chase.$(O) command.$(O) \
|
||||||
|
daemon.$(O) daemons.$(O) fight.$(O) init.$(O) io.$(O) list.$(O) \
|
||||||
|
mach_dep.$(O) main.$(O) mdport.$(O) misc.$(O) monsters.$(O) \
|
||||||
|
move.$(O) new_level.$(O)
|
||||||
|
OBJS2 = options.$(O) pack.$(O) passages.$(O) potions.$(O) rings.$(O) \
|
||||||
|
rip.$(O) rooms.$(O) save.$(O) scrolls.$(O) state.$(O) sticks.$(O) \
|
||||||
|
things.$(O) weapons.$(O) wizard.$(O) xcrypt.$(O)
|
||||||
|
OBJS = $(OBJS1) $(OBJS2)
|
||||||
|
CFILES = vers.c extern.c armor.c chase.c command.c daemon.c \
|
||||||
|
daemons.c fight.c init.c io.c list.c mach_dep.c \
|
||||||
|
main.c mdport.c misc.c monsters.c move.c new_level.c \
|
||||||
|
options.c pack.c passages.c potions.c rings.c rip.c \
|
||||||
|
rooms.c save.c scrolls.c state.c sticks.c things.c \
|
||||||
|
weapons.c wizard.c xcrypt.c
|
||||||
|
MISC_C = findpw.c scedit.c scmisc.c
|
||||||
|
DOCSRC = rogue.me.in rogue.6.in rogue.doc.in rogue.html.in rogue.cat.in
|
||||||
|
DOCS = $(PROGRAM).doc $(PROGRAM).html $(PROGRAM).cat $(PROGRAM).me \
|
||||||
|
$(PROGRAM).6
|
||||||
|
AFILES = configure Makefile.in configure.ac config.h.in config.sub config.guess \
|
||||||
|
install-sh rogue.6.in rogue.me.in rogue.html.in rogue.doc.in rogue.cat.in
|
||||||
|
MISC = Makefile.std LICENSE.TXT rogue54.sln rogue54.vcproj rogue.spec \
|
||||||
|
rogue.png rogue.desktop
|
||||||
|
CC = gcc
|
||||||
|
FEATURES = -DALLSCORES -DSCOREFILE=\"$(SCOREFILE)\" -DLOCKFILE=\"$(LOCKFILE)\"
|
||||||
|
CPPFLAGS =
|
||||||
|
CFLAGS = -O3
|
||||||
|
LDFLAGS =
|
||||||
|
LIBS = -lcurses
|
||||||
|
RM = rm -f
|
||||||
|
MAKEFILE = -f Makefile.std
|
||||||
|
SCOREFILE= $(PROGRAM).scr
|
||||||
|
LOCKFILE = $(PROGRAM).lck
|
||||||
|
OUTFLAG = -o
|
||||||
|
EXE =
|
||||||
|
|
||||||
|
.SUFFIXES: .obj
|
||||||
|
|
||||||
|
.c.obj:
|
||||||
|
$(CC) $(CFLAGS) $(CPPFLAGS) $(FEATURES) /c $*.c
|
||||||
|
|
||||||
|
.c.o:
|
||||||
|
$(CC) $(CFLAGS) $(CPPFLAGS) $(FEATURES) -c $*.c
|
||||||
|
|
||||||
|
$(PROGRAM): $(HDRS) $(OBJS) fixdocs
|
||||||
|
$(CC) $(LDFLAGS) $(OBJS) $(LIBS) $(OUTFLAG)$@$(EXE)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) $(OBJS1)
|
||||||
|
$(RM) $(OBJS2)
|
||||||
|
$(RM) core a.exe a.out a.exe.stackdump $(PROGRAM) $(PROGRAM).exe $(PROGRAM).lck
|
||||||
|
$(RM) $(PROGRAM).tar $(PROGRAM).tar.gz $(PROGRAM).zip
|
||||||
|
$(RM) $(DISTNAME)/*
|
||||||
|
|
||||||
|
dist.src:
|
||||||
|
$(MAKE) $(MAKEFILE) clean
|
||||||
|
mkdir $(DISTNAME)
|
||||||
|
cp $(CFILES) $(HDRS) $(MISC) $(AFILES) $(DISTNAME)
|
||||||
|
tar cf $(DISTNAME)-src.tar $(DISTNAME)
|
||||||
|
gzip -f $(DISTNAME)-src.tar
|
||||||
|
rm -fr $(DISTNAME)
|
||||||
|
|
||||||
|
findpw: findpw.c xcrypt.o mdport.o xcrypt.o
|
||||||
|
$(CC) -s -o findpw findpw.c xcrypt.o mdport.o -lcurses
|
||||||
|
|
||||||
|
scedit: scedit.o scmisc.o vers.o mdport.o xcrypt.o
|
||||||
|
$(CC) -s -o scedit vers.o scedit.o scmisc.o mdport.o xcrypt.o -lcurses
|
||||||
|
|
||||||
|
scmisc.o scedit.o:
|
||||||
|
$(CC) -O -c $(SF) $*.c
|
||||||
|
|
||||||
|
doc.nroff:
|
||||||
|
tbl rogue.me | nroff -me | colcrt - > rogue.doc
|
||||||
|
nroff -man rogue.6 | colcrt - > rogue.cat
|
||||||
|
|
||||||
|
doc.groff:
|
||||||
|
groff -P-c -t -me -Tascii rogue.me | sed -e 's/.\x08//g' > rogue.doc
|
||||||
|
groff -man rogue.6 | sed -e 's/.\x08//g' > rogue.cat
|
||||||
|
|
||||||
|
fixdocs:
|
||||||
|
sed -e 's/@PROGRAM@/$(PROGRAM)/' -e 's/@SCOREFILE@/$(SCOREFILE)/' rogue.6.in > $(PROGRAM).6
|
||||||
|
sed -e 's/@PROGRAM@/$(PROGRAM)/' -e 's/@SCOREFILE@/$(SCOREFILE)/' rogue.me.in > $(PROGRAM).me
|
||||||
|
sed -e 's/@PROGRAM@/$(PROGRAM)/' -e 's/@SCOREFILE@/$(SCOREFILE)/' rogue.html.in > $(PROGRAM).html
|
||||||
|
sed -e 's/@PROGRAM@/$(PROGRAM)/' -e 's/@SCOREFILE@/$(SCOREFILE)/' rogue.doc.in > $(PROGRAM).doc
|
||||||
|
sed -e 's/@PROGRAM@/$(PROGRAM)/' -e 's/@SCOREFILE@/$(SCOREFILE)/' rogue.cat.in > $(PROGRAM).cat
|
||||||
|
|
||||||
|
dist.irix:
|
||||||
|
$(MAKE) $(MAKEFILE) clean
|
||||||
|
$(MAKE) $(MAKEFILE) CC=cc $(PROGRAM)
|
||||||
|
tar cf $(DISTNAME)-irix.tar $(PROGRAM) LICENSE.TXT $(DOCS)
|
||||||
|
gzip -f $(DISTNAME)-irix.tar
|
||||||
|
|
||||||
|
dist.aix:
|
||||||
|
$(MAKE) $(MAKEFILE) clean
|
||||||
|
$(MAKE) $(MAKEFILE) CC=xlc CFLAGS="-qmaxmem=16768 -O3 -qstrict" $(PROGRAM)
|
||||||
|
tar cf $(DISTNAME)-aix.tar $(PROGRAM) LICENSE.TXT $(DOCS)
|
||||||
|
gzip -f $(DISTNAME)-aix.tar
|
||||||
|
|
||||||
|
dist.linux:
|
||||||
|
$(MAKE) $(MAKEFILE) clean
|
||||||
|
$(MAKE) $(MAKEFILE) $(PROGRAM)
|
||||||
|
tar cf $(DISTNAME)-linux.tar $(PROGRAM) LICENSE.TXT $(DOCS)
|
||||||
|
gzip -f $(DISTNAME)-linux.tar
|
||||||
|
|
||||||
|
dist.interix:
|
||||||
|
@$(MAKE) $(MAKEFILE) clean
|
||||||
|
@$(MAKE) $(MAKEFILE) CFLAGS="-ansi" $(PROGRAM)
|
||||||
|
tar cf $(DISTNAME)-interix.tar $(PROGRAM) LICENSE.TXT $(DOCS)
|
||||||
|
gzip -f $(DISTNAME)-interix.tar
|
||||||
|
|
||||||
|
dist.cygwin:
|
||||||
|
@$(MAKE) $(MAKEFILE) --no-print-directory clean
|
||||||
|
@$(MAKE) $(MAKEFILE) CPPFLAGS="-I/usr/include/ncurses" --no-print-directory $(PROGRAM)
|
||||||
|
tar cf $(DISTNAME)-cygwin.tar $(PROGRAM).exe LICENSE.TXT $(DOCS)
|
||||||
|
gzip -f $(DISTNAME)-cygwin.tar
|
||||||
|
|
||||||
|
#
|
||||||
|
# Use MINGW32-MAKE to build this target
|
||||||
|
#
|
||||||
|
dist.mingw32:
|
||||||
|
@$(MAKE) $(MAKEFILE) --no-print-directory RM="cmd /c del" clean
|
||||||
|
@$(MAKE) $(MAKEFILE) --no-print-directory CPPFLAGS="-I../pdcurses" LIBS="../pdcurses/pdcurses.a" $(PROGRAM)
|
||||||
|
cmd /c del $(DISTNAME)-mingw32.zip
|
||||||
|
zip $(DISTNAME)-mingw32.zip $(PROGRAM).exe LICENSE.TXT $(DOCS)
|
||||||
|
|
||||||
|
dist.djgpp:
|
||||||
|
@$(MAKE) $(MAKEFILE) --no-print-directory clean
|
||||||
|
@$(MAKE) $(MAKEFILE) --no-print-directory LDFLAGS="-L$(DJDIR)/LIB" \
|
||||||
|
LIBS="-lpdcurses" $(PROGRAM)
|
||||||
|
rm -f $(DISTNAME)-djgpp.zip
|
||||||
|
zip $(DISTNAME)-djgpp.zip $(PROGRAM) LICENSE.TXT $(DOCS)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Use NMAKE to build this targer
|
||||||
|
#
|
||||||
|
|
||||||
|
dist.win32:
|
||||||
|
@$(MAKE) $(MAKEFILE) /NOLOGO O="obj" RM="-del" clean
|
||||||
|
@$(MAKE) $(MAKEFILE) /NOLOGO O="obj" CC="CL" \
|
||||||
|
LIBS="..\pdcurses\pdcurses.lib shell32.lib user32.lib Advapi32.lib" \
|
||||||
|
EXE=".exe" OUTFLAG="/Fe" CPPFLAGS="-I..\pdcurses" \
|
||||||
|
CFLAGS="-nologo -Ox -wd4033 -wd4716" $(PROGRAM)
|
||||||
|
-del $(DISTNAME)-win32.zip
|
||||||
|
zip $(DISTNAME)-win32.zip $(PROGRAM).exe LICENSE.TXT $(DOCS)
|
||||||
122
rogue5/acinclude.m4
Normal file
122
rogue5/acinclude.m4
Normal file
|
|
@ -0,0 +1,122 @@
|
||||||
|
AC_DEFUN([MP_WITH_CURSES],
|
||||||
|
[AC_ARG_WITH(ncurses, [ --with-ncurses Force the use of ncurses over curses],,)
|
||||||
|
mp_save_LIBS="$LIBS"
|
||||||
|
CURSES_LIB=""
|
||||||
|
if test "$with_ncurses" != yes
|
||||||
|
then
|
||||||
|
AC_CACHE_CHECK([for working curses], mp_cv_curses,
|
||||||
|
[LIBS="$LIBS -lcurses"
|
||||||
|
AC_TRY_LINK(
|
||||||
|
[#include <curses.h>],
|
||||||
|
[chtype a; int b=A_STANDOUT, c=KEY_LEFT; initscr(); ],
|
||||||
|
mp_cv_curses=yes, mp_cv_curses=no)])
|
||||||
|
if test "$mp_cv_curses" = yes
|
||||||
|
then
|
||||||
|
AC_DEFINE(HAVE_CURSES_H, 1, [Define to 1 if libcurses is requested])
|
||||||
|
#AC_DEFINE(HAVE_CURSES_H)
|
||||||
|
CURSES_LIB="-lcurses"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if test ! "$CURSES_LIB"
|
||||||
|
then
|
||||||
|
AC_CACHE_CHECK([for working ncurses], mp_cv_ncurses,
|
||||||
|
[LIBS="$mp_save_LIBS -lncurses"
|
||||||
|
AC_TRY_LINK(
|
||||||
|
[#include <ncurses.h>],
|
||||||
|
[chtype a; int b=A_STANDOUT, c=KEY_LEFT; initscr(); ],
|
||||||
|
mp_cv_ncurses=yes, mp_cv_ncurses=no)])
|
||||||
|
if test "$mp_cv_ncurses" = yes
|
||||||
|
then
|
||||||
|
AC_DEFINE(HAVE_NCURSES_H, 1, [Define to 1 if libncurses is requested])
|
||||||
|
CURSES_LIB="-lncurses"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if test ! "$CURSES_LIB"
|
||||||
|
then
|
||||||
|
AC_CACHE_CHECK([for working pdcurses], mp_cv_pdcurses,
|
||||||
|
[LIBS="$mp_save_LIBS -lpdcurses"
|
||||||
|
AC_TRY_LINK(
|
||||||
|
[#include <curses.h>],
|
||||||
|
[chtype a; int b=A_STANDOUT, c=KEY_LEFT; initscr(); ],
|
||||||
|
mp_cv_pdcurses=yes, mp_cv_pdcurses=no)])
|
||||||
|
if test "$mp_cv_pdcurses" = yes
|
||||||
|
then
|
||||||
|
AC_DEFINE(HAVE_CURSES_H, 1, [Define to 1 if libcurses is requested])
|
||||||
|
CURSES_LIB="-lpdcurses"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if test ! "$CURSES_LIB"
|
||||||
|
then
|
||||||
|
AC_CACHE_CHECK([for working pdcur], mp_cv_pdcur,
|
||||||
|
[LIBS="$mp_save_LIBS -lpdcur"
|
||||||
|
AC_TRY_LINK(
|
||||||
|
[#include <curses.h>],
|
||||||
|
[chtype a; int b=A_STANDOUT, c=KEY_LEFT; initscr(); ],
|
||||||
|
mp_cv_pdcur=yes, mp_cv_pdcur=no)])
|
||||||
|
if test "$mp_cv_pdcur" = yes
|
||||||
|
then
|
||||||
|
AC_DEFINE(HAVE_CURSES_H, 1, [Define to 1 if libcurses is requested])
|
||||||
|
CURSES_LIB="-lpdcur"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if test ! "$CURSES_LIB"
|
||||||
|
then
|
||||||
|
AC_CACHE_CHECK([for working peer pdcurses], mp_cv_lpdcurses,
|
||||||
|
[LIBS="$mp_save_LIBS ../pdcurses/pdcurses.a"
|
||||||
|
AC_TRY_LINK(
|
||||||
|
[#include "../pdcurses/curses.h"],
|
||||||
|
[chtype a; int b=A_STANDOUT, c=KEY_LEFT; initscr(); ],
|
||||||
|
mp_cv_lpdcurses=yes, mp_cv_lpdcurses=no)])
|
||||||
|
if test "$mp_cv_lpdcurses" = yes
|
||||||
|
then
|
||||||
|
AC_DEFINE(HAVE_CURSES_H, 1, [Define to 1 if libcurses is requested])
|
||||||
|
CURSES_LIB="../pdcurses/pdcurses.a"
|
||||||
|
RF_ADDTO(CPPFLAGS,"-I../pdcurses")
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
AC_CACHE_CHECK([for ESCDELAY variable],
|
||||||
|
[mc_cv_ncurses_escdelay],
|
||||||
|
[AC_TRY_LINK([], [
|
||||||
|
extern int ESCDELAY;
|
||||||
|
ESCDELAY = 0;
|
||||||
|
],
|
||||||
|
[mc_cv_ncurses_escdelay=yes],
|
||||||
|
[mc_cv_ncurses_escdelay=no])
|
||||||
|
])
|
||||||
|
if test "$mc_cv_ncurses_escdelay" = yes; then
|
||||||
|
AC_DEFINE(HAVE_ESCDELAY, 1,
|
||||||
|
[Define if ncurses has ESCDELAY variable])
|
||||||
|
fi
|
||||||
|
if test ! "$CURSES_LIB" ; then
|
||||||
|
LIBS="$mp_save_LIBS"
|
||||||
|
fi
|
||||||
|
])dnl
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl RF_ADDTO(variable, value)
|
||||||
|
dnl
|
||||||
|
dnl Add value to variable
|
||||||
|
dnl
|
||||||
|
AC_DEFUN([RF_ADDTO],[
|
||||||
|
if test "x$$1" = "x"; then
|
||||||
|
test "x$silent" != "xyes" && echo " setting $1 to \"$2\""
|
||||||
|
$1="$2"
|
||||||
|
else
|
||||||
|
apr_addto_bugger="$2"
|
||||||
|
for i in $apr_addto_bugger; do
|
||||||
|
apr_addto_duplicate="0"
|
||||||
|
for j in $$1; do
|
||||||
|
if test "x$i" = "x$j"; then
|
||||||
|
apr_addto_duplicate="1"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if test $apr_addto_duplicate = "0"; then
|
||||||
|
test "x$silent" != "xyes" && echo " adding \"$i\" to $1"
|
||||||
|
$1="$$1 $i"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
])dnl
|
||||||
|
|
||||||
|
|
||||||
14
rogue5/aclocal.m4
vendored
Normal file
14
rogue5/aclocal.m4
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
# generated automatically by aclocal 1.9.6 -*- Autoconf -*-
|
||||||
|
|
||||||
|
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||||
|
# 2005 Free Software Foundation, Inc.
|
||||||
|
# This file is free software; the Free Software Foundation
|
||||||
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
# with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||||
|
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
# PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
m4_include([acinclude.m4])
|
||||||
89
rogue5/armor.c
Normal file
89
rogue5/armor.c
Normal file
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* This file contains misc functions for dealing with armor
|
||||||
|
* @(#)armor.c 4.14 (Berkeley) 02/05/99
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <curses.h>
|
||||||
|
#include "rogue.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* wear:
|
||||||
|
* The player wants to wear something, so let him/her put it on.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
wear(void)
|
||||||
|
{
|
||||||
|
THING *obj;
|
||||||
|
char *sp;
|
||||||
|
|
||||||
|
if ((obj = get_item("wear", ARMOR)) == NULL)
|
||||||
|
return;
|
||||||
|
if (cur_armor != NULL)
|
||||||
|
{
|
||||||
|
addmsg("you are already wearing some");
|
||||||
|
if (!terse)
|
||||||
|
addmsg(". You'll have to take it off first");
|
||||||
|
endmsg();
|
||||||
|
after = FALSE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (obj->o_type != ARMOR)
|
||||||
|
{
|
||||||
|
msg("you can't wear that");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
waste_time();
|
||||||
|
obj->o_flags |= ISKNOW;
|
||||||
|
sp = inv_name(obj, TRUE);
|
||||||
|
cur_armor = obj;
|
||||||
|
if (!terse)
|
||||||
|
addmsg("you are now ");
|
||||||
|
msg("wearing %s", sp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* take_off:
|
||||||
|
* Get the armor off of the players back
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
take_off(void)
|
||||||
|
{
|
||||||
|
THING *obj;
|
||||||
|
|
||||||
|
if ((obj = cur_armor) == NULL)
|
||||||
|
{
|
||||||
|
after = FALSE;
|
||||||
|
if (terse)
|
||||||
|
msg("not wearing armor");
|
||||||
|
else
|
||||||
|
msg("you aren't wearing any armor");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!dropcheck(cur_armor))
|
||||||
|
return;
|
||||||
|
cur_armor = NULL;
|
||||||
|
if (terse)
|
||||||
|
addmsg("was");
|
||||||
|
else
|
||||||
|
addmsg("you used to be");
|
||||||
|
msg(" wearing %c) %s", obj->o_packch, inv_name(obj, TRUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* waste_time:
|
||||||
|
* Do nothing but let other things happen
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
waste_time(void)
|
||||||
|
{
|
||||||
|
do_daemons(BEFORE);
|
||||||
|
do_fuses(BEFORE);
|
||||||
|
do_daemons(AFTER);
|
||||||
|
do_fuses(AFTER);
|
||||||
|
}
|
||||||
542
rogue5/chase.c
Normal file
542
rogue5/chase.c
Normal file
|
|
@ -0,0 +1,542 @@
|
||||||
|
/*
|
||||||
|
* Code for one creature to chase another
|
||||||
|
*
|
||||||
|
* @(#)chase.c 4.57 (Berkeley) 02/05/99
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <curses.h>
|
||||||
|
#include "rogue.h"
|
||||||
|
|
||||||
|
#define DRAGONSHOT 5 /* one chance in DRAGONSHOT that a dragon will flame */
|
||||||
|
|
||||||
|
static coord ch_ret; /* Where chasing takes you */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* runners:
|
||||||
|
* Make all the running monsters move.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
runners(void)
|
||||||
|
{
|
||||||
|
THING *tp;
|
||||||
|
THING *next;
|
||||||
|
int wastarget;
|
||||||
|
coord orig_pos;
|
||||||
|
|
||||||
|
for (tp = mlist; tp != NULL; tp = next)
|
||||||
|
{
|
||||||
|
/* remember this in case the monster's "next" is changed */
|
||||||
|
next = next(tp);
|
||||||
|
if (!on(*tp, ISHELD) && on(*tp, ISRUN))
|
||||||
|
{
|
||||||
|
orig_pos = tp->t_pos;
|
||||||
|
wastarget = on(*tp, ISTARGET);
|
||||||
|
if (move_monst(tp) == -1)
|
||||||
|
continue;
|
||||||
|
if (on(*tp, ISFLY) && dist_cp(&hero, &tp->t_pos) >= 3)
|
||||||
|
move_monst(tp);
|
||||||
|
if (wastarget && !ce(orig_pos, tp->t_pos))
|
||||||
|
{
|
||||||
|
tp->t_flags &= ~ISTARGET;
|
||||||
|
to_death = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (has_hit)
|
||||||
|
{
|
||||||
|
endmsg();
|
||||||
|
has_hit = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* move_monst:
|
||||||
|
* Execute a single turn of running for a monster
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
move_monst(THING *tp)
|
||||||
|
{
|
||||||
|
if (!on(*tp, ISSLOW) || tp->t_turn)
|
||||||
|
if (do_chase(tp) == -1)
|
||||||
|
return(-1);
|
||||||
|
if (on(*tp, ISHASTE))
|
||||||
|
if (do_chase(tp) == -1)
|
||||||
|
return(-1);
|
||||||
|
tp->t_turn ^= TRUE;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* relocate:
|
||||||
|
* Make the monster's new location be the specified one, updating
|
||||||
|
* all the relevant state.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
relocate(THING *th, const coord *new_loc)
|
||||||
|
{
|
||||||
|
struct room *oroom;
|
||||||
|
|
||||||
|
if (!ce(*new_loc, th->t_pos))
|
||||||
|
{
|
||||||
|
mvaddch(th->t_pos.y, th->t_pos.x, th->t_oldch);
|
||||||
|
th->t_room = roomin(new_loc);
|
||||||
|
set_oldch(th, new_loc);
|
||||||
|
oroom = th->t_room;
|
||||||
|
moat(th->t_pos.y, th->t_pos.x) = NULL;
|
||||||
|
|
||||||
|
if (oroom != th->t_room)
|
||||||
|
th->t_dest = find_dest(th);
|
||||||
|
th->t_pos = *new_loc;
|
||||||
|
moat(new_loc->y, new_loc->x) = th;
|
||||||
|
}
|
||||||
|
move(new_loc->y, new_loc->x);
|
||||||
|
if (see_monst(th))
|
||||||
|
addch(th->t_disguise);
|
||||||
|
else if (on(player, SEEMONST))
|
||||||
|
{
|
||||||
|
standout();
|
||||||
|
addch(th->t_type);
|
||||||
|
standend();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* do_chase:
|
||||||
|
* Make one thing chase another.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
do_chase(THING *th)
|
||||||
|
{
|
||||||
|
coord *cp;
|
||||||
|
struct room *rer, *ree; /* room of chaser, room of chasee */
|
||||||
|
int mindist = 32767, curdist;
|
||||||
|
int stoprun = FALSE; /* TRUE means we are there */
|
||||||
|
int door;
|
||||||
|
THING *obj;
|
||||||
|
coord this; /* Temporary destination for chaser */
|
||||||
|
|
||||||
|
rer = th->t_room; /* Find room of chaser */
|
||||||
|
if (on(*th, ISGREED) && rer->r_goldval == 0)
|
||||||
|
th->t_dest = &hero; /* If gold has been taken, run after hero */
|
||||||
|
if (th->t_dest == &hero) /* Find room of chasee */
|
||||||
|
ree = proom;
|
||||||
|
else
|
||||||
|
ree = roomin(th->t_dest);
|
||||||
|
/*
|
||||||
|
* We don't count doors as inside rooms for this routine
|
||||||
|
*/
|
||||||
|
door = (chat(th->t_pos.y, th->t_pos.x) == DOOR);
|
||||||
|
/*
|
||||||
|
* If the object of our desire is in a different room,
|
||||||
|
* and we are not in a corridor, run to the door nearest to
|
||||||
|
* our goal.
|
||||||
|
*/
|
||||||
|
over:
|
||||||
|
if (rer != ree)
|
||||||
|
{
|
||||||
|
for (cp = rer->r_exit; cp < &rer->r_exit[rer->r_nexits]; cp++)
|
||||||
|
{
|
||||||
|
curdist = dist_cp(th->t_dest, cp);
|
||||||
|
if (curdist < mindist)
|
||||||
|
{
|
||||||
|
this = *cp;
|
||||||
|
mindist = curdist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (door)
|
||||||
|
{
|
||||||
|
rer = &passages[flat(th->t_pos.y, th->t_pos.x) & F_PNUM];
|
||||||
|
door = FALSE;
|
||||||
|
goto over;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this = *th->t_dest;
|
||||||
|
/*
|
||||||
|
* For dragons check and see if (a) the hero is on a straight
|
||||||
|
* line from it, and (b) that it is within shooting distance,
|
||||||
|
* but outside of striking range.
|
||||||
|
*/
|
||||||
|
if (th->t_type == 'D' && (th->t_pos.y == hero.y || th->t_pos.x == hero.x
|
||||||
|
|| abs(th->t_pos.y - hero.y) == abs(th->t_pos.x - hero.x))
|
||||||
|
&& dist_cp(&th->t_pos, &hero) <= BOLT_LENGTH * BOLT_LENGTH
|
||||||
|
&& !on(*th, ISCANC) && rnd(DRAGONSHOT) == 0)
|
||||||
|
{
|
||||||
|
delta.y = sign(hero.y - th->t_pos.y);
|
||||||
|
delta.x = sign(hero.x - th->t_pos.x);
|
||||||
|
if (has_hit)
|
||||||
|
endmsg();
|
||||||
|
fire_bolt(&th->t_pos, &delta, "flame");
|
||||||
|
running = FALSE;
|
||||||
|
count = 0;
|
||||||
|
quiet = 0;
|
||||||
|
if (to_death && !on(*th, ISTARGET))
|
||||||
|
{
|
||||||
|
to_death = FALSE;
|
||||||
|
kamikaze = FALSE;
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* This now contains what we want to run to this time
|
||||||
|
* so we run to it. If we hit it we either want to fight it
|
||||||
|
* or stop running
|
||||||
|
*/
|
||||||
|
if (!chase(th, &this))
|
||||||
|
{
|
||||||
|
if (ce(this, hero))
|
||||||
|
{
|
||||||
|
return( attack(th) );
|
||||||
|
}
|
||||||
|
else if (ce(this, *th->t_dest))
|
||||||
|
{
|
||||||
|
for (obj = lvl_obj; obj != NULL; obj = next(obj))
|
||||||
|
if (th->t_dest == &obj->o_pos)
|
||||||
|
{
|
||||||
|
detach(lvl_obj, obj);
|
||||||
|
attach(th->t_pack, obj);
|
||||||
|
chat(obj->o_pos.y, obj->o_pos.x) =
|
||||||
|
(th->t_room->r_flags & ISGONE) ? PASSAGE : FLOOR;
|
||||||
|
th->t_dest = find_dest(th);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (th->t_type != 'F')
|
||||||
|
stoprun = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (th->t_type == 'F')
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
relocate(th, &ch_ret);
|
||||||
|
/*
|
||||||
|
* And stop running if need be
|
||||||
|
*/
|
||||||
|
if (stoprun && ce(th->t_pos, *(th->t_dest)))
|
||||||
|
th->t_flags &= ~ISRUN;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* set_oldch:
|
||||||
|
* Set the oldch character for the monster
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
set_oldch(THING *tp, const coord *cp)
|
||||||
|
{
|
||||||
|
int sch;
|
||||||
|
|
||||||
|
if (ce(tp->t_pos, *cp))
|
||||||
|
return;
|
||||||
|
|
||||||
|
sch = tp->t_oldch;
|
||||||
|
tp->t_oldch = CCHAR( mvinch(cp->y,cp->x) );
|
||||||
|
if (!on(player, ISBLIND))
|
||||||
|
{
|
||||||
|
if ((sch == FLOOR || tp->t_oldch == FLOOR) &&
|
||||||
|
(tp->t_room->r_flags & ISDARK))
|
||||||
|
tp->t_oldch = ' ';
|
||||||
|
else if (dist_cp(cp, &hero) <= LAMPDIST && see_floor)
|
||||||
|
tp->t_oldch = chat(cp->y, cp->x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* see_monst:
|
||||||
|
* Return TRUE if the hero can see the monster
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
see_monst(const THING *mp)
|
||||||
|
{
|
||||||
|
int y, x;
|
||||||
|
|
||||||
|
if (on(player, ISBLIND))
|
||||||
|
return FALSE;
|
||||||
|
if (on(*mp, ISINVIS) && !on(player, CANSEE))
|
||||||
|
return FALSE;
|
||||||
|
y = mp->t_pos.y;
|
||||||
|
x = mp->t_pos.x;
|
||||||
|
if (dist(y, x, hero.y, hero.x) < LAMPDIST)
|
||||||
|
{
|
||||||
|
if (y != hero.y && x != hero.x &&
|
||||||
|
!step_ok(chat(y, hero.x)) && !step_ok(chat(hero.y, x)))
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
if (mp->t_room != proom)
|
||||||
|
return FALSE;
|
||||||
|
return (!(mp->t_room->r_flags & ISDARK));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* runto:
|
||||||
|
* Set a monster running after the hero.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
runto(const coord *runner)
|
||||||
|
{
|
||||||
|
THING *tp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we couldn't find him, something is funny
|
||||||
|
*/
|
||||||
|
if ((tp = moat(runner->y, runner->x)) == NULL)
|
||||||
|
{
|
||||||
|
#ifdef MASTER
|
||||||
|
msg("couldn't find monster in runto at (%d,%d)", runner->y, runner->x);
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start the beastie running
|
||||||
|
*/
|
||||||
|
tp->t_flags |= ISRUN;
|
||||||
|
tp->t_flags &= ~ISHELD;
|
||||||
|
tp->t_dest = find_dest(tp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* chase:
|
||||||
|
* Find the spot for the chaser(er) to move closer to the
|
||||||
|
* chasee(ee). Returns TRUE if we want to keep on chasing later
|
||||||
|
* FALSE if we reach the goal.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
chase(THING *tp, const coord *ee)
|
||||||
|
{
|
||||||
|
THING *obj;
|
||||||
|
int x, y;
|
||||||
|
int curdist, thisdist;
|
||||||
|
const coord *er = &tp->t_pos;
|
||||||
|
int ch;
|
||||||
|
int plcnt = 1;
|
||||||
|
coord tryp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the thing is confused, let it move randomly. Invisible
|
||||||
|
* Stalkers are slightly confused all of the time, and bats are
|
||||||
|
* quite confused all the time
|
||||||
|
*/
|
||||||
|
if ((on(*tp, ISHUH) && rnd(5) != 0) || (tp->t_type == 'P' && rnd(5) == 0)
|
||||||
|
|| (tp->t_type == 'B' && rnd(2) == 0))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* get a valid random move
|
||||||
|
*/
|
||||||
|
ch_ret = rndmove(tp);
|
||||||
|
curdist = dist_cp(&ch_ret, ee);
|
||||||
|
/*
|
||||||
|
* Small chance that it will become un-confused
|
||||||
|
*/
|
||||||
|
if (rnd(20) == 0)
|
||||||
|
tp->t_flags &= ~ISHUH;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Otherwise, find the empty spot next to the chaser that is
|
||||||
|
* closest to the chasee.
|
||||||
|
*/
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int ey, ex;
|
||||||
|
/*
|
||||||
|
* This will eventually hold where we move to get closer
|
||||||
|
* If we can't find an empty spot, we stay where we are.
|
||||||
|
*/
|
||||||
|
curdist = dist_cp(er, ee);
|
||||||
|
ch_ret = *er;
|
||||||
|
|
||||||
|
ey = er->y + 1;
|
||||||
|
if (ey >= NUMLINES - 1)
|
||||||
|
ey = NUMLINES - 2;
|
||||||
|
ex = er->x + 1;
|
||||||
|
if (ex >= NUMCOLS)
|
||||||
|
ex = NUMCOLS - 1;
|
||||||
|
|
||||||
|
for (x = er->x - 1; x <= ex; x++)
|
||||||
|
{
|
||||||
|
if (x < 0)
|
||||||
|
continue;
|
||||||
|
tryp.x = x;
|
||||||
|
for (y = er->y - 1; y <= ey; y++)
|
||||||
|
{
|
||||||
|
tryp.y = y;
|
||||||
|
if (!diag_ok(er, &tryp))
|
||||||
|
continue;
|
||||||
|
ch = winat(y, x);
|
||||||
|
if (step_ok(ch))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If it is a scroll, it might be a scare monster scroll
|
||||||
|
* so we need to look it up to see what type it is.
|
||||||
|
*/
|
||||||
|
if (ch == SCROLL)
|
||||||
|
{
|
||||||
|
for (obj = lvl_obj; obj != NULL; obj = next(obj))
|
||||||
|
{
|
||||||
|
if (y == obj->o_pos.y && x == obj->o_pos.x)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (obj != NULL && obj->o_which == S_SCARE)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* It can also be a Xeroc, which we shouldn't step on
|
||||||
|
*/
|
||||||
|
if ((obj = moat(y, x)) != NULL && obj->t_type == 'X')
|
||||||
|
continue;
|
||||||
|
/*
|
||||||
|
* If we didn't find any scrolls at this place or it
|
||||||
|
* wasn't a scare scroll, then this place counts
|
||||||
|
*/
|
||||||
|
thisdist = dist(y, x, ee->y, ee->x);
|
||||||
|
if (thisdist < curdist)
|
||||||
|
{
|
||||||
|
plcnt = 1;
|
||||||
|
ch_ret = tryp;
|
||||||
|
curdist = thisdist;
|
||||||
|
}
|
||||||
|
else if (thisdist == curdist && rnd(++plcnt) == 0)
|
||||||
|
{
|
||||||
|
ch_ret = tryp;
|
||||||
|
curdist = thisdist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (curdist != 0 && !ce(ch_ret, hero));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* roomin:
|
||||||
|
* Find what room some coordinates are in. NULL means they aren't
|
||||||
|
* in any room.
|
||||||
|
*/
|
||||||
|
struct room *
|
||||||
|
roomin(const coord *cp)
|
||||||
|
{
|
||||||
|
struct room *rp;
|
||||||
|
int *fp;
|
||||||
|
|
||||||
|
fp = &flat(cp->y, cp->x);
|
||||||
|
if (*fp & F_PASS)
|
||||||
|
return &passages[*fp & F_PNUM];
|
||||||
|
|
||||||
|
for (rp = rooms; rp < &rooms[MAXROOMS]; rp++)
|
||||||
|
if (cp->x <= rp->r_pos.x + rp->r_max.x && rp->r_pos.x <= cp->x
|
||||||
|
&& cp->y <= rp->r_pos.y + rp->r_max.y && rp->r_pos.y <= cp->y)
|
||||||
|
return rp;
|
||||||
|
|
||||||
|
msg("in some bizarre place (%d, %d)", unc(*cp));
|
||||||
|
#ifdef MASTER
|
||||||
|
abort();
|
||||||
|
return NULL;
|
||||||
|
#else
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* diag_ok:
|
||||||
|
* Check to see if the move is legal if it is diagonal
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
diag_ok(const coord *sp, const coord *ep)
|
||||||
|
{
|
||||||
|
if (ep->x < 0 || ep->x >= NUMCOLS || ep->y <= 0 || ep->y >= NUMLINES - 1)
|
||||||
|
return FALSE;
|
||||||
|
if (ep->x == sp->x || ep->y == sp->y)
|
||||||
|
return TRUE;
|
||||||
|
return (step_ok(chat(ep->y, sp->x)) && step_ok(chat(sp->y, ep->x)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cansee:
|
||||||
|
* Returns true if the hero can see a certain coordinate.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
cansee(int y, int x)
|
||||||
|
{
|
||||||
|
struct room *rer;
|
||||||
|
coord tp;
|
||||||
|
|
||||||
|
if (on(player, ISBLIND))
|
||||||
|
return FALSE;
|
||||||
|
if (dist(y, x, hero.y, hero.x) < LAMPDIST)
|
||||||
|
{
|
||||||
|
if (flat(y, x) & F_PASS)
|
||||||
|
if (y != hero.y && x != hero.x &&
|
||||||
|
!step_ok(chat(y, hero.x)) && !step_ok(chat(hero.y, x)))
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* We can only see if the hero in the same room as
|
||||||
|
* the coordinate and the room is lit or if it is close.
|
||||||
|
*/
|
||||||
|
tp.y = y;
|
||||||
|
tp.x = x;
|
||||||
|
return ((rer = roomin(&tp)) == proom && !(rer->r_flags & ISDARK));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* find_dest:
|
||||||
|
* find the proper destination for the monster
|
||||||
|
*/
|
||||||
|
const coord *
|
||||||
|
find_dest(const THING *tp)
|
||||||
|
{
|
||||||
|
THING *obj;
|
||||||
|
int prob;
|
||||||
|
|
||||||
|
if ((prob = monsters[tp->t_type - 'A'].m_carry) <= 0 || tp->t_room == proom
|
||||||
|
|| see_monst(tp))
|
||||||
|
return &hero;
|
||||||
|
for (obj = lvl_obj; obj != NULL; obj = next(obj))
|
||||||
|
{
|
||||||
|
if (obj->o_type == SCROLL && obj->o_which == S_SCARE)
|
||||||
|
continue;
|
||||||
|
if (roomin(&obj->o_pos) == tp->t_room && rnd(100) < prob)
|
||||||
|
{
|
||||||
|
for (tp = mlist; tp != NULL; tp = next(tp))
|
||||||
|
if (tp->t_dest == &obj->o_pos)
|
||||||
|
break;
|
||||||
|
if (tp == NULL)
|
||||||
|
return &obj->o_pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &hero;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dist:
|
||||||
|
* Calculate the "distance" between to points. Actually,
|
||||||
|
* this calculates d^2, not d, but that's good enough for
|
||||||
|
* our purposes, since it's only used comparitively.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
dist(int y1, int x1, int y2, int x2)
|
||||||
|
{
|
||||||
|
return ((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dist_cp:
|
||||||
|
* Call dist() with appropriate arguments for coord pointers
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
dist_cp(const coord *c1, const coord *c2)
|
||||||
|
{
|
||||||
|
return dist(c1->y, c1->x, c2->y, c2->x);
|
||||||
|
}
|
||||||
827
rogue5/command.c
Normal file
827
rogue5/command.c
Normal file
|
|
@ -0,0 +1,827 @@
|
||||||
|
/*
|
||||||
|
* Read and execute the user commands
|
||||||
|
*
|
||||||
|
* @(#)command.c 4.73 (Berkeley) 08/06/83
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <curses.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "rogue.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* command:
|
||||||
|
* Process the user commands
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
command(void)
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
int ntimes = 1; /* Number of player moves */
|
||||||
|
int *fp;
|
||||||
|
THING *mp;
|
||||||
|
static int countch, direction, newcount = FALSE;
|
||||||
|
|
||||||
|
if (on(player, ISHASTE))
|
||||||
|
ntimes++;
|
||||||
|
/*
|
||||||
|
* Let the daemons start up
|
||||||
|
*/
|
||||||
|
do_daemons(BEFORE);
|
||||||
|
do_fuses(BEFORE);
|
||||||
|
while (ntimes--)
|
||||||
|
{
|
||||||
|
again = FALSE;
|
||||||
|
if (has_hit)
|
||||||
|
{
|
||||||
|
endmsg();
|
||||||
|
has_hit = FALSE;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* these are illegal things for the player to be, so if any are
|
||||||
|
* set, someone's been poking in memeory
|
||||||
|
*/
|
||||||
|
if (on(player, ISSLOW|ISGREED|ISINVIS|ISREGEN|ISTARGET))
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
look(TRUE);
|
||||||
|
if (!running)
|
||||||
|
door_stop = FALSE;
|
||||||
|
status();
|
||||||
|
lastscore = purse;
|
||||||
|
move(hero.y, hero.x);
|
||||||
|
if (!((running || count) && jump))
|
||||||
|
refresh(); /* Draw screen */
|
||||||
|
take = 0;
|
||||||
|
after = TRUE;
|
||||||
|
/*
|
||||||
|
* Read command or continue run
|
||||||
|
*/
|
||||||
|
#ifdef MASTER
|
||||||
|
if (wizard)
|
||||||
|
noscore = TRUE;
|
||||||
|
#endif
|
||||||
|
if (!no_command)
|
||||||
|
{
|
||||||
|
if (running || to_death)
|
||||||
|
ch = runch;
|
||||||
|
else if (count)
|
||||||
|
ch = countch;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ch = readchar();
|
||||||
|
move_on = FALSE;
|
||||||
|
if (mpos != 0) /* Erase message if its there */
|
||||||
|
{
|
||||||
|
if (ch != '.')
|
||||||
|
msg("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ch = '.';
|
||||||
|
if (no_command)
|
||||||
|
{
|
||||||
|
if (--no_command == 0)
|
||||||
|
{
|
||||||
|
player.t_flags |= ISRUN;
|
||||||
|
msg("you can move again");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* check for prefixes
|
||||||
|
*/
|
||||||
|
newcount = FALSE;
|
||||||
|
if (isdigit(ch))
|
||||||
|
{
|
||||||
|
count = 0;
|
||||||
|
newcount = TRUE;
|
||||||
|
while (isdigit(ch))
|
||||||
|
{
|
||||||
|
count = count * 10 + (ch - '0');
|
||||||
|
if (count > 255)
|
||||||
|
count = 255;
|
||||||
|
ch = readchar();
|
||||||
|
}
|
||||||
|
countch = ch;
|
||||||
|
/*
|
||||||
|
* turn off count for commands which don't make sense
|
||||||
|
* to repeat
|
||||||
|
*/
|
||||||
|
switch (ch)
|
||||||
|
{
|
||||||
|
case CTRL('B'): case CTRL('H'): case CTRL('J'):
|
||||||
|
case CTRL('K'): case CTRL('L'): case CTRL('N'):
|
||||||
|
case CTRL('U'): case CTRL('Y'):
|
||||||
|
case '.': case 'a': case 'b': case 'h': case 'j':
|
||||||
|
case 'k': case 'l': case 'm': case 'n': case 'q':
|
||||||
|
case 'r': case 's': case 't': case 'u': case 'y':
|
||||||
|
case 'z': case 'B': case 'C': case 'H': case 'I':
|
||||||
|
case 'J': case 'K': case 'L': case 'N': case 'U':
|
||||||
|
case 'Y':
|
||||||
|
#ifdef MASTER
|
||||||
|
case CTRL('D'): case CTRL('A'):
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* execute a command
|
||||||
|
*/
|
||||||
|
if (count && !running)
|
||||||
|
count--;
|
||||||
|
if (ch != 'a' && ch != ESCAPE && !(running || count || to_death))
|
||||||
|
{
|
||||||
|
l_last_comm = last_comm;
|
||||||
|
l_last_dir = last_dir;
|
||||||
|
l_last_pick = last_pick;
|
||||||
|
last_comm = ch;
|
||||||
|
last_dir = '\0';
|
||||||
|
last_pick = NULL;
|
||||||
|
}
|
||||||
|
over:
|
||||||
|
switch (ch)
|
||||||
|
{
|
||||||
|
case ',': {
|
||||||
|
THING *obj = NULL;
|
||||||
|
int found = 0;
|
||||||
|
for (obj = lvl_obj; obj != NULL; obj = next(obj))
|
||||||
|
{
|
||||||
|
if (obj->o_pos.y == hero.y && obj->o_pos.x == hero.x)
|
||||||
|
{
|
||||||
|
found=1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
if (levit_check())
|
||||||
|
;
|
||||||
|
else
|
||||||
|
pick_up(obj->o_type);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!terse)
|
||||||
|
addmsg("there is ");
|
||||||
|
addmsg("nothing here");
|
||||||
|
if (!terse)
|
||||||
|
addmsg(" to pick up");
|
||||||
|
endmsg();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
when '!': shell();
|
||||||
|
when 'h': do_move(0, -1);
|
||||||
|
when 'j': do_move(1, 0);
|
||||||
|
when 'k': do_move(-1, 0);
|
||||||
|
when 'l': do_move(0, 1);
|
||||||
|
when 'y': do_move(-1, -1);
|
||||||
|
when 'u': do_move(-1, 1);
|
||||||
|
when 'b': do_move(1, -1);
|
||||||
|
when 'n': do_move(1, 1);
|
||||||
|
when 'H': do_run('h');
|
||||||
|
when 'J': do_run('j');
|
||||||
|
when 'K': do_run('k');
|
||||||
|
when 'L': do_run('l');
|
||||||
|
when 'Y': do_run('y');
|
||||||
|
when 'U': do_run('u');
|
||||||
|
when 'B': do_run('b');
|
||||||
|
when 'N': do_run('n');
|
||||||
|
when CTRL('H'): case CTRL('J'): case CTRL('K'): case CTRL('L'):
|
||||||
|
case CTRL('Y'): case CTRL('U'): case CTRL('B'): case CTRL('N'):
|
||||||
|
{
|
||||||
|
if (!on(player, ISBLIND))
|
||||||
|
{
|
||||||
|
door_stop = TRUE;
|
||||||
|
firstmove = TRUE;
|
||||||
|
}
|
||||||
|
if (count && !newcount)
|
||||||
|
ch = direction;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ch += ('A' - CTRL('A'));
|
||||||
|
direction = ch;
|
||||||
|
}
|
||||||
|
goto over;
|
||||||
|
}
|
||||||
|
when 'F':
|
||||||
|
kamikaze = TRUE;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case 'f':
|
||||||
|
if (!get_dir())
|
||||||
|
{
|
||||||
|
after = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
delta.y += hero.y;
|
||||||
|
delta.x += hero.x;
|
||||||
|
if ( ((mp = moat(delta.y, delta.x)) == NULL)
|
||||||
|
|| ((!see_monst(mp)) && !on(player, SEEMONST)))
|
||||||
|
{
|
||||||
|
if (!terse)
|
||||||
|
addmsg("I see ");
|
||||||
|
msg("no monster there");
|
||||||
|
after = FALSE;
|
||||||
|
}
|
||||||
|
else if (diag_ok(&hero, &delta))
|
||||||
|
{
|
||||||
|
to_death = TRUE;
|
||||||
|
max_hit = 0;
|
||||||
|
mp->t_flags |= ISTARGET;
|
||||||
|
runch = ch = dir_ch;
|
||||||
|
goto over;
|
||||||
|
}
|
||||||
|
when 't':
|
||||||
|
if (!get_dir())
|
||||||
|
after = FALSE;
|
||||||
|
else
|
||||||
|
missile(delta.y, delta.x);
|
||||||
|
when 'a':
|
||||||
|
if (last_comm == '\0')
|
||||||
|
{
|
||||||
|
msg("you haven't typed a command yet");
|
||||||
|
after = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ch = last_comm;
|
||||||
|
again = TRUE;
|
||||||
|
goto over;
|
||||||
|
}
|
||||||
|
when 'q': quaff();
|
||||||
|
when 'Q':
|
||||||
|
after = FALSE;
|
||||||
|
q_comm = TRUE;
|
||||||
|
quit(0);
|
||||||
|
q_comm = FALSE;
|
||||||
|
when 'i': after = FALSE; inventory(pack, 0);
|
||||||
|
when 'I': after = FALSE; picky_inven();
|
||||||
|
when 'd': drop();
|
||||||
|
when 'r': read_scroll();
|
||||||
|
when 'e': eat();
|
||||||
|
when 'w': wield();
|
||||||
|
when 'W': wear();
|
||||||
|
when 'T': take_off();
|
||||||
|
when 'P': ring_on();
|
||||||
|
when 'R': ring_off();
|
||||||
|
when 'o': option(); after = FALSE;
|
||||||
|
when 'c': call(); after = FALSE;
|
||||||
|
when '>': after = FALSE; d_level();
|
||||||
|
when '<': after = FALSE; u_level();
|
||||||
|
when '?': after = FALSE; help();
|
||||||
|
when '/': after = FALSE; identify();
|
||||||
|
when 's': search();
|
||||||
|
when 'z':
|
||||||
|
if (get_dir())
|
||||||
|
do_zap();
|
||||||
|
else
|
||||||
|
after = FALSE;
|
||||||
|
when 'D': after = FALSE; discovered();
|
||||||
|
when CTRL('P'): after = FALSE; msg(huh);
|
||||||
|
when CTRL('R'):
|
||||||
|
after = FALSE;
|
||||||
|
clearok(curscr,TRUE);
|
||||||
|
wrefresh(curscr);
|
||||||
|
when 'v':
|
||||||
|
after = FALSE;
|
||||||
|
msg("version %s. (mctesq was here)", release);
|
||||||
|
when 'S':
|
||||||
|
after = FALSE;
|
||||||
|
save_game();
|
||||||
|
when '.': ; /* Rest command */
|
||||||
|
when ' ': after = FALSE; /* "Legal" illegal command */
|
||||||
|
when '^':
|
||||||
|
after = FALSE;
|
||||||
|
if (get_dir()) {
|
||||||
|
delta.y += hero.y;
|
||||||
|
delta.x += hero.x;
|
||||||
|
fp = &flat(delta.y, delta.x);
|
||||||
|
if (!terse)
|
||||||
|
addmsg("You have found ");
|
||||||
|
if (chat(delta.y, delta.x) != TRAP)
|
||||||
|
msg("no trap there");
|
||||||
|
else if (on(player, ISHALU))
|
||||||
|
msg(tr_name[rnd(NTRAPS)]);
|
||||||
|
else {
|
||||||
|
msg(tr_name[*fp & F_TMASK]);
|
||||||
|
*fp |= F_SEEN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef MASTER
|
||||||
|
when '+':
|
||||||
|
after = FALSE;
|
||||||
|
if (wizard)
|
||||||
|
{
|
||||||
|
wizard = FALSE;
|
||||||
|
turn_see(TRUE);
|
||||||
|
msg("not wizard any more");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wizard = passwd();
|
||||||
|
if (wizard)
|
||||||
|
{
|
||||||
|
noscore = TRUE;
|
||||||
|
turn_see(FALSE);
|
||||||
|
msg("you are suddenly as smart as Ken Arnold in dungeon #%d", dnum);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
msg("sorry");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
when ESCAPE: /* Escape */
|
||||||
|
door_stop = FALSE;
|
||||||
|
count = 0;
|
||||||
|
after = FALSE;
|
||||||
|
again = FALSE;
|
||||||
|
when 'm':
|
||||||
|
move_on = TRUE;
|
||||||
|
if (!get_dir())
|
||||||
|
after = FALSE;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ch = dir_ch;
|
||||||
|
countch = dir_ch;
|
||||||
|
goto over;
|
||||||
|
}
|
||||||
|
when ')': current(cur_weapon, "wielding", NULL);
|
||||||
|
when ']': current(cur_armor, "wearing", NULL);
|
||||||
|
when '=':
|
||||||
|
current(cur_ring[LEFT], "wearing",
|
||||||
|
terse ? "(L)" : "on left hand");
|
||||||
|
current(cur_ring[RIGHT], "wearing",
|
||||||
|
terse ? "(R)" : "on right hand");
|
||||||
|
when '@':
|
||||||
|
stat_msg = TRUE;
|
||||||
|
status();
|
||||||
|
stat_msg = FALSE;
|
||||||
|
after = FALSE;
|
||||||
|
otherwise:
|
||||||
|
after = FALSE;
|
||||||
|
#ifdef MASTER
|
||||||
|
if (wizard) switch (ch)
|
||||||
|
{
|
||||||
|
case '|': msg("@ %d,%d", hero.y, hero.x);
|
||||||
|
when 'C': create_obj();
|
||||||
|
when '$': msg("inpack = %d", inpack);
|
||||||
|
when CTRL('G'): inventory(lvl_obj, 0);
|
||||||
|
when CTRL('W'): whatis(FALSE, 0);
|
||||||
|
when CTRL('D'): level++; new_level();
|
||||||
|
when CTRL('A'): level--; new_level();
|
||||||
|
when CTRL('F'): show_map();
|
||||||
|
when CTRL('T'): teleport();
|
||||||
|
when CTRL('E'): msg("food left: %d", food_left);
|
||||||
|
when CTRL('Q'): add_pass();
|
||||||
|
when CTRL('X'): turn_see(on(player, SEEMONST));
|
||||||
|
when '~':
|
||||||
|
{
|
||||||
|
THING *item;
|
||||||
|
|
||||||
|
if ((item = get_item("charge", STICK)) != NULL)
|
||||||
|
item->o_charges = 10000;
|
||||||
|
}
|
||||||
|
when CTRL('I'):
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
THING *obj;
|
||||||
|
|
||||||
|
for (i = 0; i < 9; i++)
|
||||||
|
raise_level();
|
||||||
|
/*
|
||||||
|
* Give him a sword (+1,+1)
|
||||||
|
*/
|
||||||
|
obj = new_item();
|
||||||
|
init_weapon(obj, TWOSWORD);
|
||||||
|
obj->o_hplus = 1;
|
||||||
|
obj->o_dplus = 1;
|
||||||
|
add_pack(obj, TRUE);
|
||||||
|
cur_weapon = obj;
|
||||||
|
/*
|
||||||
|
* And his suit of armor
|
||||||
|
*/
|
||||||
|
obj = new_item();
|
||||||
|
obj->o_type = ARMOR;
|
||||||
|
obj->o_which = PLATE_MAIL;
|
||||||
|
obj->o_arm = -5;
|
||||||
|
obj->o_flags |= ISKNOW;
|
||||||
|
obj->o_count = 1;
|
||||||
|
obj->o_group = 0;
|
||||||
|
cur_armor = obj;
|
||||||
|
add_pack(obj, TRUE);
|
||||||
|
}
|
||||||
|
when '*' :
|
||||||
|
pr_list();
|
||||||
|
otherwise:
|
||||||
|
illcom(ch);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
illcom(ch);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* turn off flags if no longer needed
|
||||||
|
*/
|
||||||
|
if (!running)
|
||||||
|
door_stop = FALSE;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* If he ran into something to take, let him pick it up.
|
||||||
|
*/
|
||||||
|
if (take != 0)
|
||||||
|
pick_up(take);
|
||||||
|
if (!running)
|
||||||
|
door_stop = FALSE;
|
||||||
|
if (!after)
|
||||||
|
ntimes++;
|
||||||
|
}
|
||||||
|
do_daemons(AFTER);
|
||||||
|
do_fuses(AFTER);
|
||||||
|
if (ISRING(LEFT, R_SEARCH))
|
||||||
|
search();
|
||||||
|
else if (ISRING(LEFT, R_TELEPORT) && rnd(50) == 0)
|
||||||
|
teleport();
|
||||||
|
if (ISRING(RIGHT, R_SEARCH))
|
||||||
|
search();
|
||||||
|
else if (ISRING(RIGHT, R_TELEPORT) && rnd(50) == 0)
|
||||||
|
teleport();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* illcom:
|
||||||
|
* What to do with an illegal command
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
illcom(int ch)
|
||||||
|
{
|
||||||
|
save_msg = FALSE;
|
||||||
|
count = 0;
|
||||||
|
msg("illegal command '%s'", unctrl(ch));
|
||||||
|
save_msg = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* search:
|
||||||
|
* player gropes about him to find hidden things.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
search(void)
|
||||||
|
{
|
||||||
|
int y, x;
|
||||||
|
int *fp;
|
||||||
|
int ey, ex;
|
||||||
|
int probinc;
|
||||||
|
int found;
|
||||||
|
|
||||||
|
ey = hero.y + 1;
|
||||||
|
ex = hero.x + 1;
|
||||||
|
probinc = (on(player, ISHALU) ? 3 : 0);
|
||||||
|
probinc += (on(player, ISBLIND) ? 2 : 0);
|
||||||
|
found = FALSE;
|
||||||
|
for (y = hero.y - 1; y <= ey; y++)
|
||||||
|
for (x = hero.x - 1; x <= ex; x++)
|
||||||
|
{
|
||||||
|
if (y == hero.y && x == hero.x)
|
||||||
|
continue;
|
||||||
|
fp = &flat(y, x);
|
||||||
|
if (!(*fp & F_REAL))
|
||||||
|
switch (chat(y, x))
|
||||||
|
{
|
||||||
|
case '|':
|
||||||
|
case '-':
|
||||||
|
if (rnd(5 + probinc) != 0)
|
||||||
|
break;
|
||||||
|
chat(y, x) = DOOR;
|
||||||
|
msg("a secret door");
|
||||||
|
foundone:
|
||||||
|
found = TRUE;
|
||||||
|
*fp |= F_REAL;
|
||||||
|
count = FALSE;
|
||||||
|
running = FALSE;
|
||||||
|
break;
|
||||||
|
case FLOOR:
|
||||||
|
if (rnd(2 + probinc) != 0)
|
||||||
|
break;
|
||||||
|
chat(y, x) = TRAP;
|
||||||
|
if (!terse)
|
||||||
|
addmsg("you found ");
|
||||||
|
if (on(player, ISHALU))
|
||||||
|
msg(tr_name[rnd(NTRAPS)]);
|
||||||
|
else {
|
||||||
|
msg(tr_name[*fp & F_TMASK]);
|
||||||
|
*fp |= F_SEEN;
|
||||||
|
}
|
||||||
|
goto foundone;
|
||||||
|
break;
|
||||||
|
case ' ':
|
||||||
|
if (rnd(3 + probinc) != 0)
|
||||||
|
break;
|
||||||
|
chat(y, x) = PASSAGE;
|
||||||
|
goto foundone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found)
|
||||||
|
look(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* help:
|
||||||
|
* Give single character help, or the whole mess if he wants it
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
help(void)
|
||||||
|
{
|
||||||
|
const struct h_list *strp;
|
||||||
|
int helpch;
|
||||||
|
int numprint, cnt;
|
||||||
|
msg("character you want help for (* for all): ");
|
||||||
|
helpch = readchar();
|
||||||
|
mpos = 0;
|
||||||
|
/*
|
||||||
|
* If its not a *, print the right help string
|
||||||
|
* or an error if he typed a funny character.
|
||||||
|
*/
|
||||||
|
if (helpch != '*')
|
||||||
|
{
|
||||||
|
move(0, 0);
|
||||||
|
for (strp = helpstr; strp->h_desc != NULL; strp++)
|
||||||
|
if (strp->h_ch == helpch)
|
||||||
|
{
|
||||||
|
lower_msg = TRUE;
|
||||||
|
msg("%s%s", unctrl(strp->h_ch), strp->h_desc);
|
||||||
|
lower_msg = FALSE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
msg("unknown character '%s'", unctrl(helpch));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Here we print help for everything.
|
||||||
|
* Then wait before we return to command mode
|
||||||
|
*/
|
||||||
|
numprint = 0;
|
||||||
|
for (strp = helpstr; strp->h_desc != NULL; strp++)
|
||||||
|
if (strp->h_print)
|
||||||
|
numprint++;
|
||||||
|
if (numprint & 01) /* round odd numbers up */
|
||||||
|
numprint++;
|
||||||
|
numprint /= 2;
|
||||||
|
if (numprint > LINES - 1)
|
||||||
|
numprint = LINES - 1;
|
||||||
|
|
||||||
|
wclear(hw);
|
||||||
|
cnt = 0;
|
||||||
|
for (strp = helpstr; strp->h_desc != NULL; strp++)
|
||||||
|
if (strp->h_print)
|
||||||
|
{
|
||||||
|
wmove(hw, cnt % numprint, cnt >= numprint ? COLS / 2 : 0);
|
||||||
|
if (strp->h_ch)
|
||||||
|
waddstr(hw, unctrl(strp->h_ch));
|
||||||
|
waddstr(hw, strp->h_desc);
|
||||||
|
if (++cnt >= numprint * 2)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
wmove(hw, LINES - 1, 0);
|
||||||
|
waddstr(hw, "--Press space to continue--");
|
||||||
|
wrefresh(hw);
|
||||||
|
wait_for(hw, ' ');
|
||||||
|
clearok(stdscr, TRUE);
|
||||||
|
/*
|
||||||
|
refresh();
|
||||||
|
*/
|
||||||
|
msg("");
|
||||||
|
touchwin(stdscr);
|
||||||
|
wrefresh(stdscr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* identify:
|
||||||
|
* Tell the player what a certain thing is.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
identify(void)
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
const struct h_list *hp;
|
||||||
|
const char *str;
|
||||||
|
const struct h_list ident_list[] = {
|
||||||
|
{'|', "wall of a room", FALSE},
|
||||||
|
{'-', "wall of a room", FALSE},
|
||||||
|
{GOLD, "gold", FALSE},
|
||||||
|
{STAIRS, "a staircase", FALSE},
|
||||||
|
{DOOR, "door", FALSE},
|
||||||
|
{FLOOR, "room floor", FALSE},
|
||||||
|
{PLAYER, "you", FALSE},
|
||||||
|
{PASSAGE, "passage", FALSE},
|
||||||
|
{TRAP, "trap", FALSE},
|
||||||
|
{POTION, "potion", FALSE},
|
||||||
|
{SCROLL, "scroll", FALSE},
|
||||||
|
{FOOD, "food", FALSE},
|
||||||
|
{WEAPON, "weapon", FALSE},
|
||||||
|
{' ', "solid rock", FALSE},
|
||||||
|
{ARMOR, "armor", FALSE},
|
||||||
|
{AMULET, "the Amulet of Yendor", FALSE},
|
||||||
|
{RING, "ring", FALSE},
|
||||||
|
{STICK, "wand or staff", FALSE},
|
||||||
|
{'\0'}
|
||||||
|
};
|
||||||
|
|
||||||
|
msg("what do you want identified? ");
|
||||||
|
ch = readchar();
|
||||||
|
mpos = 0;
|
||||||
|
if (ch == ESCAPE)
|
||||||
|
{
|
||||||
|
msg("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isupper(ch))
|
||||||
|
str = monsters[ch-'A'].m_name;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
str = "unknown character";
|
||||||
|
for (hp = ident_list; hp->h_ch != '\0'; hp++)
|
||||||
|
if (hp->h_ch == ch)
|
||||||
|
{
|
||||||
|
str = hp->h_desc;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg("'%s': %s", unctrl(ch), str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* d_level:
|
||||||
|
* He wants to go down a level
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
d_level(void)
|
||||||
|
{
|
||||||
|
if (levit_check())
|
||||||
|
return;
|
||||||
|
if (chat(hero.y, hero.x) != STAIRS)
|
||||||
|
msg("I see no way down");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
level++;
|
||||||
|
seenstairs = FALSE;
|
||||||
|
new_level();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* u_level:
|
||||||
|
* He wants to go up a level
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
u_level(void)
|
||||||
|
{
|
||||||
|
if (levit_check())
|
||||||
|
return;
|
||||||
|
if (chat(hero.y, hero.x) == STAIRS)
|
||||||
|
if (amulet)
|
||||||
|
{
|
||||||
|
level--;
|
||||||
|
if (level == 0)
|
||||||
|
total_winner();
|
||||||
|
new_level();
|
||||||
|
msg("you feel a wrenching sensation in your gut");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
msg("your way is magically blocked");
|
||||||
|
else
|
||||||
|
msg("I see no way up");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* levit_check:
|
||||||
|
* Check to see if she's levitating, and if she is, print an
|
||||||
|
* appropriate message.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
levit_check(void)
|
||||||
|
{
|
||||||
|
if (!on(player, ISLEVIT))
|
||||||
|
return FALSE;
|
||||||
|
msg("You can't. You're floating off the ground!");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* call:
|
||||||
|
* Allow a user to call a potion, scroll, or ring something
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
call(void)
|
||||||
|
{
|
||||||
|
THING *obj;
|
||||||
|
struct obj_info *op = NULL;
|
||||||
|
char **guess;
|
||||||
|
const char *elsewise = NULL;
|
||||||
|
int *know;
|
||||||
|
|
||||||
|
obj = get_item("call", CALLABLE);
|
||||||
|
/*
|
||||||
|
* Make certain that it is somethings that we want to wear
|
||||||
|
*/
|
||||||
|
if (obj == NULL)
|
||||||
|
return;
|
||||||
|
switch (obj->o_type)
|
||||||
|
{
|
||||||
|
case RING:
|
||||||
|
op = &ring_info[obj->o_which];
|
||||||
|
elsewise = r_stones[obj->o_which];
|
||||||
|
goto norm;
|
||||||
|
when POTION:
|
||||||
|
op = &pot_info[obj->o_which];
|
||||||
|
elsewise = p_colors[obj->o_which];
|
||||||
|
goto norm;
|
||||||
|
when SCROLL:
|
||||||
|
op = &scr_info[obj->o_which];
|
||||||
|
elsewise = s_names[obj->o_which];
|
||||||
|
goto norm;
|
||||||
|
when STICK:
|
||||||
|
op = &ws_info[obj->o_which];
|
||||||
|
elsewise = ws_made[obj->o_which];
|
||||||
|
norm:
|
||||||
|
know = &op->oi_know;
|
||||||
|
guess = &op->oi_guess;
|
||||||
|
if (*guess != NULL)
|
||||||
|
elsewise = *guess;
|
||||||
|
when FOOD:
|
||||||
|
msg("you can't call that anything");
|
||||||
|
return;
|
||||||
|
otherwise:
|
||||||
|
guess = &obj->o_label;
|
||||||
|
know = NULL;
|
||||||
|
elsewise = obj->o_label;
|
||||||
|
}
|
||||||
|
if (know != NULL && *know)
|
||||||
|
{
|
||||||
|
msg("that has already been identified");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (elsewise != NULL && elsewise == *guess)
|
||||||
|
{
|
||||||
|
if (!terse)
|
||||||
|
addmsg("Was ");
|
||||||
|
msg("called \"%s\"", elsewise);
|
||||||
|
}
|
||||||
|
if (terse)
|
||||||
|
msg("call it: ");
|
||||||
|
else
|
||||||
|
msg("what do you want to call it? ");
|
||||||
|
|
||||||
|
if (elsewise == NULL)
|
||||||
|
strcpy(prbuf, "");
|
||||||
|
else
|
||||||
|
strcpy(prbuf, elsewise);
|
||||||
|
if (get_str(prbuf, stdscr) == NORM)
|
||||||
|
{
|
||||||
|
if (*guess != NULL)
|
||||||
|
free(*guess);
|
||||||
|
*guess = malloc(strlen(prbuf) + 1);
|
||||||
|
if (*guess != NULL)
|
||||||
|
strcpy(*guess, prbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
msg("");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* current:
|
||||||
|
* Print the current weapon/armor
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
current(const THING *cur, const char *how, const char *where)
|
||||||
|
{
|
||||||
|
after = FALSE;
|
||||||
|
if (cur != NULL)
|
||||||
|
{
|
||||||
|
if (!terse)
|
||||||
|
addmsg("you are %s (", how);
|
||||||
|
inv_describe = FALSE;
|
||||||
|
addmsg("%c) %s", cur->o_packch, inv_name(cur, TRUE));
|
||||||
|
inv_describe = TRUE;
|
||||||
|
if (where)
|
||||||
|
addmsg(" %s", where);
|
||||||
|
endmsg();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!terse)
|
||||||
|
addmsg("you are ");
|
||||||
|
addmsg("%s nothing", how);
|
||||||
|
if (where)
|
||||||
|
addmsg(" %s", where);
|
||||||
|
endmsg();
|
||||||
|
}
|
||||||
|
}
|
||||||
1500
rogue5/config.guess
vendored
Executable file
1500
rogue5/config.guess
vendored
Executable file
File diff suppressed because it is too large
Load diff
269
rogue5/config.h.in
Normal file
269
rogue5/config.h.in
Normal file
|
|
@ -0,0 +1,269 @@
|
||||||
|
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||||
|
|
||||||
|
/* Define if scorefile is top scores, not top players */
|
||||||
|
#undef ALLSCORES
|
||||||
|
|
||||||
|
/* Define if checktime feature should be enabled */
|
||||||
|
#undef CHECKTIME
|
||||||
|
|
||||||
|
/* Define to group owner of setgid executable */
|
||||||
|
#undef GROUPOWNER
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `alarm' function. */
|
||||||
|
#undef HAVE_ALARM
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||||
|
#undef HAVE_ARPA_INET_H
|
||||||
|
|
||||||
|
/* Define to 1 if libcurses is requested */
|
||||||
|
#undef HAVE_CURSES_H
|
||||||
|
|
||||||
|
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
|
||||||
|
#undef HAVE_DOPRNT
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `erasechar' function. */
|
||||||
|
#undef HAVE_ERASECHAR
|
||||||
|
|
||||||
|
/* Define if ncurses has ESCDELAY variable */
|
||||||
|
#undef HAVE_ESCDELAY
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||||
|
#undef HAVE_FCNTL_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `fork' function. */
|
||||||
|
#undef HAVE_FORK
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `getgid' function. */
|
||||||
|
#undef HAVE_GETGID
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `getloadavg' function. */
|
||||||
|
#undef HAVE_GETLOADAVG
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `getpass' function. */
|
||||||
|
#undef HAVE_GETPASS
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `getpwuid' function. */
|
||||||
|
#undef HAVE_GETPWUID
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `getuid' function. */
|
||||||
|
#undef HAVE_GETUID
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||||
|
#undef HAVE_INTTYPES_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `killchar' function. */
|
||||||
|
#undef HAVE_KILLCHAR
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <limits.h> header file. */
|
||||||
|
#undef HAVE_LIMITS_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `loadav' function. */
|
||||||
|
#undef HAVE_LOADAV
|
||||||
|
|
||||||
|
/* Define to 1 if `lstat' has the bug that it succeeds when given the
|
||||||
|
zero-length file name argument. */
|
||||||
|
#undef HAVE_LSTAT_EMPTY_STRING_BUG
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <memory.h> header file. */
|
||||||
|
#undef HAVE_MEMORY_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `memset' function. */
|
||||||
|
#undef HAVE_MEMSET
|
||||||
|
|
||||||
|
/* Define to 1 if libncurses is requested */
|
||||||
|
#undef HAVE_NCURSES_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <ncurses/term.h> header file. */
|
||||||
|
#undef HAVE_NCURSES_TERM_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `nlist' function. */
|
||||||
|
#undef HAVE_NLIST
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <nlist.h> header file. */
|
||||||
|
#undef HAVE_NLIST_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <process.h> header file. */
|
||||||
|
#undef HAVE_PROCESS_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <pwd.h> header file. */
|
||||||
|
#undef HAVE_PWD_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `setenv' function. */
|
||||||
|
#undef HAVE_SETENV
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `setgid' function. */
|
||||||
|
#undef HAVE_SETGID
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `setregid' function. */
|
||||||
|
#undef HAVE_SETREGID
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `setresgid' function. */
|
||||||
|
#undef HAVE_SETRESGID
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `setresuid' function. */
|
||||||
|
#undef HAVE_SETRESUID
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `setreuid' function. */
|
||||||
|
#undef HAVE_SETREUID
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `setuid' function. */
|
||||||
|
#undef HAVE_SETUID
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `spawnl' function. */
|
||||||
|
#undef HAVE_SPAWNL
|
||||||
|
|
||||||
|
/* Define to 1 if `stat' has the bug that it succeeds when given the
|
||||||
|
zero-length file name argument. */
|
||||||
|
#undef HAVE_STAT_EMPTY_STRING_BUG
|
||||||
|
|
||||||
|
/* Define to 1 if stdbool.h conforms to C99. */
|
||||||
|
#undef HAVE_STDBOOL_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdint.h> header file. */
|
||||||
|
#undef HAVE_STDINT_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||||
|
#undef HAVE_STDLIB_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strchr' function. */
|
||||||
|
#undef HAVE_STRCHR
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strerror' function. */
|
||||||
|
#undef HAVE_STRERROR
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <strings.h> header file. */
|
||||||
|
#undef HAVE_STRINGS_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <string.h> header file. */
|
||||||
|
#undef HAVE_STRING_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
||||||
|
#undef HAVE_SYS_IOCTL_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||||
|
#undef HAVE_SYS_STAT_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||||
|
#undef HAVE_SYS_TYPES_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/utsname.h> header file. */
|
||||||
|
#undef HAVE_SYS_UTSNAME_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <termios.h> header file. */
|
||||||
|
#undef HAVE_TERMIOS_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <term.h> header file. */
|
||||||
|
#undef HAVE_TERM_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <unistd.h> header file. */
|
||||||
|
#undef HAVE_UNISTD_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <utmp.h> header file. */
|
||||||
|
#undef HAVE_UTMP_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `vfork' function. */
|
||||||
|
#undef HAVE_VFORK
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <vfork.h> header file. */
|
||||||
|
#undef HAVE_VFORK_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `vprintf' function. */
|
||||||
|
#undef HAVE_VPRINTF
|
||||||
|
|
||||||
|
/* Define to 1 if `fork' works. */
|
||||||
|
#undef HAVE_WORKING_FORK
|
||||||
|
|
||||||
|
/* Define to 1 if `vfork' works. */
|
||||||
|
#undef HAVE_WORKING_VFORK
|
||||||
|
|
||||||
|
/* Define to 1 if the system has the type `_Bool'. */
|
||||||
|
#undef HAVE__BOOL
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `_spawnl' function. */
|
||||||
|
#undef HAVE__SPAWNL
|
||||||
|
|
||||||
|
/* define if we should use program's load average function instead of system
|
||||||
|
*/
|
||||||
|
#undef LOADAV
|
||||||
|
|
||||||
|
/* Define to file to use for scoreboard lockfile */
|
||||||
|
#undef LOCKFILE
|
||||||
|
|
||||||
|
/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
|
||||||
|
slash. */
|
||||||
|
#undef LSTAT_FOLLOWS_SLASHED_SYMLINK
|
||||||
|
|
||||||
|
/* Define to include wizard mode */
|
||||||
|
#undef MASTER
|
||||||
|
|
||||||
|
/* Define if maxusers feature should be enabled */
|
||||||
|
#undef MAXLOAD
|
||||||
|
|
||||||
|
/* Define if maxusers feature should be enabled */
|
||||||
|
#undef MAXUSERS
|
||||||
|
|
||||||
|
/* kernel file to pass to nlist() when reading load average (unlikely to work)
|
||||||
|
*/
|
||||||
|
#undef NAMELIST
|
||||||
|
|
||||||
|
/* word for the number of scores to store in scoreboard */
|
||||||
|
#undef NUMNAME
|
||||||
|
|
||||||
|
/* number of scores to store in scoreboard */
|
||||||
|
#undef NUMSCORES
|
||||||
|
|
||||||
|
/* Define to the address where bug reports for this package should be sent. */
|
||||||
|
#undef PACKAGE_BUGREPORT
|
||||||
|
|
||||||
|
/* Define to the full name of this package. */
|
||||||
|
#undef PACKAGE_NAME
|
||||||
|
|
||||||
|
/* Define to the full name and version of this package. */
|
||||||
|
#undef PACKAGE_STRING
|
||||||
|
|
||||||
|
/* Define to the one symbol short name of this package. */
|
||||||
|
#undef PACKAGE_TARNAME
|
||||||
|
|
||||||
|
/* Define to the version of this package. */
|
||||||
|
#undef PACKAGE_VERSION
|
||||||
|
|
||||||
|
/* Define crypt(3) wizard mode password */
|
||||||
|
#undef PASSWD
|
||||||
|
|
||||||
|
/* Define as the return type of signal handlers (`int' or `void'). */
|
||||||
|
#undef RETSIGTYPE
|
||||||
|
|
||||||
|
/* Define to file to use for scoreboard */
|
||||||
|
#undef SCOREFILE
|
||||||
|
|
||||||
|
/* Define to 1 if you have the ANSI C header files. */
|
||||||
|
#undef STDC_HEADERS
|
||||||
|
|
||||||
|
/* Define to 1 if your <sys/time.h> declares `struct tm'. */
|
||||||
|
#undef TM_IN_SYS_TIME
|
||||||
|
|
||||||
|
/* define if we should use program's user counting function instead of
|
||||||
|
system's */
|
||||||
|
#undef UCOUNT
|
||||||
|
|
||||||
|
/* utmp like file to pass to ucount() when counting online users (unlikely to
|
||||||
|
work) */
|
||||||
|
#undef UTMP
|
||||||
|
|
||||||
|
/* Define to empty if `const' does not conform to ANSI C. */
|
||||||
|
#undef const
|
||||||
|
|
||||||
|
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||||
|
#undef gid_t
|
||||||
|
|
||||||
|
/* Define to `int' if <sys/types.h> does not define. */
|
||||||
|
#undef pid_t
|
||||||
|
|
||||||
|
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||||
|
#undef size_t
|
||||||
|
|
||||||
|
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||||
|
#undef uid_t
|
||||||
|
|
||||||
|
/* Define as `fork' if `vfork' does not work. */
|
||||||
|
#undef vfork
|
||||||
1608
rogue5/config.sub
vendored
Executable file
1608
rogue5/config.sub
vendored
Executable file
File diff suppressed because it is too large
Load diff
7511
rogue5/configure
vendored
Executable file
7511
rogue5/configure
vendored
Executable file
File diff suppressed because it is too large
Load diff
246
rogue5/configure.ac
Normal file
246
rogue5/configure.ac
Normal file
|
|
@ -0,0 +1,246 @@
|
||||||
|
# -*- Autoconf -*-
|
||||||
|
# Process this file with autoconf to produce a configure script.
|
||||||
|
|
||||||
|
AC_PREREQ(2.56)
|
||||||
|
AC_INIT([Rogue],[5.4.5], [yendor@rogueforge.net])
|
||||||
|
AC_CONFIG_SRCDIR([armor.c])
|
||||||
|
AC_CONFIG_HEADER([config.h])
|
||||||
|
AC_CONFIG_FILES([Makefile rogue.6 rogue.cat rogue.doc rogue.html rogue.me])
|
||||||
|
AC_CANONICAL_SYSTEM([])
|
||||||
|
|
||||||
|
# Checks for programs.
|
||||||
|
AC_PROG_CC
|
||||||
|
|
||||||
|
# Checks for libraries.
|
||||||
|
|
||||||
|
# Checks for header files.
|
||||||
|
AC_HEADER_STDC
|
||||||
|
AC_CHECK_HEADERS([arpa/inet.h sys/utsname.h pwd.h fcntl.h limits.h nlist.h stdlib.h string.h sys/ioctl.h termios.h unistd.h utmp.h term.h ncurses/term.h process.h])
|
||||||
|
|
||||||
|
# Checks for typedefs, structures, and compiler characteristics.
|
||||||
|
AC_HEADER_STDBOOL
|
||||||
|
AC_C_CONST
|
||||||
|
AC_TYPE_UID_T
|
||||||
|
AC_TYPE_SIZE_T
|
||||||
|
AC_STRUCT_TM
|
||||||
|
MP_WITH_CURSES
|
||||||
|
# Checks for library functions.
|
||||||
|
AC_FUNC_FORK
|
||||||
|
AC_PROG_GCC_TRADITIONAL
|
||||||
|
AC_FUNC_LSTAT
|
||||||
|
AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK
|
||||||
|
AC_TYPE_SIGNAL
|
||||||
|
AC_FUNC_STAT
|
||||||
|
AC_FUNC_VPRINTF
|
||||||
|
AC_CHECK_FUNCS([erasechar killchar alarm getpass memset setenv strchr nlist _spawnl spawnl getpwuid loadav getloadavg strerror setresgid setregid setgid setresuid setreuid setuid getuid getgid])
|
||||||
|
|
||||||
|
AC_CHECK_PROG([NROFF], [nroff], [nroff],)
|
||||||
|
AC_CHECK_PROG([GROFF], [groff], [groff],)
|
||||||
|
AC_CHECK_PROG([COLCRT], [colcrt], [colcrt],)
|
||||||
|
AC_CHECK_PROG([TBL], [tbl], [tbl],)
|
||||||
|
AC_CHECK_PROG([SED], [sed], [sed],)
|
||||||
|
|
||||||
|
AC_ARG_WITH(program-name, AC_HELP_STRING([--with-program-name=NAME],[alternate executable name]),[progname="$withval" ], [progname="rogue"] )
|
||||||
|
PROGRAM=$progname
|
||||||
|
AC_SUBST(PROGRAM)
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(setgid, AC_HELP_STRING([--enable-setgid=NAME],[install executable as setgid with group ownership of NAME @<:@default=no@:>@])],[],[])
|
||||||
|
AC_MSG_CHECKING([if using setgid execute bit])
|
||||||
|
if test "x$enable_setgid" = "xno" ; then
|
||||||
|
GROUPOWNER=
|
||||||
|
elif test "x$enable_setgid" = "xyes" ; then
|
||||||
|
GROUPOWNER=games
|
||||||
|
elif test "x$enable_setgid" = "x" ; then
|
||||||
|
GROUPOWNER=
|
||||||
|
else
|
||||||
|
GROUPOWNER=$enable_setgid
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x$GROUPOWNER" != "x" ; then
|
||||||
|
AC_DEFINE_UNQUOTED([GROUPOWNER],[$GROUPOWNER], [Define to group owner of setgid executable])
|
||||||
|
AC_MSG_RESULT([$GROUPOWNER])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_SUBST(GROUPOWNER)
|
||||||
|
|
||||||
|
AC_ARG_ENABLE([scorefile],[AC_HELP_STRING([--enable-scorefile=SCOREFILE], [enable scoreboard with given filename])],[],[])
|
||||||
|
AC_MSG_CHECKING([for scoreboard file])
|
||||||
|
if test "x$enable_scorefile" = "xno" ; then
|
||||||
|
SCOREFILE=
|
||||||
|
elif test "x$enable_scorefile" = "xyes" ; then
|
||||||
|
SCOREFILE=$progname.scr
|
||||||
|
elif test "x$enable_scorefile" = "x" ; then
|
||||||
|
SCOREFILE=$progname.scr
|
||||||
|
else
|
||||||
|
SCOREFILE=$enable_scorefile
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x$SCOREFILE" != "x" ; then
|
||||||
|
AC_DEFINE_UNQUOTED([SCOREFILE], ["$SCOREFILE"], [Define to file to use for scoreboard])
|
||||||
|
AC_MSG_RESULT([$SCOREFILE])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([disabled])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_SUBST(SCOREFILE)
|
||||||
|
|
||||||
|
AC_ARG_ENABLE([lockfile],[AC_HELP_STRING([--enable-lockfile=LOCKFILE], [enable scoreboard lockfile with given filename])],[],[])
|
||||||
|
AC_MSG_CHECKING([for scoreboard lockfile file])
|
||||||
|
if test "x$enable_lockfile" = "xno" ; then
|
||||||
|
LOCKFILE=
|
||||||
|
elif test "x$enable_lockfile" = "xyes" ; then
|
||||||
|
LOCKFILE=$progname.lck
|
||||||
|
elif test "x$enable_lockfile" = "x" ; then
|
||||||
|
LOCKFILE=$progname.lck
|
||||||
|
else
|
||||||
|
LOCKFILE=$enable_lockfile
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "x$LOCKFILE" != "x" ; then
|
||||||
|
AC_DEFINE_UNQUOTED([LOCKFILE], ["$LOCKFILE"], [Define to file to use for scoreboard lockfile])
|
||||||
|
AC_MSG_RESULT([$LOCKFILE])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([disabled])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_SUBST(LOCKFILE)
|
||||||
|
|
||||||
|
AC_ARG_ENABLE([wizardmode],[AC_HELP_STRING([--enable-wizardmode], [enable availability of wizard mode @<:@default=no@:>@])],[],[])
|
||||||
|
AC_MSG_CHECKING([if wizard mode is enabled])
|
||||||
|
if test "x$enable_wizardmode" = "xno" ; then
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
elif test "x$enable_wizardmode" = "x" ; then
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
else
|
||||||
|
AC_DEFINE([MASTER], [], [Define to include wizard mode])
|
||||||
|
if test "x$enable_wizardmode" != "xyes" ; then
|
||||||
|
AC_DEFINE_UNQUOTED([PASSWD],["$enable_wizardmode"], [Define crypt(3) wizard mode password])
|
||||||
|
fi
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE([allscores],[AC_HELP_STRING([--enable-allscores], [enable scoreboard to show top scores, not just top players @<:@default=yes@:>@])],[],[enable_allscores=yes])
|
||||||
|
AC_MSG_CHECKING([if allscores is enabled])
|
||||||
|
if test "x$enable_allscores" = "xyes" ; then
|
||||||
|
AC_DEFINE([ALLSCORES], [1], [Define if scorefile is top scores, not top players])
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE([checktime],[AC_HELP_STRING([--enable-checktime], [enable checktime @<:@default=no@:>@])],[],[])
|
||||||
|
AC_MSG_CHECKING([if checktime is enabled])
|
||||||
|
if test "x$enable_checktime" = "xyes" ; then
|
||||||
|
AC_DEFINE([CHECKTIME], [1], [Define if checktime feature should be enabled])
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE([maxload],[AC_HELP_STRING([--enable-maxload], [enable maxload @<:@default=no@:>@])],[],[])
|
||||||
|
AC_MSG_CHECKING([runtime execution limit (maximum system load average)])
|
||||||
|
if test "x$enable_maxload" = "xyes" ; then
|
||||||
|
AC_DEFINE([MAXLOAD], [100], [Define if maxload feature should be enabled])
|
||||||
|
AC_MSG_RESULT([100])
|
||||||
|
elif test "x$enable_maxload" = "x" ; then
|
||||||
|
AC_MSG_RESULT([unlimited])
|
||||||
|
elif test "x$enable_maxload" = "xno" ; then
|
||||||
|
AC_MSG_RESULT([unlimited])
|
||||||
|
else
|
||||||
|
AC_DEFINE_UNQUOTED([MAXLOAD], [$enable_maxload], [Define if maxload feature should be enabled])
|
||||||
|
AC_MSG_RESULT([$enable_maxload])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE([maxusers],[AC_HELP_STRING([--enable-maxusers], [enable maxuser @<:@default=no@:>@])],[],[])
|
||||||
|
AC_MSG_CHECKING([runtime execution limit (maximum online system users)])
|
||||||
|
if test "x$enable_maxusers" = "xyes" ; then
|
||||||
|
AC_DEFINE([MAXUSERS], [100], [Define if maxusers feature should be enabled])
|
||||||
|
AC_MSG_RESULT([100])
|
||||||
|
elif test "x$enable_maxusers" = "x" ; then
|
||||||
|
AC_MSG_RESULT([unlimited])
|
||||||
|
elif test "x$enable_maxload" = "xno" ; then
|
||||||
|
AC_MSG_RESULT([unlimited])
|
||||||
|
else
|
||||||
|
AC_DEFINE_UNQUOTED([MAXLOAD], [$enable_maxusers], [Define if maxusers feature should be enabled])
|
||||||
|
AC_MSG_RESULT([$enable_maxusers])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE([numscores],[AC_HELP_STRING([--enable-numscores], [number of scores to store in scoreboard @<:@default=10@:>@])],[],[])
|
||||||
|
AC_MSG_CHECKING([what the number of scores to store in scoreboard is])
|
||||||
|
if test "x$numscores" = "xyes" ; then
|
||||||
|
AC_DEFINE([NUMSCORES], [10], [number of scores to store in scoreboard])
|
||||||
|
AC_MSG_RESULT([10])
|
||||||
|
elif test "x$enable_numscores" = "x" ; then
|
||||||
|
AC_DEFINE([NUMSCORES], [10], [number of scores to store in scoreboard])
|
||||||
|
AC_MSG_RESULT([10])
|
||||||
|
elif test "x$enable_numscores" = "xno" ; then
|
||||||
|
AC_DEFINE([NUMSCORES], [10], [number of scores to store in scoreboard])
|
||||||
|
AC_MSG_RESULT([10])
|
||||||
|
else
|
||||||
|
AC_DEFINE_UNQUOTED([NUMSCORES], [$enable_numscores], [number of scores to store in scoreboard])
|
||||||
|
AC_MSG_RESULT([$enable_numscores])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE([numname],[AC_HELP_STRING([--enable-numname], [word for number of scores to store in scoreboard @<:@default=Ten@:>@])],[],[])
|
||||||
|
AC_MSG_CHECKING([word for the number of scores to store in scoreboard is])
|
||||||
|
if test "x$enable_numname" = "xyes" ; then
|
||||||
|
AC_DEFINE([NUMNAME], ["Ten"], [word for the number of scores to store in scoreboard])
|
||||||
|
AC_MSG_RESULT([Ten])
|
||||||
|
elif test "x$enable_numname" = "x" ; then
|
||||||
|
AC_DEFINE([NUMNAME], ["Ten"], [word for the number of scores to store in scoreboard])
|
||||||
|
AC_MSG_RESULT([Ten])
|
||||||
|
elif test "x$enable_numname" = "xno" ; then
|
||||||
|
AC_DEFINE([NUMNAME], ["Ten"], [word for the number of scores to store in scoreboard])
|
||||||
|
AC_MSG_RESULT([Ten])
|
||||||
|
else
|
||||||
|
AC_DEFINE_UNQUOTED([NUMNAME], ["$enable_numname"], [word for the number of scores to store in scoreboard])
|
||||||
|
AC_MSG_RESULT([$enable_numname])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE([loadav],[AC_HELP_STRING([--enable-loadav=NAMELIST], [use program's load average function (unlikely to work) @<:@default=no@:>@])],[],[])
|
||||||
|
AC_MSG_CHECKING([whether to use program's built in load average function])
|
||||||
|
if test "x$enable_loadav" = "xyes" ; then
|
||||||
|
AC_DEFINE([LOADAV], [], [define if we should use program's load average function instead of system])
|
||||||
|
AC_DEFINE([NAMELIST], [/vmunix], [kernel file to pass to nlist() when reading load average (unlikely to work)])
|
||||||
|
AC_MSG_RESULT([/vmunix])
|
||||||
|
elif test "x$enable_loadav" = "x" ; then
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
elif test "x$enable_loadav" = "xno" ; then
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
else
|
||||||
|
AC_DEFINE([LOADAV], [], [define if we should use program's load average function instead of system])
|
||||||
|
AC_DEFINE_UNQUOTED([NAMELIST], [$enable_loadav], [kernel file to pass to nlist() when reading load average (unlikely to work)])
|
||||||
|
AC_MSG_RESULT([$enable_loadav])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE([ucount],[AC_HELP_STRING([--enable-ucount=UTMPFILE], [use program's own function to count users (unlikely to work) @<:@default=no@:>@])],[],[])
|
||||||
|
AC_MSG_CHECKING([whether to use program's built in user counting function])
|
||||||
|
if test "x$enable_ucount" = "xyes" ; then
|
||||||
|
AC_DEFINE([UCOUNT], [], [define if we should use program's user counting function instead of system's])
|
||||||
|
AC_DEFINE([UTMP], [/etc/utmp], [utmp like file to pass to ucount() when counting online users (unlikely to work)])
|
||||||
|
AC_MSG_RESULT([/etc/utmp])
|
||||||
|
elif test "x$enable_ucount" = "x" ; then
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
elif test "x$enable_count" = "xno" ; then
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
else
|
||||||
|
AC_DEFINE([UCOUNT], [], [define if we should use program's user counting function instead of system's])
|
||||||
|
AC_DEFINE_UNQUOTED([UTMP], [$enable_ucount], [utmp like file to pass to ucount() when counting online users (unlikely to work)])
|
||||||
|
AC_MSG_RESULT([$enable_ucount])
|
||||||
|
fi
|
||||||
|
|
||||||
|
TARGET=$target
|
||||||
|
AC_SUBST(TARGET)
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([whether to docdir is defined])
|
||||||
|
if test "x$docdir" = "x" ; then
|
||||||
|
AC_MSG_RESULT([docdir undefined])
|
||||||
|
docdir=\${datadir}/doc/\${PACKAGE_TARNAME}
|
||||||
|
AC_SUBST(docdir)
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([docdir defined])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_OUTPUT
|
||||||
172
rogue5/daemon.c
Normal file
172
rogue5/daemon.c
Normal file
|
|
@ -0,0 +1,172 @@
|
||||||
|
/*
|
||||||
|
* Contains functions for dealing with things that happen in the
|
||||||
|
* future.
|
||||||
|
*
|
||||||
|
* @(#)daemon.c 4.7 (Berkeley) 02/05/99
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <curses.h>
|
||||||
|
#include "rogue.h"
|
||||||
|
|
||||||
|
#define DAEMON -1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* d_slot:
|
||||||
|
* Find an empty slot in the daemon/fuse list
|
||||||
|
*/
|
||||||
|
struct delayed_action *
|
||||||
|
d_slot(void)
|
||||||
|
{
|
||||||
|
struct delayed_action *dev;
|
||||||
|
|
||||||
|
for (dev = d_list; dev <= &d_list[MAXDAEMONS-1]; dev++)
|
||||||
|
if (dev->d_type == EMPTY)
|
||||||
|
return dev;
|
||||||
|
#ifdef MASTER
|
||||||
|
debug("Ran out of fuse slots");
|
||||||
|
#endif
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* find_slot:
|
||||||
|
* Find a particular slot in the table
|
||||||
|
*/
|
||||||
|
struct delayed_action *
|
||||||
|
find_slot(void (*func)())
|
||||||
|
{
|
||||||
|
struct delayed_action *dev;
|
||||||
|
|
||||||
|
for (dev = d_list; dev <= &d_list[MAXDAEMONS-1]; dev++)
|
||||||
|
if (dev->d_type != EMPTY && func == dev->d_func)
|
||||||
|
return dev;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* start_daemon:
|
||||||
|
* Start a daemon, takes a function.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
start_daemon(void (*func)(), int arg, int type)
|
||||||
|
{
|
||||||
|
struct delayed_action *dev;
|
||||||
|
|
||||||
|
dev = d_slot();
|
||||||
|
dev->d_type = type;
|
||||||
|
dev->d_func = func;
|
||||||
|
dev->d_arg = arg;
|
||||||
|
dev->d_time = DAEMON;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* kill_daemon:
|
||||||
|
* Remove a daemon from the list
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
kill_daemon(void (*func)())
|
||||||
|
{
|
||||||
|
struct delayed_action *dev;
|
||||||
|
|
||||||
|
if ((dev = find_slot(func)) == NULL)
|
||||||
|
return;
|
||||||
|
/*
|
||||||
|
* Take it out of the list
|
||||||
|
*/
|
||||||
|
dev->d_type = EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* do_daemons:
|
||||||
|
* Run all the daemons that are active with the current flag,
|
||||||
|
* passing the argument to the function.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
do_daemons(int flag)
|
||||||
|
{
|
||||||
|
struct delayed_action *dev;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Loop through the devil list
|
||||||
|
*/
|
||||||
|
for (dev = d_list; dev <= &d_list[MAXDAEMONS-1]; dev++)
|
||||||
|
/*
|
||||||
|
* Executing each one, giving it the proper arguments
|
||||||
|
*/
|
||||||
|
if (dev->d_type == flag && dev->d_time == DAEMON)
|
||||||
|
(*dev->d_func)(dev->d_arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fuse:
|
||||||
|
* Start a fuse to go off in a certain number of turns
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
fuse(void (*func)(), int arg, int time, int type)
|
||||||
|
{
|
||||||
|
struct delayed_action *wire;
|
||||||
|
|
||||||
|
wire = d_slot();
|
||||||
|
wire->d_type = type;
|
||||||
|
wire->d_func = func;
|
||||||
|
wire->d_arg = arg;
|
||||||
|
wire->d_time = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* lengthen:
|
||||||
|
* Increase the time until a fuse goes off
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
lengthen(void (*func)(), int xtime)
|
||||||
|
{
|
||||||
|
struct delayed_action *wire;
|
||||||
|
|
||||||
|
if ((wire = find_slot(func)) == NULL)
|
||||||
|
return;
|
||||||
|
wire->d_time += xtime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* extinguish:
|
||||||
|
* Put out a fuse
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
extinguish(void (*func)())
|
||||||
|
{
|
||||||
|
struct delayed_action *wire;
|
||||||
|
|
||||||
|
if ((wire = find_slot(func)) == NULL)
|
||||||
|
return;
|
||||||
|
wire->d_type = EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* do_fuses:
|
||||||
|
* Decrement counters and start needed fuses
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
do_fuses(int flag)
|
||||||
|
{
|
||||||
|
struct delayed_action *wire;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Step though the list
|
||||||
|
*/
|
||||||
|
for (wire = d_list; wire <= &d_list[MAXDAEMONS-1]; wire++)
|
||||||
|
/*
|
||||||
|
* Decrementing counters and starting things we want. We also need
|
||||||
|
* to remove the fuse from the list once it has gone off.
|
||||||
|
*/
|
||||||
|
if (flag == wire->d_type && wire->d_time > 0 && --wire->d_time == 0)
|
||||||
|
{
|
||||||
|
wire->d_type = EMPTY;
|
||||||
|
(*wire->d_func)(wire->d_arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
295
rogue5/daemons.c
Normal file
295
rogue5/daemons.c
Normal file
|
|
@ -0,0 +1,295 @@
|
||||||
|
/*
|
||||||
|
* All the daemon and fuse functions are in here
|
||||||
|
*
|
||||||
|
* @(#)daemons.c 4.24 (Berkeley) 02/05/99
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <curses.h>
|
||||||
|
#include "rogue.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* doctor:
|
||||||
|
* A healing daemon that restors hit points after rest
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
doctor(void)
|
||||||
|
{
|
||||||
|
int lv, ohp;
|
||||||
|
|
||||||
|
lv = pstats.s_lvl;
|
||||||
|
ohp = pstats.s_hpt;
|
||||||
|
quiet++;
|
||||||
|
if (lv < 8)
|
||||||
|
{
|
||||||
|
if (quiet + (lv << 1) > 20)
|
||||||
|
pstats.s_hpt++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (quiet >= 3)
|
||||||
|
pstats.s_hpt += rnd(lv - 7) + 1;
|
||||||
|
if (ISRING(LEFT, R_REGEN))
|
||||||
|
pstats.s_hpt++;
|
||||||
|
if (ISRING(RIGHT, R_REGEN))
|
||||||
|
pstats.s_hpt++;
|
||||||
|
if (ohp != pstats.s_hpt)
|
||||||
|
{
|
||||||
|
if (pstats.s_hpt > max_hp)
|
||||||
|
pstats.s_hpt = max_hp;
|
||||||
|
quiet = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Swander:
|
||||||
|
* Called when it is time to start rolling for wandering monsters
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
swander(void)
|
||||||
|
{
|
||||||
|
start_daemon(rollwand, 0, BEFORE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rollwand:
|
||||||
|
* Called to roll to see if a wandering monster starts up
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
rollwand(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (++between >= 4)
|
||||||
|
{
|
||||||
|
if (roll(1, 6) == 4)
|
||||||
|
{
|
||||||
|
wanderer();
|
||||||
|
kill_daemon(rollwand);
|
||||||
|
fuse(swander, 0, WANDERTIME, BEFORE);
|
||||||
|
}
|
||||||
|
between = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* unconfuse:
|
||||||
|
* Release the poor player from his confusion
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
unconfuse(void)
|
||||||
|
{
|
||||||
|
player.t_flags &= ~ISHUH;
|
||||||
|
msg("you feel less %s now", choose_str("trippy", "confused"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* unsee:
|
||||||
|
* Turn off the ability to see invisible
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
unsee(void)
|
||||||
|
{
|
||||||
|
THING *th;
|
||||||
|
|
||||||
|
for (th = mlist; th != NULL; th = next(th))
|
||||||
|
if (on(*th, ISINVIS) && see_monst(th))
|
||||||
|
mvaddch(th->t_pos.y, th->t_pos.x, th->t_oldch);
|
||||||
|
player.t_flags &= ~CANSEE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sight:
|
||||||
|
* He gets his sight back
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
sight(void)
|
||||||
|
{
|
||||||
|
if (on(player, ISBLIND))
|
||||||
|
{
|
||||||
|
extinguish(sight);
|
||||||
|
player.t_flags &= ~ISBLIND;
|
||||||
|
if (!(proom->r_flags & ISGONE))
|
||||||
|
enter_room(&hero);
|
||||||
|
msg(choose_str("far out! Everything is all cosmic again",
|
||||||
|
"the veil of darkness lifts"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* nohaste:
|
||||||
|
* End the hasting
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
nohaste(void)
|
||||||
|
{
|
||||||
|
player.t_flags &= ~ISHASTE;
|
||||||
|
msg("you feel yourself slowing down");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* stomach:
|
||||||
|
* Digest the hero's food
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
stomach(void)
|
||||||
|
{
|
||||||
|
int oldfood;
|
||||||
|
int orig_hungry = hungry_state;
|
||||||
|
|
||||||
|
if (food_left <= 0)
|
||||||
|
{
|
||||||
|
if (food_left-- < -STARVETIME)
|
||||||
|
death('s');
|
||||||
|
/*
|
||||||
|
* the hero is fainting
|
||||||
|
*/
|
||||||
|
if (no_command || rnd(5) != 0)
|
||||||
|
return;
|
||||||
|
no_command += rnd(8) + 4;
|
||||||
|
hungry_state = 3;
|
||||||
|
if (!terse)
|
||||||
|
addmsg(choose_str("the munchies overpower your motor capabilities. ",
|
||||||
|
"you feel too weak from lack of food. "));
|
||||||
|
msg(choose_str("You freak out", "You faint"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
oldfood = food_left;
|
||||||
|
food_left -= ring_eat(LEFT) + ring_eat(RIGHT) + 1 - amulet;
|
||||||
|
|
||||||
|
if (food_left < MORETIME && oldfood >= MORETIME)
|
||||||
|
{
|
||||||
|
hungry_state = 2;
|
||||||
|
msg(choose_str("the munchies are interfering with your motor capabilites",
|
||||||
|
"you are starting to feel weak"));
|
||||||
|
}
|
||||||
|
else if (food_left < 2 * MORETIME && oldfood >= 2 * MORETIME)
|
||||||
|
{
|
||||||
|
hungry_state = 1;
|
||||||
|
if (terse)
|
||||||
|
msg(choose_str("getting the munchies", "getting hungry"));
|
||||||
|
else
|
||||||
|
msg(choose_str("you are getting the munchies",
|
||||||
|
"you are starting to get hungry"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hungry_state != orig_hungry) {
|
||||||
|
player.t_flags &= ~ISRUN;
|
||||||
|
running = FALSE;
|
||||||
|
to_death = FALSE;
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* come_down:
|
||||||
|
* Take the hero down off her acid trip.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
come_down(void)
|
||||||
|
{
|
||||||
|
THING *tp;
|
||||||
|
int seemonst;
|
||||||
|
|
||||||
|
if (!on(player, ISHALU))
|
||||||
|
return;
|
||||||
|
|
||||||
|
kill_daemon(visuals);
|
||||||
|
player.t_flags &= ~ISHALU;
|
||||||
|
|
||||||
|
if (on(player, ISBLIND))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* undo the things
|
||||||
|
*/
|
||||||
|
for (tp = lvl_obj; tp != NULL; tp = next(tp))
|
||||||
|
if (cansee(tp->o_pos.y, tp->o_pos.x))
|
||||||
|
mvaddch(tp->o_pos.y, tp->o_pos.x, tp->o_type);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* undo the monsters
|
||||||
|
*/
|
||||||
|
seemonst = on(player, SEEMONST);
|
||||||
|
for (tp = mlist; tp != NULL; tp = next(tp))
|
||||||
|
{
|
||||||
|
move(tp->t_pos.y, tp->t_pos.x);
|
||||||
|
if (cansee(tp->t_pos.y, tp->t_pos.x))
|
||||||
|
if (!on(*tp, ISINVIS) || on(player, CANSEE))
|
||||||
|
addch(tp->t_disguise);
|
||||||
|
else
|
||||||
|
addch(chat(tp->t_pos.y, tp->t_pos.x));
|
||||||
|
else if (seemonst)
|
||||||
|
{
|
||||||
|
standout();
|
||||||
|
addch(tp->t_type);
|
||||||
|
standend();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg("Everything looks SO boring now.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* visuals:
|
||||||
|
* change the characters for the player
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
visuals(void)
|
||||||
|
{
|
||||||
|
THING *tp;
|
||||||
|
int seemonst;
|
||||||
|
|
||||||
|
if (!after || (running && jump))
|
||||||
|
return;
|
||||||
|
/*
|
||||||
|
* change the things
|
||||||
|
*/
|
||||||
|
for (tp = lvl_obj; tp != NULL; tp = next(tp))
|
||||||
|
if (cansee(tp->o_pos.y, tp->o_pos.x))
|
||||||
|
mvaddch(tp->o_pos.y, tp->o_pos.x, rnd_thing());
|
||||||
|
|
||||||
|
/*
|
||||||
|
* change the stairs
|
||||||
|
*/
|
||||||
|
if (!seenstairs && cansee(stairs.y, stairs.x))
|
||||||
|
mvaddch(stairs.y, stairs.x, rnd_thing());
|
||||||
|
|
||||||
|
/*
|
||||||
|
* change the monsters
|
||||||
|
*/
|
||||||
|
seemonst = on(player, SEEMONST);
|
||||||
|
for (tp = mlist; tp != NULL; tp = next(tp))
|
||||||
|
{
|
||||||
|
move(tp->t_pos.y, tp->t_pos.x);
|
||||||
|
if (see_monst(tp))
|
||||||
|
{
|
||||||
|
if (tp->t_type == 'X' && tp->t_disguise != 'X')
|
||||||
|
addch(rnd_thing());
|
||||||
|
else
|
||||||
|
addch(rnd(26) + 'A');
|
||||||
|
}
|
||||||
|
else if (seemonst)
|
||||||
|
{
|
||||||
|
standout();
|
||||||
|
addch(rnd(26) + 'A');
|
||||||
|
standend();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* land:
|
||||||
|
* Land from a levitation potion
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
land(void)
|
||||||
|
{
|
||||||
|
player.t_flags &= ~ISLEVIT;
|
||||||
|
msg(choose_str("bummer! You've hit the ground",
|
||||||
|
"you float gently to the ground"));
|
||||||
|
}
|
||||||
406
rogue5/extern.c
Normal file
406
rogue5/extern.c
Normal file
|
|
@ -0,0 +1,406 @@
|
||||||
|
/*
|
||||||
|
* global variable initializaton
|
||||||
|
*
|
||||||
|
* @(#)extern.c 4.82 (Berkeley) 02/05/99
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* All global variables are defined here, or in vers.c or init.c */
|
||||||
|
|
||||||
|
#include <curses.h>
|
||||||
|
#include "rogue.h"
|
||||||
|
|
||||||
|
int after; /* True if we want after daemons */
|
||||||
|
int again; /* Repeating the last command */
|
||||||
|
int noscore; /* Was a wizard sometime */
|
||||||
|
int seenstairs; /* Have seen the stairs (for lsd) */
|
||||||
|
int amulet = FALSE; /* He found the amulet */
|
||||||
|
int door_stop = FALSE; /* Stop running when we pass a door */
|
||||||
|
int fight_flush = FALSE; /* True if toilet input */
|
||||||
|
int firstmove = FALSE; /* First move after setting door_stop */
|
||||||
|
int got_ltc = FALSE; /* We have gotten the local tty chars */
|
||||||
|
int has_hit = FALSE; /* Has a "hit" message pending in msg */
|
||||||
|
int in_shell = FALSE; /* True if executing a shell */
|
||||||
|
int inv_describe = TRUE; /* Say which way items are being used */
|
||||||
|
int jump = FALSE; /* Show running as series of jumps */
|
||||||
|
int kamikaze = FALSE; /* to_death really to DEATH */
|
||||||
|
int lower_msg = FALSE; /* Messages should start w/lower case */
|
||||||
|
int move_on = FALSE; /* Next move shouldn't pick up items */
|
||||||
|
int msg_esc = FALSE; /* Check for ESC from msg's --More-- */
|
||||||
|
int passgo = FALSE; /* Follow passages */
|
||||||
|
int playing = TRUE; /* True until he quits */
|
||||||
|
int q_comm = FALSE; /* Are we executing a 'Q' command? */
|
||||||
|
int running = FALSE; /* True if player is running */
|
||||||
|
int save_msg = TRUE; /* Remember last msg */
|
||||||
|
int see_floor = TRUE; /* Show the lamp illuminated floor */
|
||||||
|
int stat_msg = FALSE; /* Should status() print as a msg() */
|
||||||
|
int terse = FALSE; /* True if we should be short */
|
||||||
|
int to_death = FALSE; /* Fighting is to the death! */
|
||||||
|
int tombstone = TRUE; /* Print out tombstone at end */
|
||||||
|
#ifdef MASTER
|
||||||
|
int wizard = FALSE; /* True if allows wizard commands */
|
||||||
|
#endif
|
||||||
|
int pack_used[26] = { /* Is the character used in the pack? */
|
||||||
|
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
|
||||||
|
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
|
||||||
|
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE
|
||||||
|
};
|
||||||
|
|
||||||
|
int dir_ch; /* Direction from last get_dir() call */
|
||||||
|
char file_name[MAXSTR]; /* Save file name */
|
||||||
|
char huh[MAXSTR]; /* The last message printed */
|
||||||
|
const char *p_colors[MAXPOTIONS]; /* Colors of the potions */
|
||||||
|
char prbuf[2*MAXSTR]; /* buffer for sprintfs */
|
||||||
|
const char *r_stones[MAXRINGS]; /* Stone settings of the rings */
|
||||||
|
int runch; /* Direction player is running */
|
||||||
|
char *s_names[MAXSCROLLS]; /* Names of the scrolls */
|
||||||
|
int take; /* Thing she is taking */
|
||||||
|
char whoami[MAXSTR]; /* Name of player */
|
||||||
|
const char *ws_made[MAXSTICKS]; /* What sticks are made of */
|
||||||
|
char *ws_type[MAXSTICKS]; /* Is it a wand or a staff */
|
||||||
|
int orig_dsusp; /* Original dsusp char */
|
||||||
|
char fruit[MAXSTR] = /* Favorite fruit */
|
||||||
|
{ 's', 'l', 'i', 'm', 'e', '-', 'm', 'o', 'l', 'd', '\0' };
|
||||||
|
char home[MAXSTR] = { '\0' }; /* User's home directory */
|
||||||
|
const char *inv_t_name[] = {
|
||||||
|
"Overwrite",
|
||||||
|
"Slow",
|
||||||
|
"Clear"
|
||||||
|
};
|
||||||
|
int l_last_comm = '\0'; /* Last last_comm */
|
||||||
|
int l_last_dir = '\0'; /* Last last_dir */
|
||||||
|
int last_comm = '\0'; /* Last command typed */
|
||||||
|
int last_dir = '\0'; /* Last direction given */
|
||||||
|
const char *tr_name[] = { /* Names of the traps */
|
||||||
|
"a trapdoor",
|
||||||
|
"an arrow trap",
|
||||||
|
"a sleeping gas trap",
|
||||||
|
"a beartrap",
|
||||||
|
"a teleport trap",
|
||||||
|
"a poison dart trap",
|
||||||
|
"a rust trap",
|
||||||
|
"a mysterious trap"
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int n_objs; /* # items listed in inventory() call */
|
||||||
|
int ntraps; /* Number of traps on this level */
|
||||||
|
int hungry_state = 0; /* How hungry is he */
|
||||||
|
int inpack = 0; /* Number of things in pack */
|
||||||
|
int inv_type = 0; /* Type of inventory to use */
|
||||||
|
int level = 1; /* What level she is on */
|
||||||
|
int max_hit; /* Max damage done to her in to_death */
|
||||||
|
int max_level; /* Deepest player has gone */
|
||||||
|
int mpos = 0; /* Where cursor is on top line */
|
||||||
|
int no_food = 0; /* Number of levels without food */
|
||||||
|
const int a_class[MAXARMORS] = { /* Armor class for each armor type */
|
||||||
|
8, /* LEATHER */
|
||||||
|
7, /* RING_MAIL */
|
||||||
|
7, /* STUDDED_LEATHER */
|
||||||
|
6, /* SCALE_MAIL */
|
||||||
|
5, /* CHAIN_MAIL */
|
||||||
|
4, /* SPLINT_MAIL */
|
||||||
|
4, /* BANDED_MAIL */
|
||||||
|
3, /* PLATE_MAIL */
|
||||||
|
};
|
||||||
|
|
||||||
|
int count = 0; /* Number of times to repeat command */
|
||||||
|
FILE *scoreboard = NULL; /* File descriptor for score file */
|
||||||
|
int food_left; /* Amount of food in hero's stomach */
|
||||||
|
int lastscore = -1; /* Score before this turn */
|
||||||
|
int no_command = 0; /* Number of turns asleep */
|
||||||
|
int no_move = 0; /* Number of turns held in place */
|
||||||
|
int purse = 0; /* How much gold he has */
|
||||||
|
int quiet = 0; /* Number of quiet turns */
|
||||||
|
int vf_hit = 0; /* Number of time flytrap has hit */
|
||||||
|
|
||||||
|
unsigned int dnum; /* Dungeon number */
|
||||||
|
unsigned int seed; /* Random number seed */
|
||||||
|
const int e_levels[] = {
|
||||||
|
10L,
|
||||||
|
20L,
|
||||||
|
40L,
|
||||||
|
80L,
|
||||||
|
160L,
|
||||||
|
320L,
|
||||||
|
640L,
|
||||||
|
1300L,
|
||||||
|
2600L,
|
||||||
|
5200L,
|
||||||
|
13000L,
|
||||||
|
26000L,
|
||||||
|
50000L,
|
||||||
|
100000L,
|
||||||
|
200000L,
|
||||||
|
400000L,
|
||||||
|
800000L,
|
||||||
|
2000000L,
|
||||||
|
4000000L,
|
||||||
|
8000000L,
|
||||||
|
0L
|
||||||
|
};
|
||||||
|
|
||||||
|
coord delta; /* Change indicated to get_dir() */
|
||||||
|
coord oldpos; /* Position before last look() call */
|
||||||
|
coord stairs; /* Location of staircase */
|
||||||
|
|
||||||
|
PLACE places[MAXLINES*MAXCOLS]; /* level map */
|
||||||
|
|
||||||
|
THING *cur_armor; /* What he is wearing */
|
||||||
|
THING *cur_ring[2]; /* Which rings are being worn */
|
||||||
|
THING *cur_weapon; /* Which weapon he is weilding */
|
||||||
|
THING *l_last_pick = NULL; /* Last last_pick */
|
||||||
|
THING *last_pick = NULL; /* Last object picked in get_item() */
|
||||||
|
THING *lvl_obj = NULL; /* List of objects on this level */
|
||||||
|
THING *mlist = NULL; /* List of monsters on the level */
|
||||||
|
THING player; /* His stats */
|
||||||
|
/* restart of game */
|
||||||
|
|
||||||
|
WINDOW *hw = NULL; /* used as a scratch window */
|
||||||
|
|
||||||
|
#define INIT_STATS { 16, 0, 1, 10, 12, "1x4", 12 }
|
||||||
|
|
||||||
|
struct stats max_stats = INIT_STATS; /* The maximum for the player */
|
||||||
|
|
||||||
|
struct room *oldrp; /* Roomin(&oldpos) */
|
||||||
|
struct room rooms[MAXROOMS]; /* One for each room -- A level */
|
||||||
|
struct room passages[MAXPASS] = /* One for each passage */
|
||||||
|
{
|
||||||
|
{ {0, 0}, {0, 0}, {0, 0}, 0, ISGONE|ISDARK, 0, {{0,0}} },
|
||||||
|
{ {0, 0}, {0, 0}, {0, 0}, 0, ISGONE|ISDARK, 0, {{0,0}} },
|
||||||
|
{ {0, 0}, {0, 0}, {0, 0}, 0, ISGONE|ISDARK, 0, {{0,0}} },
|
||||||
|
{ {0, 0}, {0, 0}, {0, 0}, 0, ISGONE|ISDARK, 0, {{0,0}} },
|
||||||
|
{ {0, 0}, {0, 0}, {0, 0}, 0, ISGONE|ISDARK, 0, {{0,0}} },
|
||||||
|
{ {0, 0}, {0, 0}, {0, 0}, 0, ISGONE|ISDARK, 0, {{0,0}} },
|
||||||
|
{ {0, 0}, {0, 0}, {0, 0}, 0, ISGONE|ISDARK, 0, {{0,0}} },
|
||||||
|
{ {0, 0}, {0, 0}, {0, 0}, 0, ISGONE|ISDARK, 0, {{0,0}} },
|
||||||
|
{ {0, 0}, {0, 0}, {0, 0}, 0, ISGONE|ISDARK, 0, {{0,0}} },
|
||||||
|
{ {0, 0}, {0, 0}, {0, 0}, 0, ISGONE|ISDARK, 0, {{0,0}} },
|
||||||
|
{ {0, 0}, {0, 0}, {0, 0}, 0, ISGONE|ISDARK, 0, {{0,0}} },
|
||||||
|
{ {0, 0}, {0, 0}, {0, 0}, 0, ISGONE|ISDARK, 0, {{0,0}} }
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ___ 1
|
||||||
|
#define XX 10
|
||||||
|
struct monster monsters[26] =
|
||||||
|
{
|
||||||
|
/* Name CARRY FLAG str, exp, lvl, amr, hpt, dmg */
|
||||||
|
{ "aquator", 0, ISMEAN, { XX, 20, 5, 2, ___, "0x0/0x0" } },
|
||||||
|
{ "bat", 0, ISFLY, { XX, 1, 1, 3, ___, "1x2" } },
|
||||||
|
{ "centaur", 15, 0, { XX, 17, 4, 4, ___, "1x2/1x5/1x5" } },
|
||||||
|
{ "dragon", 100, ISMEAN, { XX,5000, 10, -1, ___, "1x8/1x8/3x10" } },
|
||||||
|
{ "emu", 0, ISMEAN, { XX, 2, 1, 7, ___, "1x2" } },
|
||||||
|
{ "venus flytrap", 0, ISMEAN, { XX, 80, 8, 3, ___, "%%%x0" } },
|
||||||
|
/* NOTE: the damage is %%% so that xstr won't merge this */
|
||||||
|
/* string with others, since it is written on in the program */
|
||||||
|
{ "griffin", 20, ISMEAN|ISFLY|ISREGEN, { XX,2000, 13, 2, ___, "4x3/3x5" } },
|
||||||
|
{ "hobgoblin", 0, ISMEAN, { XX, 3, 1, 5, ___, "1x8" } },
|
||||||
|
{ "ice monster", 0, 0, { XX, 5, 1, 9, ___, "0x0" } },
|
||||||
|
{ "jabberwock", 70, 0, { XX,3000, 15, 6, ___, "2x12/2x4" } },
|
||||||
|
{ "kestrel", 0, ISMEAN|ISFLY, { XX, 1, 1, 7, ___, "1x4" } },
|
||||||
|
{ "leprechaun", 0, 0, { XX, 10, 3, 8, ___, "1x1" } },
|
||||||
|
{ "medusa", 40, ISMEAN, { XX,200, 8, 2, ___, "3x4/3x4/2x5" } },
|
||||||
|
{ "nymph", 100, 0, { XX, 37, 3, 9, ___, "0x0" } },
|
||||||
|
{ "orc", 15, ISGREED,{ XX, 5, 1, 6, ___, "1x8" } },
|
||||||
|
{ "phantom", 0, ISINVIS,{ XX,120, 8, 3, ___, "4x4" } },
|
||||||
|
{ "quagga", 0, ISMEAN, { XX, 15, 3, 3, ___, "1x5/1x5" } },
|
||||||
|
{ "rattlesnake", 0, ISMEAN, { XX, 9, 2, 3, ___, "1x6" } },
|
||||||
|
{ "snake", 0, ISMEAN, { XX, 2, 1, 5, ___, "1x3" } },
|
||||||
|
{ "troll", 50, ISREGEN|ISMEAN,{ XX, 120, 6, 4, ___, "1x8/1x8/2x6" } },
|
||||||
|
{ "black unicorn", 0, ISMEAN, { XX,190, 7, -2, ___, "1x9/1x9/2x9" } },
|
||||||
|
{ "vampire", 20, ISREGEN|ISMEAN,{ XX,350, 8, 1, ___, "1x10" } },
|
||||||
|
{ "wraith", 0, 0, { XX, 55, 5, 4, ___, "1x6" } },
|
||||||
|
{ "xeroc", 30, 0, { XX,100, 7, 7, ___, "4x4" } },
|
||||||
|
{ "yeti", 30, 0, { XX, 50, 4, 6, ___, "1x6/1x6" } },
|
||||||
|
{ "zombie", 0, ISMEAN, { XX, 6, 2, 8, ___, "1x8" } }
|
||||||
|
};
|
||||||
|
#undef ___
|
||||||
|
#undef XX
|
||||||
|
|
||||||
|
struct obj_info things[NUMTHINGS] = {
|
||||||
|
{ 0, 26 }, /* potion */
|
||||||
|
{ 0, 36 }, /* scroll */
|
||||||
|
{ 0, 16 }, /* food */
|
||||||
|
{ 0, 7 }, /* weapon */
|
||||||
|
{ 0, 7 }, /* armor */
|
||||||
|
{ 0, 4 }, /* ring */
|
||||||
|
{ 0, 4 }, /* stick */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct obj_info arm_info[MAXARMORS] = {
|
||||||
|
{ "leather armor", 20, 20, NULL, FALSE },
|
||||||
|
{ "ring mail", 15, 25, NULL, FALSE },
|
||||||
|
{ "studded leather armor", 15, 20, NULL, FALSE },
|
||||||
|
{ "scale mail", 13, 30, NULL, FALSE },
|
||||||
|
{ "chain mail", 12, 75, NULL, FALSE },
|
||||||
|
{ "splint mail", 10, 80, NULL, FALSE },
|
||||||
|
{ "banded mail", 10, 90, NULL, FALSE },
|
||||||
|
{ "plate mail", 5, 150, NULL, FALSE },
|
||||||
|
};
|
||||||
|
struct obj_info pot_info[MAXPOTIONS] = {
|
||||||
|
{ "confusion", 7, 5, NULL, FALSE },
|
||||||
|
{ "hallucination", 8, 5, NULL, FALSE },
|
||||||
|
{ "poison", 8, 5, NULL, FALSE },
|
||||||
|
{ "gain strength", 13, 150, NULL, FALSE },
|
||||||
|
{ "see invisible", 3, 100, NULL, FALSE },
|
||||||
|
{ "healing", 13, 130, NULL, FALSE },
|
||||||
|
{ "monster detection", 6, 130, NULL, FALSE },
|
||||||
|
{ "magic detection", 6, 105, NULL, FALSE },
|
||||||
|
{ "raise level", 2, 250, NULL, FALSE },
|
||||||
|
{ "extra healing", 5, 200, NULL, FALSE },
|
||||||
|
{ "haste self", 5, 190, NULL, FALSE },
|
||||||
|
{ "restore strength", 13, 130, NULL, FALSE },
|
||||||
|
{ "blindness", 5, 5, NULL, FALSE },
|
||||||
|
{ "levitation", 6, 75, NULL, FALSE },
|
||||||
|
};
|
||||||
|
struct obj_info ring_info[MAXRINGS] = {
|
||||||
|
{ "protection", 9, 400, NULL, FALSE },
|
||||||
|
{ "add strength", 9, 400, NULL, FALSE },
|
||||||
|
{ "sustain strength", 5, 280, NULL, FALSE },
|
||||||
|
{ "searching", 10, 420, NULL, FALSE },
|
||||||
|
{ "see invisible", 10, 310, NULL, FALSE },
|
||||||
|
{ "adornment", 1, 10, NULL, FALSE },
|
||||||
|
{ "aggravate monster", 10, 10, NULL, FALSE },
|
||||||
|
{ "dexterity", 8, 440, NULL, FALSE },
|
||||||
|
{ "increase damage", 8, 400, NULL, FALSE },
|
||||||
|
{ "regeneration", 4, 460, NULL, FALSE },
|
||||||
|
{ "slow digestion", 9, 240, NULL, FALSE },
|
||||||
|
{ "teleportation", 5, 30, NULL, FALSE },
|
||||||
|
{ "stealth", 7, 470, NULL, FALSE },
|
||||||
|
{ "maintain armor", 5, 380, NULL, FALSE },
|
||||||
|
};
|
||||||
|
struct obj_info scr_info[MAXSCROLLS] = {
|
||||||
|
{ "monster confusion", 7, 140, NULL, FALSE },
|
||||||
|
{ "magic mapping", 4, 150, NULL, FALSE },
|
||||||
|
{ "hold monster", 2, 180, NULL, FALSE },
|
||||||
|
{ "sleep", 3, 5, NULL, FALSE },
|
||||||
|
{ "enchant armor", 7, 160, NULL, FALSE },
|
||||||
|
{ "identify potion", 10, 80, NULL, FALSE },
|
||||||
|
{ "identify scroll", 10, 80, NULL, FALSE },
|
||||||
|
{ "identify weapon", 6, 80, NULL, FALSE },
|
||||||
|
{ "identify armor", 7, 100, NULL, FALSE },
|
||||||
|
{ "identify ring, wand or staff", 10, 115, NULL, FALSE },
|
||||||
|
{ "scare monster", 3, 200, NULL, FALSE },
|
||||||
|
{ "food detection", 2, 60, NULL, FALSE },
|
||||||
|
{ "teleportation", 5, 165, NULL, FALSE },
|
||||||
|
{ "enchant weapon", 8, 150, NULL, FALSE },
|
||||||
|
{ "create monster", 4, 75, NULL, FALSE },
|
||||||
|
{ "remove curse", 7, 105, NULL, FALSE },
|
||||||
|
{ "aggravate monsters", 3, 20, NULL, FALSE },
|
||||||
|
{ "protect armor", 2, 250, NULL, FALSE },
|
||||||
|
};
|
||||||
|
struct obj_info weap_info[MAXWEAPONS + 1] = {
|
||||||
|
{ "mace", 11, 8, NULL, FALSE },
|
||||||
|
{ "long sword", 11, 15, NULL, FALSE },
|
||||||
|
{ "short bow", 12, 15, NULL, FALSE },
|
||||||
|
{ "arrow", 12, 1, NULL, FALSE },
|
||||||
|
{ "dagger", 8, 3, NULL, FALSE },
|
||||||
|
{ "two handed sword", 10, 75, NULL, FALSE },
|
||||||
|
{ "dart", 12, 2, NULL, FALSE },
|
||||||
|
{ "shuriken", 12, 5, NULL, FALSE },
|
||||||
|
{ "spear", 12, 5, NULL, FALSE },
|
||||||
|
{ NULL, 0 }, /* DO NOT REMOVE: fake entry for dragon's breath */
|
||||||
|
};
|
||||||
|
struct obj_info ws_info[MAXSTICKS] = {
|
||||||
|
{ "light", 12, 250, NULL, FALSE },
|
||||||
|
{ "invisibility", 6, 5, NULL, FALSE },
|
||||||
|
{ "lightning", 3, 330, NULL, FALSE },
|
||||||
|
{ "fire", 3, 330, NULL, FALSE },
|
||||||
|
{ "cold", 3, 330, NULL, FALSE },
|
||||||
|
{ "polymorph", 15, 310, NULL, FALSE },
|
||||||
|
{ "magic missile", 10, 170, NULL, FALSE },
|
||||||
|
{ "haste monster", 10, 5, NULL, FALSE },
|
||||||
|
{ "slow monster", 11, 350, NULL, FALSE },
|
||||||
|
{ "drain life", 9, 300, NULL, FALSE },
|
||||||
|
{ "nothing", 1, 5, NULL, FALSE },
|
||||||
|
{ "teleport away", 6, 340, NULL, FALSE },
|
||||||
|
{ "teleport to", 6, 50, NULL, FALSE },
|
||||||
|
{ "cancellation", 5, 280, NULL, FALSE },
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct h_list helpstr[] = {
|
||||||
|
{'?', " prints help", TRUE},
|
||||||
|
{'/', " identify object", TRUE},
|
||||||
|
{'h', " left", TRUE},
|
||||||
|
{'j', " down", TRUE},
|
||||||
|
{'k', " up", TRUE},
|
||||||
|
{'l', " right", TRUE},
|
||||||
|
{'y', " up & left", TRUE},
|
||||||
|
{'u', " up & right", TRUE},
|
||||||
|
{'b', " down & left", TRUE},
|
||||||
|
{'n', " down & right", TRUE},
|
||||||
|
{'H', " run left", FALSE},
|
||||||
|
{'J', " run down", FALSE},
|
||||||
|
{'K', " run up", FALSE},
|
||||||
|
{'L', " run right", FALSE},
|
||||||
|
{'Y', " run up & left", FALSE},
|
||||||
|
{'U', " run up & right", FALSE},
|
||||||
|
{'B', " run down & left", FALSE},
|
||||||
|
{'N', " run down & right", FALSE},
|
||||||
|
{CTRL('H'), " run left until adjacent", FALSE},
|
||||||
|
{CTRL('J'), " run down until adjacent", FALSE},
|
||||||
|
{CTRL('K'), " run up until adjacent", FALSE},
|
||||||
|
{CTRL('L'), " run right until adjacent", FALSE},
|
||||||
|
{CTRL('Y'), " run up & left until adjacent", FALSE},
|
||||||
|
{CTRL('U'), " run up & right until adjacent", FALSE},
|
||||||
|
{CTRL('B'), " run down & left until adjacent", FALSE},
|
||||||
|
{CTRL('N'), " run down & right until adjacent", FALSE},
|
||||||
|
{'\0', " <SHIFT><dir>: run that way", TRUE},
|
||||||
|
{'\0', " <CTRL><dir>: run till adjacent", TRUE},
|
||||||
|
{'f', "<dir> fight till death or near death", TRUE},
|
||||||
|
{'t', "<dir> throw something", TRUE},
|
||||||
|
{'m', "<dir> move onto without picking up", TRUE},
|
||||||
|
{'z', "<dir> zap a wand in a direction", TRUE},
|
||||||
|
{'^', "<dir> identify trap type", TRUE},
|
||||||
|
{'s', " search for trap/secret door", TRUE},
|
||||||
|
{'>', " go down a staircase", TRUE},
|
||||||
|
{'<', " go up a staircase", TRUE},
|
||||||
|
{'.', " rest for a turn", TRUE},
|
||||||
|
{',', " pick something up", TRUE},
|
||||||
|
{'i', " inventory", TRUE},
|
||||||
|
{'I', " inventory single item", TRUE},
|
||||||
|
{'q', " quaff potion", TRUE},
|
||||||
|
{'r', " read scroll", TRUE},
|
||||||
|
{'e', " eat food", TRUE},
|
||||||
|
{'w', " wield a weapon", TRUE},
|
||||||
|
{'W', " wear armor", TRUE},
|
||||||
|
{'T', " take armor off", TRUE},
|
||||||
|
{'P', " put on ring", TRUE},
|
||||||
|
{'R', " remove ring", TRUE},
|
||||||
|
{'d', " drop object", TRUE},
|
||||||
|
{'c', " call object", TRUE},
|
||||||
|
{'a', " repeat last command", TRUE},
|
||||||
|
{')', " print current weapon", TRUE},
|
||||||
|
{']', " print current armor", TRUE},
|
||||||
|
{'=', " print current rings", TRUE},
|
||||||
|
{'@', " print current stats", TRUE},
|
||||||
|
{'D', " recall what's been discovered", TRUE},
|
||||||
|
{'o', " examine/set options", TRUE},
|
||||||
|
{CTRL('R'), " redraw screen", TRUE},
|
||||||
|
{CTRL('P'), " repeat last message", TRUE},
|
||||||
|
{ESCAPE, " cancel command", TRUE},
|
||||||
|
{'S', " save game", TRUE},
|
||||||
|
{'Q', " quit", TRUE},
|
||||||
|
{'!', " shell escape", TRUE},
|
||||||
|
{'F', "<dir> fight till either of you dies", TRUE},
|
||||||
|
{'v', " print version number", TRUE},
|
||||||
|
{0, NULL }
|
||||||
|
};
|
||||||
|
int numscores;
|
||||||
|
char *Numname;
|
||||||
|
int allscore;
|
||||||
|
int between;
|
||||||
|
|
||||||
|
#define _X_ { EMPTY }
|
||||||
|
|
||||||
|
struct delayed_action d_list[MAXDAEMONS] = {
|
||||||
|
_X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_,
|
||||||
|
_X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_,
|
||||||
|
};
|
||||||
|
|
||||||
|
int group = 2;
|
||||||
170
rogue5/extern.h
Normal file
170
rogue5/extern.h
Normal file
|
|
@ -0,0 +1,170 @@
|
||||||
|
/*
|
||||||
|
* Defines for things used in mach_dep.c
|
||||||
|
*
|
||||||
|
* @(#)extern.h 4.35 (Berkeley) 02/05/99
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#ifdef PDCURSES
|
||||||
|
#undef HAVE_UNISTD_H
|
||||||
|
#undef HAVE_LIMITS_H
|
||||||
|
#undef HAVE_MEMORY_H
|
||||||
|
#undef HAVE_STRING_H
|
||||||
|
#endif
|
||||||
|
#include "config.h"
|
||||||
|
#elif defined(__DJGPP__)
|
||||||
|
#define HAVE_SYS_TYPES_H 1
|
||||||
|
#define HAVE_PROCESS_H 1
|
||||||
|
#define HAVE_PWD_H 1
|
||||||
|
#define HAVE_TERMIOS_H 1
|
||||||
|
#define HAVE_SETGID 1
|
||||||
|
#define HAVE_GETGID 1
|
||||||
|
#define HAVE_SETUID 1
|
||||||
|
#define HAVE_GETUID 1
|
||||||
|
#define HAVE_GETPASS 1
|
||||||
|
#define HAVE_SPAWNL 1
|
||||||
|
#define HAVE_ALARM 1
|
||||||
|
#define HAVE_ERASECHAR 1
|
||||||
|
#define HAVE_KILLCHAR 1
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
#define HAVE_CURSES_H
|
||||||
|
#define HAVE_TERM_H
|
||||||
|
#define HAVE__SPAWNL
|
||||||
|
#define HAVE_SYS_TYPES_H
|
||||||
|
#define HAVE_PROCESS_H
|
||||||
|
#define HAVE_ERASECHAR 1
|
||||||
|
#define HAVE_KILLCHAR 1
|
||||||
|
#ifndef uid_t
|
||||||
|
typedef unsigned int uid_t;
|
||||||
|
#endif
|
||||||
|
#ifndef pid_t
|
||||||
|
typedef unsigned int pid_t;
|
||||||
|
#endif
|
||||||
|
#elif defined(__CYGWIN__)
|
||||||
|
#define HAVE_SYS_TYPES_H 1
|
||||||
|
#define HAVE_PWD_H 1
|
||||||
|
#define HAVE_PWD_H 1
|
||||||
|
#define HAVE_SYS_UTSNAME_H 1
|
||||||
|
#define HAVE_ARPA_INET_H 1
|
||||||
|
#define HAVE_UNISTD_H 1
|
||||||
|
#define HAVE_TERMIOS_H 1
|
||||||
|
#define HAVE_NCURSES_TERM_H 1
|
||||||
|
#define HAVE_ESCDELAY
|
||||||
|
#define HAVE_SETGID 1
|
||||||
|
#define HAVE_GETGID 1
|
||||||
|
#define HAVE_SETUID 1
|
||||||
|
#define HAVE_GETUID 1
|
||||||
|
#define HAVE_GETPASS 1
|
||||||
|
#define HAVE_GETPWUID 1
|
||||||
|
#define HAVE_WORKING_FORK 1
|
||||||
|
#define HAVE_ALARM 1
|
||||||
|
#define HAVE_SPAWNL 1
|
||||||
|
#define HAVE__SPAWNL 1
|
||||||
|
#define HAVE_ERASECHAR 1
|
||||||
|
#define HAVE_KILLCHAR 1
|
||||||
|
#else /* POSIX */
|
||||||
|
#define HAVE_SYS_TYPES_H 1
|
||||||
|
#define HAVE_PWD_H 1
|
||||||
|
#define HAVE_PWD_H 1
|
||||||
|
#define HAVE_SYS_UTSNAME_H 1
|
||||||
|
#define HAVE_ARPA_INET_H 1
|
||||||
|
#define HAVE_UNISTD_H 1
|
||||||
|
#define HAVE_TERMIOS_H 1
|
||||||
|
#define HAVE_TERM_H 1
|
||||||
|
#define HAVE_SETGID 1
|
||||||
|
#define HAVE_GETGID 1
|
||||||
|
#define HAVE_SETUID 1
|
||||||
|
#define HAVE_GETUID 1
|
||||||
|
#define HAVE_SETREUID 1
|
||||||
|
#define HAVE_SETREGID 1
|
||||||
|
#define HAVE_GETPASS 1
|
||||||
|
#define HAVE_GETPWUID 1
|
||||||
|
#define HAVE_WORKING_FORK 1
|
||||||
|
#define HAVE_ERASECHAR 1
|
||||||
|
#define HAVE_KILLCHAR 1
|
||||||
|
#ifndef _AIX
|
||||||
|
#define HAVE_GETLOADAVG 1
|
||||||
|
#endif
|
||||||
|
#define HAVE_ALARM 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __DJGPP__
|
||||||
|
#undef HAVE_GETPWUID /* DJGPP's limited version doesn't even work as documented */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Don't change the constants, since they are used for sizes in many
|
||||||
|
* places in the program.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#undef SIGTSTP
|
||||||
|
|
||||||
|
#define MAXSTR 1024 /* maximum length of strings */
|
||||||
|
#define MAXLINES 32 /* maximum number of screen lines used */
|
||||||
|
#define MAXCOLS 80 /* maximum number of screen columns used */
|
||||||
|
|
||||||
|
#define RN (((seed = seed*11109+13849) >> 16) & 0xffff)
|
||||||
|
#ifdef CTRL
|
||||||
|
#undef CTRL
|
||||||
|
#endif
|
||||||
|
#define CTRL(c) (c & 037)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now all the global variables
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern int got_ltc, in_shell;
|
||||||
|
extern int wizard;
|
||||||
|
extern char fruit[], prbuf[], whoami[];
|
||||||
|
extern int orig_dsusp;
|
||||||
|
extern FILE *scoreboard;
|
||||||
|
extern int numscores;
|
||||||
|
extern char *Numname;
|
||||||
|
extern int allscore;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function types
|
||||||
|
*/
|
||||||
|
|
||||||
|
int md_chmod(const char *filename, int mode);
|
||||||
|
char *md_crypt(const char *key, const char *salt);
|
||||||
|
int md_dsuspchar(void);
|
||||||
|
int md_erasechar(void);
|
||||||
|
char *md_gethomedir(void);
|
||||||
|
char *md_getusername(void);
|
||||||
|
uid_t md_getuid(void);
|
||||||
|
char *md_getpass(char *prompt);
|
||||||
|
pid_t md_getpid(void);
|
||||||
|
char *md_getrealname(uid_t uid);
|
||||||
|
void md_init(void);
|
||||||
|
int md_killchar(void);
|
||||||
|
void md_normaluser(void);
|
||||||
|
void md_raw_standout(void);
|
||||||
|
void md_raw_standend(void);
|
||||||
|
int md_readchar(WINDOW *win);
|
||||||
|
int md_setdsuspchar(int c);
|
||||||
|
int md_shellescape(void);
|
||||||
|
void md_sleep(int s);
|
||||||
|
int md_suspchar(void);
|
||||||
|
int md_hasclreol(void);
|
||||||
|
int md_unlink(char *file);
|
||||||
|
int md_unlink_open_file(const char *file, FILE *inf);
|
||||||
|
void md_tstpsignal(void);
|
||||||
|
void md_tstphold(void);
|
||||||
|
void md_tstpresume(void);
|
||||||
|
void md_ignoreallsignals(void);
|
||||||
|
void md_onsignal_autosave(void);
|
||||||
|
void md_onsignal_exit(void);
|
||||||
|
void md_onsignal_default(void);
|
||||||
|
int md_issymlink(char *sp);
|
||||||
|
extern char *xcrypt(const char *key, const char *setting);
|
||||||
|
|
||||||
687
rogue5/fight.c
Normal file
687
rogue5/fight.c
Normal file
|
|
@ -0,0 +1,687 @@
|
||||||
|
/*
|
||||||
|
* All the fighting gets done here
|
||||||
|
*
|
||||||
|
* @(#)fight.c 4.67 (Berkeley) 09/06/83
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <curses.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "rogue.h"
|
||||||
|
|
||||||
|
#define EQSTR(a, b) (strcmp(a, b) == 0)
|
||||||
|
|
||||||
|
static const char *h_names[] = { /* strings for hitting */
|
||||||
|
" scored an excellent hit on ",
|
||||||
|
" hit ",
|
||||||
|
" have injured ",
|
||||||
|
" swing and hit ",
|
||||||
|
" scored an excellent hit on ",
|
||||||
|
" hit ",
|
||||||
|
" has injured ",
|
||||||
|
" swings and hits "
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *m_names[] = { /* strings for missing */
|
||||||
|
" miss",
|
||||||
|
" swing and miss",
|
||||||
|
" barely miss",
|
||||||
|
" don't hit",
|
||||||
|
" misses",
|
||||||
|
" swings and misses",
|
||||||
|
" barely misses",
|
||||||
|
" doesn't hit",
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* adjustments to hit probabilities due to strength
|
||||||
|
*/
|
||||||
|
static int str_plus[] = {
|
||||||
|
-7, -6, -5, -4, -3, -2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
|
||||||
|
1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* adjustments to damage done due to strength
|
||||||
|
*/
|
||||||
|
static int add_dam[] = {
|
||||||
|
-7, -6, -5, -4, -3, -2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3,
|
||||||
|
3, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fight:
|
||||||
|
* The player attacks the monster.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
fight(const coord *mp, const THING *weap, int thrown)
|
||||||
|
{
|
||||||
|
THING *tp;
|
||||||
|
int did_hit = TRUE;
|
||||||
|
const char *mname;
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the monster we want to fight
|
||||||
|
*/
|
||||||
|
if ((tp = moat(mp->y, mp->x)) == NULL)
|
||||||
|
{
|
||||||
|
#ifdef MASTER
|
||||||
|
debug("Fight what @ %d,%d", mp->y, mp->x);
|
||||||
|
#endif
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Since we are fighting, things are not quiet so no healing takes
|
||||||
|
* place.
|
||||||
|
*/
|
||||||
|
count = 0;
|
||||||
|
quiet = 0;
|
||||||
|
runto(mp);
|
||||||
|
/*
|
||||||
|
* Let him know it was really a xeroc (if it was one).
|
||||||
|
*/
|
||||||
|
ch = '\0';
|
||||||
|
if (tp->t_type == 'X' && tp->t_disguise != 'X' && !on(player, ISBLIND))
|
||||||
|
{
|
||||||
|
tp->t_disguise = 'X';
|
||||||
|
if (on(player, ISHALU)) {
|
||||||
|
ch = rnd(26) + 'A';
|
||||||
|
mvaddch(tp->t_pos.y, tp->t_pos.x, ch);
|
||||||
|
}
|
||||||
|
msg(choose_str("heavy! That's a nasty critter!",
|
||||||
|
"wait! That's a xeroc!"));
|
||||||
|
if (!thrown)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
mname = set_mname(tp);
|
||||||
|
did_hit = FALSE;
|
||||||
|
has_hit = (terse && !to_death);
|
||||||
|
if (roll_em(&player, tp, weap, thrown))
|
||||||
|
{
|
||||||
|
did_hit = FALSE;
|
||||||
|
if (thrown)
|
||||||
|
thunk(weap, mname, terse);
|
||||||
|
else
|
||||||
|
hit(NULL, mname, terse);
|
||||||
|
if (on(player, CANHUH))
|
||||||
|
{
|
||||||
|
did_hit = TRUE;
|
||||||
|
tp->t_flags |= ISHUH;
|
||||||
|
player.t_flags &= ~CANHUH;
|
||||||
|
endmsg();
|
||||||
|
has_hit = FALSE;
|
||||||
|
msg("your hands stop glowing %s", pick_color("red"));
|
||||||
|
}
|
||||||
|
if (tp->t_stats.s_hpt <= 0)
|
||||||
|
killed(tp, TRUE);
|
||||||
|
else if (did_hit && !on(player, ISBLIND))
|
||||||
|
msg("%s appears confused", mname);
|
||||||
|
did_hit = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (thrown)
|
||||||
|
bounce(weap, mname, terse);
|
||||||
|
else
|
||||||
|
miss(NULL, mname, terse);
|
||||||
|
return did_hit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* attack:
|
||||||
|
* The monster attacks the player
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
attack(THING *mp)
|
||||||
|
{
|
||||||
|
const char *mname;
|
||||||
|
int oldhp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since this is an attack, stop running and any healing that was
|
||||||
|
* going on at the time.
|
||||||
|
*/
|
||||||
|
running = FALSE;
|
||||||
|
count = 0;
|
||||||
|
quiet = 0;
|
||||||
|
if (to_death && !on(*mp, ISTARGET))
|
||||||
|
{
|
||||||
|
to_death = FALSE;
|
||||||
|
kamikaze = FALSE;
|
||||||
|
}
|
||||||
|
if (mp->t_type == 'X' && mp->t_disguise != 'X' && !on(player, ISBLIND))
|
||||||
|
{
|
||||||
|
mp->t_disguise = 'X';
|
||||||
|
if (on(player, ISHALU))
|
||||||
|
mvaddch(mp->t_pos.y, mp->t_pos.x, rnd(26) + 'A');
|
||||||
|
}
|
||||||
|
mname = set_mname(mp);
|
||||||
|
oldhp = pstats.s_hpt;
|
||||||
|
if (roll_em(mp, &player, NULL, FALSE))
|
||||||
|
{
|
||||||
|
if (mp->t_type != 'I')
|
||||||
|
{
|
||||||
|
if (has_hit)
|
||||||
|
addmsg(". ");
|
||||||
|
hit(mname, NULL, FALSE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (has_hit)
|
||||||
|
endmsg();
|
||||||
|
has_hit = FALSE;
|
||||||
|
if (pstats.s_hpt <= 0)
|
||||||
|
death(mp->t_type); /* Bye bye life ... */
|
||||||
|
else if (!kamikaze)
|
||||||
|
{
|
||||||
|
oldhp -= pstats.s_hpt;
|
||||||
|
if (oldhp > max_hit)
|
||||||
|
max_hit = oldhp;
|
||||||
|
if (pstats.s_hpt <= max_hit)
|
||||||
|
to_death = FALSE;
|
||||||
|
}
|
||||||
|
if (!on(*mp, ISCANC))
|
||||||
|
switch (mp->t_type)
|
||||||
|
{
|
||||||
|
case 'A':
|
||||||
|
/*
|
||||||
|
* If an aquator hits, you can lose armor class.
|
||||||
|
*/
|
||||||
|
rust_armor(cur_armor);
|
||||||
|
when 'I':
|
||||||
|
/*
|
||||||
|
* The ice monster freezes you
|
||||||
|
*/
|
||||||
|
player.t_flags &= ~ISRUN;
|
||||||
|
if (!no_command)
|
||||||
|
{
|
||||||
|
addmsg("you are frozen");
|
||||||
|
if (!terse)
|
||||||
|
addmsg(" by the %s", mname);
|
||||||
|
endmsg();
|
||||||
|
}
|
||||||
|
no_command += rnd(2) + 2;
|
||||||
|
if (no_command > BORE_LEVEL)
|
||||||
|
death('h');
|
||||||
|
when 'R':
|
||||||
|
/*
|
||||||
|
* Rattlesnakes have poisonous bites
|
||||||
|
*/
|
||||||
|
if (!save(VS_POISON))
|
||||||
|
{
|
||||||
|
if (!ISWEARING(R_SUSTSTR))
|
||||||
|
{
|
||||||
|
chg_str(-1);
|
||||||
|
if (!terse)
|
||||||
|
msg("you feel a bite in your leg and now feel weaker");
|
||||||
|
else
|
||||||
|
msg("a bite has weakened you");
|
||||||
|
}
|
||||||
|
else if (!to_death)
|
||||||
|
{
|
||||||
|
if (!terse)
|
||||||
|
msg("a bite momentarily weakens you");
|
||||||
|
else
|
||||||
|
msg("bite has no effect");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
when 'W':
|
||||||
|
case 'V':
|
||||||
|
/*
|
||||||
|
* Wraiths might drain energy levels, and Vampires
|
||||||
|
* can steal max_hp
|
||||||
|
*/
|
||||||
|
if (rnd(100) < (mp->t_type == 'W' ? 15 : 30))
|
||||||
|
{
|
||||||
|
int fewer;
|
||||||
|
|
||||||
|
if (mp->t_type == 'W')
|
||||||
|
{
|
||||||
|
if (pstats.s_exp == 0)
|
||||||
|
death('W'); /* All levels gone */
|
||||||
|
if (--pstats.s_lvl == 0)
|
||||||
|
{
|
||||||
|
pstats.s_exp = 0;
|
||||||
|
pstats.s_lvl = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pstats.s_exp = e_levels[pstats.s_lvl-1]+1;
|
||||||
|
fewer = roll(1, 10);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fewer = roll(1, 3);
|
||||||
|
pstats.s_hpt -= fewer;
|
||||||
|
max_hp -= fewer;
|
||||||
|
if (pstats.s_hpt <= 0)
|
||||||
|
pstats.s_hpt = 1;
|
||||||
|
if (max_hp <= 0)
|
||||||
|
death(mp->t_type);
|
||||||
|
msg("you suddenly feel weaker");
|
||||||
|
}
|
||||||
|
when 'F':
|
||||||
|
/*
|
||||||
|
* Venus Flytrap stops the poor guy from moving
|
||||||
|
*/
|
||||||
|
player.t_flags |= ISHELD;
|
||||||
|
sprintf(monsters['F'-'A'].m_stats.s_dmg,"%dx1", ++vf_hit);
|
||||||
|
if (--pstats.s_hpt <= 0)
|
||||||
|
death('F');
|
||||||
|
when 'L':
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Leperachaun steals some gold
|
||||||
|
*/
|
||||||
|
int lastpurse;
|
||||||
|
|
||||||
|
lastpurse = purse;
|
||||||
|
purse -= GOLDCALC;
|
||||||
|
if (!save(VS_MAGIC))
|
||||||
|
purse -= GOLDCALC + GOLDCALC + GOLDCALC + GOLDCALC;
|
||||||
|
if (purse < 0)
|
||||||
|
purse = 0;
|
||||||
|
remove_mon(&mp->t_pos, mp, FALSE);
|
||||||
|
mp=NULL;
|
||||||
|
if (purse != lastpurse)
|
||||||
|
msg("your purse feels lighter");
|
||||||
|
}
|
||||||
|
when 'N':
|
||||||
|
{
|
||||||
|
THING *obj, *steal;
|
||||||
|
int nobj;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Nymph's steal a magic item, look through the pack
|
||||||
|
* and pick out one we like.
|
||||||
|
*/
|
||||||
|
steal = NULL;
|
||||||
|
for (nobj = 0, obj = pack; obj != NULL; obj = next(obj))
|
||||||
|
if (obj != cur_armor && obj != cur_weapon
|
||||||
|
&& obj != cur_ring[LEFT] && obj != cur_ring[RIGHT]
|
||||||
|
&& is_magic(obj) && rnd(++nobj) == 0)
|
||||||
|
steal = obj;
|
||||||
|
if (steal != NULL)
|
||||||
|
{
|
||||||
|
remove_mon(&mp->t_pos, moat(mp->t_pos.y, mp->t_pos.x), FALSE);
|
||||||
|
mp=NULL;
|
||||||
|
steal = leave_pack(steal, TRUE, FALSE);
|
||||||
|
msg("she stole %s!", inv_name(steal, TRUE));
|
||||||
|
discard(steal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
otherwise:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mp->t_type != 'I')
|
||||||
|
{
|
||||||
|
if (has_hit)
|
||||||
|
{
|
||||||
|
addmsg(". ");
|
||||||
|
has_hit = FALSE;
|
||||||
|
}
|
||||||
|
if (mp->t_type == 'F')
|
||||||
|
{
|
||||||
|
pstats.s_hpt -= vf_hit;
|
||||||
|
if (pstats.s_hpt <= 0)
|
||||||
|
death(mp->t_type); /* Bye bye life ... */
|
||||||
|
}
|
||||||
|
miss(mname, NULL, FALSE);
|
||||||
|
}
|
||||||
|
if (fight_flush && !to_death)
|
||||||
|
flush_type();
|
||||||
|
count = 0;
|
||||||
|
status();
|
||||||
|
if (mp == NULL)
|
||||||
|
return(-1);
|
||||||
|
else
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* set_mname:
|
||||||
|
* return the monster name for the given monster
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
set_mname(const THING *tp)
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
const char *mname;
|
||||||
|
static char tbuf[MAXSTR] = { 't', 'h', 'e', ' ' };
|
||||||
|
|
||||||
|
if (!see_monst(tp) && !on(player, SEEMONST))
|
||||||
|
return (terse ? "it" : "something");
|
||||||
|
else if (on(player, ISHALU))
|
||||||
|
{
|
||||||
|
move(tp->t_pos.y, tp->t_pos.x);
|
||||||
|
ch = toascii(CCHAR(inch()));
|
||||||
|
if (!isupper(ch))
|
||||||
|
ch = rnd(26);
|
||||||
|
else
|
||||||
|
ch -= 'A';
|
||||||
|
mname = monsters[ch].m_name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mname = monsters[tp->t_type - 'A'].m_name;
|
||||||
|
strcpy(&tbuf[4], mname);
|
||||||
|
return tbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* swing:
|
||||||
|
* Returns true if the swing hits
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
swing(int at_lvl, int op_arm, int wplus)
|
||||||
|
{
|
||||||
|
int res = rnd(20);
|
||||||
|
int need = (20 - at_lvl) - op_arm;
|
||||||
|
|
||||||
|
return (res + wplus >= need);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* roll_em:
|
||||||
|
* Roll several attacks
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
roll_em(const THING *thatt, THING *thdef, const THING *weap, int hurl)
|
||||||
|
{
|
||||||
|
const struct stats *att;
|
||||||
|
struct stats *def;
|
||||||
|
const char *cp;
|
||||||
|
int ndice, nsides, def_arm;
|
||||||
|
int did_hit = FALSE;
|
||||||
|
int hplus;
|
||||||
|
int dplus;
|
||||||
|
int damage;
|
||||||
|
|
||||||
|
att = &thatt->t_stats;
|
||||||
|
def = &thdef->t_stats;
|
||||||
|
if (weap == NULL)
|
||||||
|
{
|
||||||
|
cp = att->s_dmg;
|
||||||
|
dplus = 0;
|
||||||
|
hplus = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hplus = (weap == NULL ? 0 : weap->o_hplus);
|
||||||
|
dplus = (weap == NULL ? 0 : weap->o_dplus);
|
||||||
|
if (weap == cur_weapon)
|
||||||
|
{
|
||||||
|
if (ISRING(LEFT, R_ADDDAM))
|
||||||
|
dplus += cur_ring[LEFT]->o_arm;
|
||||||
|
else if (ISRING(LEFT, R_ADDHIT))
|
||||||
|
hplus += cur_ring[LEFT]->o_arm;
|
||||||
|
if (ISRING(RIGHT, R_ADDDAM))
|
||||||
|
dplus += cur_ring[RIGHT]->o_arm;
|
||||||
|
else if (ISRING(RIGHT, R_ADDHIT))
|
||||||
|
hplus += cur_ring[RIGHT]->o_arm;
|
||||||
|
}
|
||||||
|
cp = weap->o_damage;
|
||||||
|
if (hurl)
|
||||||
|
{
|
||||||
|
if ((weap->o_flags&ISMISL) && cur_weapon != NULL &&
|
||||||
|
cur_weapon->o_which == weap->o_launch)
|
||||||
|
{
|
||||||
|
cp = weap->o_hurldmg;
|
||||||
|
hplus += cur_weapon->o_hplus;
|
||||||
|
dplus += cur_weapon->o_dplus;
|
||||||
|
}
|
||||||
|
else if (weap->o_launch < 0)
|
||||||
|
cp = weap->o_hurldmg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* If the creature being attacked is not running (alseep or held)
|
||||||
|
* then the attacker gets a plus four bonus to hit.
|
||||||
|
*/
|
||||||
|
if (!on(*thdef, ISRUN))
|
||||||
|
hplus += 4;
|
||||||
|
def_arm = def->s_arm;
|
||||||
|
if (def == &pstats)
|
||||||
|
{
|
||||||
|
if (cur_armor != NULL)
|
||||||
|
def_arm = cur_armor->o_arm;
|
||||||
|
if (ISRING(LEFT, R_PROTECT))
|
||||||
|
def_arm -= cur_ring[LEFT]->o_arm;
|
||||||
|
if (ISRING(RIGHT, R_PROTECT))
|
||||||
|
def_arm -= cur_ring[RIGHT]->o_arm;
|
||||||
|
}
|
||||||
|
while(cp != NULL && *cp != '\0')
|
||||||
|
{
|
||||||
|
ndice = atoi(cp);
|
||||||
|
if ((cp = strchr(cp, 'x')) == NULL)
|
||||||
|
break;
|
||||||
|
nsides = atoi(++cp);
|
||||||
|
if (swing(att->s_lvl, def_arm, hplus + str_plus[att->s_str]))
|
||||||
|
{
|
||||||
|
int proll;
|
||||||
|
|
||||||
|
proll = roll(ndice, nsides);
|
||||||
|
#ifdef MASTER
|
||||||
|
if (ndice + nsides > 0 && proll <= 0)
|
||||||
|
debug("Damage for %dx%d came out %d, dplus = %d, add_dam = %d, def_arm = %d", ndice, nsides, proll, dplus, add_dam[att->s_str], def_arm);
|
||||||
|
#endif
|
||||||
|
damage = dplus + proll + add_dam[att->s_str];
|
||||||
|
def->s_hpt -= max(0, damage);
|
||||||
|
did_hit = TRUE;
|
||||||
|
}
|
||||||
|
if ((cp = strchr(cp, '/')) == NULL)
|
||||||
|
break;
|
||||||
|
cp++;
|
||||||
|
}
|
||||||
|
return did_hit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prname:
|
||||||
|
* The print name of a combatant
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
prname(const char *mname, int upper)
|
||||||
|
{
|
||||||
|
static char tbuf[MAXSTR];
|
||||||
|
|
||||||
|
*tbuf = '\0';
|
||||||
|
if (mname == 0)
|
||||||
|
strcpy(tbuf, "you");
|
||||||
|
else
|
||||||
|
strcpy(tbuf, mname);
|
||||||
|
if (upper)
|
||||||
|
*tbuf = (char) toupper(*tbuf);
|
||||||
|
return tbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* thunk:
|
||||||
|
* A missile hits a monster
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
thunk(const THING *weap, const char *mname, int noend)
|
||||||
|
{
|
||||||
|
if (to_death)
|
||||||
|
return;
|
||||||
|
if (weap->o_type == WEAPON)
|
||||||
|
addmsg("the %s hits ", weap_info[weap->o_which].oi_name);
|
||||||
|
else
|
||||||
|
addmsg("you hit ");
|
||||||
|
addmsg("%s", mname);
|
||||||
|
if (!noend)
|
||||||
|
endmsg();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* hit:
|
||||||
|
* Print a message to indicate a succesful hit
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
hit(const char *er, const char *ee, int noend)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
if (to_death)
|
||||||
|
return;
|
||||||
|
addmsg(prname(er, TRUE));
|
||||||
|
if (terse)
|
||||||
|
s = " hit";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i = rnd(4);
|
||||||
|
if (er != NULL)
|
||||||
|
i += 4;
|
||||||
|
s = h_names[i];
|
||||||
|
}
|
||||||
|
addmsg(s);
|
||||||
|
if (!terse)
|
||||||
|
addmsg(prname(ee, FALSE));
|
||||||
|
if (!noend)
|
||||||
|
endmsg();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* miss:
|
||||||
|
* Print a message to indicate a poor swing
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
miss(const char *er, const char *ee, int noend)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (to_death)
|
||||||
|
return;
|
||||||
|
addmsg(prname(er, TRUE));
|
||||||
|
if (terse)
|
||||||
|
i = 0;
|
||||||
|
else
|
||||||
|
i = rnd(4);
|
||||||
|
if (er != NULL)
|
||||||
|
i += 4;
|
||||||
|
addmsg(m_names[i]);
|
||||||
|
if (!terse)
|
||||||
|
addmsg(" %s", prname(ee, FALSE));
|
||||||
|
if (!noend)
|
||||||
|
endmsg();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* bounce:
|
||||||
|
* A missile misses a monster
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
bounce(const THING *weap, const char *mname, int noend)
|
||||||
|
{
|
||||||
|
if (to_death)
|
||||||
|
return;
|
||||||
|
if (weap->o_type == WEAPON)
|
||||||
|
addmsg("the %s misses ", weap_info[weap->o_which].oi_name);
|
||||||
|
else
|
||||||
|
addmsg("you missed ");
|
||||||
|
addmsg(mname);
|
||||||
|
if (!noend)
|
||||||
|
endmsg();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* remove_mon:
|
||||||
|
* Remove a monster from the screen
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
remove_mon(const coord *mp, THING *tp, int waskill)
|
||||||
|
{
|
||||||
|
THING *obj, *nexti;
|
||||||
|
|
||||||
|
for (obj = tp->t_pack; obj != NULL; obj = nexti)
|
||||||
|
{
|
||||||
|
nexti = next(obj);
|
||||||
|
obj->o_pos = tp->t_pos;
|
||||||
|
detach(tp->t_pack, obj);
|
||||||
|
if (waskill)
|
||||||
|
fall(obj, FALSE);
|
||||||
|
else
|
||||||
|
discard(obj);
|
||||||
|
}
|
||||||
|
moat(mp->y, mp->x) = NULL;
|
||||||
|
mvaddch(mp->y, mp->x, tp->t_oldch);
|
||||||
|
detach(mlist, tp);
|
||||||
|
if (on(*tp, ISTARGET))
|
||||||
|
{
|
||||||
|
kamikaze = FALSE;
|
||||||
|
to_death = FALSE;
|
||||||
|
if (fight_flush)
|
||||||
|
flush_type();
|
||||||
|
}
|
||||||
|
discard(tp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* killed:
|
||||||
|
* Called to put a monster to death
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
killed(THING *tp, int pr)
|
||||||
|
{
|
||||||
|
const char *mname;
|
||||||
|
|
||||||
|
pstats.s_exp += tp->t_stats.s_exp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the monster was a venus flytrap, un-hold him
|
||||||
|
*/
|
||||||
|
switch (tp->t_type)
|
||||||
|
{
|
||||||
|
case 'F':
|
||||||
|
player.t_flags &= ~ISHELD;
|
||||||
|
vf_hit = 0;
|
||||||
|
strcpy(monsters['F'-'A'].m_stats.s_dmg, "000x0");
|
||||||
|
when 'L':
|
||||||
|
{
|
||||||
|
THING *gold;
|
||||||
|
|
||||||
|
if (fallpos(&tp->t_pos, &tp->t_room->r_gold) && level >= max_level)
|
||||||
|
{
|
||||||
|
gold = new_item();
|
||||||
|
gold->o_type = GOLD;
|
||||||
|
gold->o_goldval = GOLDCALC;
|
||||||
|
if (save(VS_MAGIC))
|
||||||
|
gold->o_goldval += GOLDCALC + GOLDCALC
|
||||||
|
+ GOLDCALC + GOLDCALC;
|
||||||
|
attach(tp->t_pack, gold);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Get rid of the monster.
|
||||||
|
*/
|
||||||
|
mname = set_mname(tp);
|
||||||
|
remove_mon(&tp->t_pos, tp, TRUE);
|
||||||
|
if (pr)
|
||||||
|
{
|
||||||
|
if (has_hit)
|
||||||
|
{
|
||||||
|
addmsg(". Defeated ");
|
||||||
|
has_hit = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!terse)
|
||||||
|
addmsg("you have ");
|
||||||
|
addmsg("defeated ");
|
||||||
|
}
|
||||||
|
msg(mname);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Do adjustments if he went up a level
|
||||||
|
*/
|
||||||
|
check_level();
|
||||||
|
if (fight_flush)
|
||||||
|
flush_type();
|
||||||
|
}
|
||||||
22
rogue5/findpw.c
Normal file
22
rogue5/findpw.c
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* print out an encrypted password on the standard output
|
||||||
|
*
|
||||||
|
* @(#)findpw.c 1.4 (Berkeley) 02/05/99
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
char buf[80];
|
||||||
|
|
||||||
|
fprintf(stderr, "Password: ");
|
||||||
|
(void) fgets(buf, 80, stdin);
|
||||||
|
buf[strlen(buf) - 1] = '\0';
|
||||||
|
printf("%s\n", xcrypt(buf, "mT"));
|
||||||
|
}
|
||||||
450
rogue5/init.c
Normal file
450
rogue5/init.c
Normal file
|
|
@ -0,0 +1,450 @@
|
||||||
|
/*
|
||||||
|
* global variable initializaton
|
||||||
|
*
|
||||||
|
* @(#)init.c 4.31 (Berkeley) 02/05/99
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <curses.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "rogue.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* init_player:
|
||||||
|
* Roll her up
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
init_player(void)
|
||||||
|
{
|
||||||
|
THING *obj;
|
||||||
|
|
||||||
|
pstats = max_stats;
|
||||||
|
food_left = HUNGERTIME;
|
||||||
|
/*
|
||||||
|
* Give him some food
|
||||||
|
*/
|
||||||
|
obj = new_item();
|
||||||
|
obj->o_type = FOOD;
|
||||||
|
obj->o_count = 1;
|
||||||
|
add_pack(obj, TRUE);
|
||||||
|
/*
|
||||||
|
* And his suit of armor
|
||||||
|
*/
|
||||||
|
obj = new_item();
|
||||||
|
obj->o_type = ARMOR;
|
||||||
|
obj->o_which = RING_MAIL;
|
||||||
|
obj->o_arm = a_class[RING_MAIL] - 1;
|
||||||
|
obj->o_flags |= ISKNOW;
|
||||||
|
obj->o_count = 1;
|
||||||
|
cur_armor = obj;
|
||||||
|
add_pack(obj, TRUE);
|
||||||
|
/*
|
||||||
|
* Give him his weaponry. First a mace.
|
||||||
|
*/
|
||||||
|
obj = new_item();
|
||||||
|
init_weapon(obj, MACE);
|
||||||
|
obj->o_hplus = 1;
|
||||||
|
obj->o_dplus = 1;
|
||||||
|
obj->o_flags |= ISKNOW;
|
||||||
|
add_pack(obj, TRUE);
|
||||||
|
cur_weapon = obj;
|
||||||
|
/*
|
||||||
|
* Now a +1 bow
|
||||||
|
*/
|
||||||
|
obj = new_item();
|
||||||
|
init_weapon(obj, BOW);
|
||||||
|
obj->o_hplus = 1;
|
||||||
|
obj->o_flags |= ISKNOW;
|
||||||
|
add_pack(obj, TRUE);
|
||||||
|
/*
|
||||||
|
* Now some arrows
|
||||||
|
*/
|
||||||
|
obj = new_item();
|
||||||
|
init_weapon(obj, ARROW);
|
||||||
|
obj->o_count = rnd(15) + 25;
|
||||||
|
obj->o_flags |= ISKNOW;
|
||||||
|
add_pack(obj, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Contains defintions and functions for dealing with things like
|
||||||
|
* potions and scrolls
|
||||||
|
*/
|
||||||
|
|
||||||
|
const char *rainbow[] = {
|
||||||
|
"amber",
|
||||||
|
"aquamarine",
|
||||||
|
"black",
|
||||||
|
"blue",
|
||||||
|
"brown",
|
||||||
|
"clear",
|
||||||
|
"crimson",
|
||||||
|
"cyan",
|
||||||
|
"ecru",
|
||||||
|
"gold",
|
||||||
|
"green",
|
||||||
|
"grey",
|
||||||
|
"magenta",
|
||||||
|
"orange",
|
||||||
|
"pink",
|
||||||
|
"plaid",
|
||||||
|
"purple",
|
||||||
|
"red",
|
||||||
|
"silver",
|
||||||
|
"tan",
|
||||||
|
"tangerine",
|
||||||
|
"topaz",
|
||||||
|
"turquoise",
|
||||||
|
"vermilion",
|
||||||
|
"violet",
|
||||||
|
"white",
|
||||||
|
"yellow",
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NCOLORS (sizeof rainbow / sizeof (char *))
|
||||||
|
|
||||||
|
static const char *sylls[] = {
|
||||||
|
"a", "ab", "ag", "aks", "ala", "an", "app", "arg", "arze", "ash",
|
||||||
|
"bek", "bie", "bit", "bjor", "blu", "bot", "bu", "byt", "comp",
|
||||||
|
"con", "cos", "cre", "dalf", "dan", "den", "do", "e", "eep", "el",
|
||||||
|
"eng", "er", "ere", "erk", "esh", "evs", "fa", "fid", "fri", "fu",
|
||||||
|
"gan", "gar", "glen", "gop", "gre", "ha", "hyd", "i", "ing", "ip",
|
||||||
|
"ish", "it", "ite", "iv", "jo", "kho", "kli", "klis", "la", "lech",
|
||||||
|
"mar", "me", "mi", "mic", "mik", "mon", "mung", "mur", "nej",
|
||||||
|
"nelg", "nep", "ner", "nes", "nes", "nih", "nin", "o", "od", "ood",
|
||||||
|
"org", "orn", "ox", "oxy", "pay", "ple", "plu", "po", "pot",
|
||||||
|
"prok", "re", "rea", "rhov", "ri", "ro", "rog", "rok", "rol", "sa",
|
||||||
|
"san", "sat", "sef", "seh", "shu", "ski", "sna", "sne", "snik",
|
||||||
|
"sno", "so", "sol", "sri", "sta", "sun", "ta", "tab", "tem",
|
||||||
|
"ther", "ti", "tox", "trol", "tue", "turs", "u", "ulk", "um", "un",
|
||||||
|
"uni", "ur", "val", "viv", "vly", "vom", "wah", "wed", "werg",
|
||||||
|
"wex", "whon", "wun", "xo", "y", "yot", "yu", "zant", "zeb", "zim",
|
||||||
|
"zok", "zon", "zum",
|
||||||
|
};
|
||||||
|
|
||||||
|
const STONE stones[] = {
|
||||||
|
{ "agate", 25},
|
||||||
|
{ "alexandrite", 40},
|
||||||
|
{ "amethyst", 50},
|
||||||
|
{ "carnelian", 40},
|
||||||
|
{ "diamond", 300},
|
||||||
|
{ "emerald", 300},
|
||||||
|
{ "germanium", 225},
|
||||||
|
{ "granite", 5},
|
||||||
|
{ "garnet", 50},
|
||||||
|
{ "jade", 150},
|
||||||
|
{ "kryptonite", 300},
|
||||||
|
{ "lapis lazuli", 50},
|
||||||
|
{ "moonstone", 50},
|
||||||
|
{ "obsidian", 15},
|
||||||
|
{ "onyx", 60},
|
||||||
|
{ "opal", 200},
|
||||||
|
{ "pearl", 220},
|
||||||
|
{ "peridot", 63},
|
||||||
|
{ "ruby", 350},
|
||||||
|
{ "sapphire", 285},
|
||||||
|
{ "stibotantalite", 200},
|
||||||
|
{ "tiger eye", 50},
|
||||||
|
{ "topaz", 60},
|
||||||
|
{ "turquoise", 70},
|
||||||
|
{ "taaffeite", 300},
|
||||||
|
{ "zircon", 80},
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NSTONES (sizeof stones / sizeof (STONE))
|
||||||
|
|
||||||
|
const char *wood[] = {
|
||||||
|
"avocado wood",
|
||||||
|
"balsa",
|
||||||
|
"bamboo",
|
||||||
|
"banyan",
|
||||||
|
"birch",
|
||||||
|
"cedar",
|
||||||
|
"cherry",
|
||||||
|
"cinnibar",
|
||||||
|
"cypress",
|
||||||
|
"dogwood",
|
||||||
|
"driftwood",
|
||||||
|
"ebony",
|
||||||
|
"elm",
|
||||||
|
"eucalyptus",
|
||||||
|
"fall",
|
||||||
|
"hemlock",
|
||||||
|
"holly",
|
||||||
|
"ironwood",
|
||||||
|
"kukui wood",
|
||||||
|
"mahogany",
|
||||||
|
"manzanita",
|
||||||
|
"maple",
|
||||||
|
"oaken",
|
||||||
|
"persimmon wood",
|
||||||
|
"pecan",
|
||||||
|
"pine",
|
||||||
|
"poplar",
|
||||||
|
"redwood",
|
||||||
|
"rosewood",
|
||||||
|
"spruce",
|
||||||
|
"teak",
|
||||||
|
"walnut",
|
||||||
|
"zebrawood",
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NWOOD (sizeof wood / sizeof (char *))
|
||||||
|
|
||||||
|
const char *metal[] = {
|
||||||
|
"aluminum",
|
||||||
|
"beryllium",
|
||||||
|
"bone",
|
||||||
|
"brass",
|
||||||
|
"bronze",
|
||||||
|
"copper",
|
||||||
|
"electrum",
|
||||||
|
"gold",
|
||||||
|
"iron",
|
||||||
|
"lead",
|
||||||
|
"magnesium",
|
||||||
|
"mercury",
|
||||||
|
"nickel",
|
||||||
|
"pewter",
|
||||||
|
"platinum",
|
||||||
|
"steel",
|
||||||
|
"silver",
|
||||||
|
"silicon",
|
||||||
|
"tin",
|
||||||
|
"titanium",
|
||||||
|
"tungsten",
|
||||||
|
"zinc",
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NMETAL (sizeof metal / sizeof (char *))
|
||||||
|
|
||||||
|
int cNWOOD = NWOOD;
|
||||||
|
int cNMETAL = NMETAL;
|
||||||
|
int cNSTONES = NSTONES;
|
||||||
|
int cNCOLORS = NCOLORS;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* init_colors:
|
||||||
|
* Initialize the potion color scheme for this time
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
init_colors(void)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
int used[NCOLORS];
|
||||||
|
|
||||||
|
for (i = 0; i < NCOLORS; i++)
|
||||||
|
used[i] = FALSE;
|
||||||
|
for (i = 0; i < MAXPOTIONS; i++)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
j = rnd(NCOLORS);
|
||||||
|
until (!used[j]);
|
||||||
|
used[j] = TRUE;
|
||||||
|
p_colors[i] = rainbow[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* init_names:
|
||||||
|
* Generate the names of the various scrolls
|
||||||
|
*/
|
||||||
|
#define MAXNAME 40 /* Max number of characters in a name */
|
||||||
|
|
||||||
|
void
|
||||||
|
init_names(void)
|
||||||
|
{
|
||||||
|
int nsyl;
|
||||||
|
const char *sp;
|
||||||
|
char *cp;
|
||||||
|
int i, nwords;
|
||||||
|
|
||||||
|
for (i = 0; i < MAXSCROLLS; i++)
|
||||||
|
{
|
||||||
|
cp = prbuf;
|
||||||
|
nwords = rnd(3) + 2;
|
||||||
|
while (nwords--)
|
||||||
|
{
|
||||||
|
nsyl = rnd(3) + 1;
|
||||||
|
while (nsyl--)
|
||||||
|
{
|
||||||
|
sp = sylls[rnd((sizeof sylls) / (sizeof (char *)))];
|
||||||
|
if (&cp[strlen(sp)] > &prbuf[MAXNAME])
|
||||||
|
break;
|
||||||
|
while (*sp)
|
||||||
|
*cp++ = *sp++;
|
||||||
|
}
|
||||||
|
*cp++ = ' ';
|
||||||
|
}
|
||||||
|
*--cp = '\0';
|
||||||
|
s_names[i] = malloc(strlen(prbuf)+1);
|
||||||
|
if (s_names[i] != NULL)
|
||||||
|
strcpy(s_names[i], prbuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* init_stones:
|
||||||
|
* Initialize the ring stone setting scheme for this time
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
init_stones(void)
|
||||||
|
{
|
||||||
|
int used[NSTONES];
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
for (i = 0; i < NSTONES; i++)
|
||||||
|
used[i] = FALSE;
|
||||||
|
for (i = 0; i < MAXRINGS; i++)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
j = rnd(NSTONES);
|
||||||
|
until (!used[j]);
|
||||||
|
used[j] = TRUE;
|
||||||
|
r_stones[i] = stones[j].st_name;
|
||||||
|
ring_info[i].oi_worth += stones[j].st_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* init_materials:
|
||||||
|
* Initialize the construction materials for wands and staffs
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
init_materials(void)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
const char *str;
|
||||||
|
int metused[NMETAL];
|
||||||
|
int used[NWOOD];
|
||||||
|
|
||||||
|
for (i = 0; i < NWOOD; i++)
|
||||||
|
used[i] = FALSE;
|
||||||
|
for (i = 0; i < NMETAL; i++)
|
||||||
|
metused[i] = FALSE;
|
||||||
|
for (i = 0; i < MAXSTICKS; i++)
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
if (rnd(2) == 0)
|
||||||
|
{
|
||||||
|
j = rnd(NMETAL);
|
||||||
|
if (!metused[j])
|
||||||
|
{
|
||||||
|
ws_type[i] = "wand";
|
||||||
|
str = metal[j];
|
||||||
|
metused[j] = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
j = rnd(NWOOD);
|
||||||
|
if (!used[j])
|
||||||
|
{
|
||||||
|
ws_type[i] = "staff";
|
||||||
|
str = wood[j];
|
||||||
|
used[j] = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ws_made[i] = str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MASTER
|
||||||
|
# define NT NUMTHINGS, "things"
|
||||||
|
# define MP MAXPOTIONS, "potions"
|
||||||
|
# define MS MAXSCROLLS, "scrolls"
|
||||||
|
# define MR MAXRINGS, "rings"
|
||||||
|
# define MWS MAXSTICKS, "sticks"
|
||||||
|
# define MW MAXWEAPONS, "weapons"
|
||||||
|
# define MA MAXARMORS, "armor"
|
||||||
|
#else
|
||||||
|
# define NT NUMTHINGS
|
||||||
|
# define MP MAXPOTIONS
|
||||||
|
# define MS MAXSCROLLS
|
||||||
|
# define MR MAXRINGS
|
||||||
|
# define MWS MAXSTICKS
|
||||||
|
# define MW MAXWEAPONS
|
||||||
|
# define MA MAXARMORS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sumprobs:
|
||||||
|
* Sum up the probabilities for items appearing
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
sumprobs(struct obj_info *info, int bound
|
||||||
|
#ifdef MASTER
|
||||||
|
, char *name
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
#ifdef MASTER
|
||||||
|
struct obj_info *start = info;
|
||||||
|
#endif
|
||||||
|
struct obj_info *endp;
|
||||||
|
|
||||||
|
endp = info + bound;
|
||||||
|
while (++info < endp)
|
||||||
|
info->oi_prob += (info - 1)->oi_prob;
|
||||||
|
#ifdef MASTER
|
||||||
|
badcheck(name, start, bound);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* init_probs:
|
||||||
|
* Initialize the probabilities for the various items
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
init_probs(void)
|
||||||
|
{
|
||||||
|
sumprobs(things, NT);
|
||||||
|
sumprobs(pot_info, MP);
|
||||||
|
sumprobs(scr_info, MS);
|
||||||
|
sumprobs(ring_info, MR);
|
||||||
|
sumprobs(ws_info, MWS);
|
||||||
|
sumprobs(weap_info, MW);
|
||||||
|
sumprobs(arm_info, MA);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MASTER
|
||||||
|
/*
|
||||||
|
* badcheck:
|
||||||
|
* Check to see if a series of probabilities sums to 100
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
badcheck(const char *name, const struct obj_info *info, int bound)
|
||||||
|
{
|
||||||
|
const struct obj_info *end;
|
||||||
|
|
||||||
|
if (info[bound - 1].oi_prob == 100)
|
||||||
|
return;
|
||||||
|
printf("\nBad percentages for %s (bound = %d):\n", name, bound);
|
||||||
|
for (end = &info[bound]; info < end; info++)
|
||||||
|
printf("%3d%% %s\n", info->oi_prob, info->oi_name);
|
||||||
|
printf("[hit RETURN to continue]");
|
||||||
|
fflush(stdout);
|
||||||
|
while (getchar() != '\n')
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pick_color:
|
||||||
|
* If he is halucinating, pick a random color name and return it,
|
||||||
|
* otherwise return the given color.
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
pick_color(const char *col)
|
||||||
|
{
|
||||||
|
return (on(player, ISHALU) ? rainbow[rnd(NCOLORS)] : col);
|
||||||
|
}
|
||||||
323
rogue5/install-sh
Executable file
323
rogue5/install-sh
Executable file
|
|
@ -0,0 +1,323 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# install - install a program, script, or datafile
|
||||||
|
|
||||||
|
scriptversion=2005-05-14.22
|
||||||
|
|
||||||
|
# This originates from X11R5 (mit/util/scripts/install.sh), which was
|
||||||
|
# later released in X11R6 (xc/config/util/install.sh) with the
|
||||||
|
# following copyright and license.
|
||||||
|
#
|
||||||
|
# Copyright (C) 1994 X Consortium
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to
|
||||||
|
# deal in the Software without restriction, including without limitation the
|
||||||
|
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
# sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||||
|
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
|
||||||
|
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
#
|
||||||
|
# Except as contained in this notice, the name of the X Consortium shall not
|
||||||
|
# be used in advertising or otherwise to promote the sale, use or other deal-
|
||||||
|
# ings in this Software without prior written authorization from the X Consor-
|
||||||
|
# tium.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# FSF changes to this file are in the public domain.
|
||||||
|
#
|
||||||
|
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||||
|
# `make' implicit rules from creating a file called install from it
|
||||||
|
# when there is no Makefile.
|
||||||
|
#
|
||||||
|
# This script is compatible with the BSD install script, but was written
|
||||||
|
# from scratch. It can only install one file at a time, a restriction
|
||||||
|
# shared with many OS's install programs.
|
||||||
|
|
||||||
|
# set DOITPROG to echo to test this script
|
||||||
|
|
||||||
|
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||||
|
doit="${DOITPROG-}"
|
||||||
|
|
||||||
|
# put in absolute paths if you don't have them in your path; or use env. vars.
|
||||||
|
|
||||||
|
mvprog="${MVPROG-mv}"
|
||||||
|
cpprog="${CPPROG-cp}"
|
||||||
|
chmodprog="${CHMODPROG-chmod}"
|
||||||
|
chownprog="${CHOWNPROG-chown}"
|
||||||
|
chgrpprog="${CHGRPPROG-chgrp}"
|
||||||
|
stripprog="${STRIPPROG-strip}"
|
||||||
|
rmprog="${RMPROG-rm}"
|
||||||
|
mkdirprog="${MKDIRPROG-mkdir}"
|
||||||
|
|
||||||
|
chmodcmd="$chmodprog 0755"
|
||||||
|
chowncmd=
|
||||||
|
chgrpcmd=
|
||||||
|
stripcmd=
|
||||||
|
rmcmd="$rmprog -f"
|
||||||
|
mvcmd="$mvprog"
|
||||||
|
src=
|
||||||
|
dst=
|
||||||
|
dir_arg=
|
||||||
|
dstarg=
|
||||||
|
no_target_directory=
|
||||||
|
|
||||||
|
usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
|
||||||
|
or: $0 [OPTION]... SRCFILES... DIRECTORY
|
||||||
|
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
|
||||||
|
or: $0 [OPTION]... -d DIRECTORIES...
|
||||||
|
|
||||||
|
In the 1st form, copy SRCFILE to DSTFILE.
|
||||||
|
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
|
||||||
|
In the 4th, create DIRECTORIES.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-c (ignored)
|
||||||
|
-d create directories instead of installing files.
|
||||||
|
-g GROUP $chgrpprog installed files to GROUP.
|
||||||
|
-m MODE $chmodprog installed files to MODE.
|
||||||
|
-o USER $chownprog installed files to USER.
|
||||||
|
-s $stripprog installed files.
|
||||||
|
-t DIRECTORY install into DIRECTORY.
|
||||||
|
-T report an error if DSTFILE is a directory.
|
||||||
|
--help display this help and exit.
|
||||||
|
--version display version info and exit.
|
||||||
|
|
||||||
|
Environment variables override the default commands:
|
||||||
|
CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
|
||||||
|
"
|
||||||
|
|
||||||
|
while test -n "$1"; do
|
||||||
|
case $1 in
|
||||||
|
-c) shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-d) dir_arg=true
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-g) chgrpcmd="$chgrpprog $2"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
--help) echo "$usage"; exit $?;;
|
||||||
|
|
||||||
|
-m) chmodcmd="$chmodprog $2"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-o) chowncmd="$chownprog $2"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-s) stripcmd=$stripprog
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-t) dstarg=$2
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-T) no_target_directory=true
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
--version) echo "$0 $scriptversion"; exit $?;;
|
||||||
|
|
||||||
|
*) # When -d is used, all remaining arguments are directories to create.
|
||||||
|
# When -t is used, the destination is already specified.
|
||||||
|
test -n "$dir_arg$dstarg" && break
|
||||||
|
# Otherwise, the last argument is the destination. Remove it from $@.
|
||||||
|
for arg
|
||||||
|
do
|
||||||
|
if test -n "$dstarg"; then
|
||||||
|
# $@ is not empty: it contains at least $arg.
|
||||||
|
set fnord "$@" "$dstarg"
|
||||||
|
shift # fnord
|
||||||
|
fi
|
||||||
|
shift # arg
|
||||||
|
dstarg=$arg
|
||||||
|
done
|
||||||
|
break;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if test -z "$1"; then
|
||||||
|
if test -z "$dir_arg"; then
|
||||||
|
echo "$0: no input file specified." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# It's OK to call `install-sh -d' without argument.
|
||||||
|
# This can happen when creating conditional directories.
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
for src
|
||||||
|
do
|
||||||
|
# Protect names starting with `-'.
|
||||||
|
case $src in
|
||||||
|
-*) src=./$src ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if test -n "$dir_arg"; then
|
||||||
|
dst=$src
|
||||||
|
src=
|
||||||
|
|
||||||
|
if test -d "$dst"; then
|
||||||
|
mkdircmd=:
|
||||||
|
chmodcmd=
|
||||||
|
else
|
||||||
|
mkdircmd=$mkdirprog
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
|
||||||
|
# might cause directories to be created, which would be especially bad
|
||||||
|
# if $src (and thus $dsttmp) contains '*'.
|
||||||
|
if test ! -f "$src" && test ! -d "$src"; then
|
||||||
|
echo "$0: $src does not exist." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -z "$dstarg"; then
|
||||||
|
echo "$0: no destination specified." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
dst=$dstarg
|
||||||
|
# Protect names starting with `-'.
|
||||||
|
case $dst in
|
||||||
|
-*) dst=./$dst ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# If destination is a directory, append the input filename; won't work
|
||||||
|
# if double slashes aren't ignored.
|
||||||
|
if test -d "$dst"; then
|
||||||
|
if test -n "$no_target_directory"; then
|
||||||
|
echo "$0: $dstarg: Is a directory" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
dst=$dst/`basename "$src"`
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# This sed command emulates the dirname command.
|
||||||
|
dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
|
||||||
|
|
||||||
|
# Make sure that the destination directory exists.
|
||||||
|
|
||||||
|
# Skip lots of stat calls in the usual case.
|
||||||
|
if test ! -d "$dstdir"; then
|
||||||
|
defaultIFS='
|
||||||
|
'
|
||||||
|
IFS="${IFS-$defaultIFS}"
|
||||||
|
|
||||||
|
oIFS=$IFS
|
||||||
|
# Some sh's can't handle IFS=/ for some reason.
|
||||||
|
IFS='%'
|
||||||
|
set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
|
||||||
|
shift
|
||||||
|
IFS=$oIFS
|
||||||
|
|
||||||
|
pathcomp=
|
||||||
|
|
||||||
|
while test $# -ne 0 ; do
|
||||||
|
pathcomp=$pathcomp$1
|
||||||
|
shift
|
||||||
|
if test ! -d "$pathcomp"; then
|
||||||
|
$mkdirprog "$pathcomp"
|
||||||
|
# mkdir can fail with a `File exist' error in case several
|
||||||
|
# install-sh are creating the directory concurrently. This
|
||||||
|
# is OK.
|
||||||
|
test -d "$pathcomp" || exit
|
||||||
|
fi
|
||||||
|
pathcomp=$pathcomp/
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -n "$dir_arg"; then
|
||||||
|
$doit $mkdircmd "$dst" \
|
||||||
|
&& { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
|
||||||
|
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
|
||||||
|
&& { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
|
||||||
|
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
|
||||||
|
|
||||||
|
else
|
||||||
|
dstfile=`basename "$dst"`
|
||||||
|
|
||||||
|
# Make a couple of temp file names in the proper directory.
|
||||||
|
dsttmp=$dstdir/_inst.$$_
|
||||||
|
rmtmp=$dstdir/_rm.$$_
|
||||||
|
|
||||||
|
# Trap to clean up those temp files at exit.
|
||||||
|
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
|
||||||
|
trap '(exit $?); exit' 1 2 13 15
|
||||||
|
|
||||||
|
# Copy the file name to the temp name.
|
||||||
|
$doit $cpprog "$src" "$dsttmp" &&
|
||||||
|
|
||||||
|
# and set any options; do chmod last to preserve setuid bits.
|
||||||
|
#
|
||||||
|
# If any of these fail, we abort the whole thing. If we want to
|
||||||
|
# ignore errors from any of these, just make sure not to ignore
|
||||||
|
# errors from the above "$doit $cpprog $src $dsttmp" command.
|
||||||
|
#
|
||||||
|
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
|
||||||
|
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
|
||||||
|
&& { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
|
||||||
|
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
|
||||||
|
|
||||||
|
# Now rename the file to the real destination.
|
||||||
|
{ $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
|
||||||
|
|| {
|
||||||
|
# The rename failed, perhaps because mv can't rename something else
|
||||||
|
# to itself, or perhaps because mv is so ancient that it does not
|
||||||
|
# support -f.
|
||||||
|
|
||||||
|
# Now remove or move aside any old file at destination location.
|
||||||
|
# We try this two ways since rm can't unlink itself on some
|
||||||
|
# systems and the destination file might be busy for other
|
||||||
|
# reasons. In this case, the final cleanup might fail but the new
|
||||||
|
# file should still install successfully.
|
||||||
|
{
|
||||||
|
if test -f "$dstdir/$dstfile"; then
|
||||||
|
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
|
||||||
|
|| $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
|
||||||
|
|| {
|
||||||
|
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
|
||||||
|
(exit 1); exit 1
|
||||||
|
}
|
||||||
|
else
|
||||||
|
:
|
||||||
|
fi
|
||||||
|
} &&
|
||||||
|
|
||||||
|
# Now rename the file to the real destination.
|
||||||
|
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fi || { (exit 1); exit 1; }
|
||||||
|
done
|
||||||
|
|
||||||
|
# The final little trick to "correctly" pass the exit status to the exit trap.
|
||||||
|
{
|
||||||
|
(exit 0); exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Local variables:
|
||||||
|
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||||
|
# time-stamp-start: "scriptversion="
|
||||||
|
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||||
|
# time-stamp-end: "$"
|
||||||
|
# End:
|
||||||
294
rogue5/io.c
Normal file
294
rogue5/io.c
Normal file
|
|
@ -0,0 +1,294 @@
|
||||||
|
/*
|
||||||
|
* Various input/output functions
|
||||||
|
*
|
||||||
|
* @(#)io.c 4.32 (Berkeley) 02/05/99
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <curses.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "rogue.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* msg:
|
||||||
|
* Display a message at the top of the screen.
|
||||||
|
*/
|
||||||
|
#define MAXMSG (NUMCOLS - sizeof "--More--")
|
||||||
|
|
||||||
|
static char msgbuf[2*MAXMSG+1];
|
||||||
|
static int newpos = 0;
|
||||||
|
|
||||||
|
/* VARARGS1 */
|
||||||
|
int
|
||||||
|
msg(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if the string is "", just clear the line
|
||||||
|
*/
|
||||||
|
if (*fmt == '\0')
|
||||||
|
{
|
||||||
|
move(0, 0);
|
||||||
|
clrtoeol();
|
||||||
|
mpos = 0;
|
||||||
|
return ~ESCAPE;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* otherwise add to the message and flush it out
|
||||||
|
*/
|
||||||
|
va_start(args, fmt);
|
||||||
|
doadd(fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
return endmsg();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* addmsg:
|
||||||
|
* Add things to the current message
|
||||||
|
*/
|
||||||
|
/* VARARGS1 */
|
||||||
|
void
|
||||||
|
addmsg(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
doadd(fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* endmsg:
|
||||||
|
* Display a new msg (giving him a chance to see the previous one
|
||||||
|
* if it is up there with the --More--)
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
endmsg(void)
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
if (save_msg)
|
||||||
|
strcpy(huh, msgbuf);
|
||||||
|
if (mpos)
|
||||||
|
{
|
||||||
|
look(FALSE);
|
||||||
|
mvaddstr(0, mpos, "--More--");
|
||||||
|
refresh();
|
||||||
|
if (!msg_esc)
|
||||||
|
wait_for(stdscr, ' ');
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while ((ch = readchar()) != ' ')
|
||||||
|
if (ch == ESCAPE)
|
||||||
|
{
|
||||||
|
msgbuf[0] = '\0';
|
||||||
|
mpos = 0;
|
||||||
|
newpos = 0;
|
||||||
|
msgbuf[0] = '\0';
|
||||||
|
return ESCAPE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* All messages should start with uppercase, except ones that
|
||||||
|
* start with a pack addressing character
|
||||||
|
*/
|
||||||
|
if (islower((int)msgbuf[0]) && !lower_msg && msgbuf[1] != ')')
|
||||||
|
msgbuf[0] = (char) toupper(msgbuf[0]);
|
||||||
|
mvaddstr(0, 0, msgbuf);
|
||||||
|
clrtoeol();
|
||||||
|
mpos = newpos;
|
||||||
|
newpos = 0;
|
||||||
|
msgbuf[0] = '\0';
|
||||||
|
refresh();
|
||||||
|
return ~ESCAPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* doadd:
|
||||||
|
* Perform an add onto the message buffer
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
doadd(const char *fmt, va_list args)
|
||||||
|
{
|
||||||
|
static char buf[MAXSTR];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do the printf into buf
|
||||||
|
*/
|
||||||
|
vsprintf(buf, fmt, args);
|
||||||
|
if (strlen(buf) + newpos >= MAXMSG)
|
||||||
|
endmsg();
|
||||||
|
strcat(msgbuf, buf);
|
||||||
|
newpos = (int) strlen(msgbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* step_ok:
|
||||||
|
* Returns true if it is ok to step on ch
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
step_ok(int ch)
|
||||||
|
{
|
||||||
|
switch (ch)
|
||||||
|
{
|
||||||
|
case ' ':
|
||||||
|
case '|':
|
||||||
|
case '-':
|
||||||
|
return FALSE;
|
||||||
|
default:
|
||||||
|
return (!isalpha(ch));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* readchar:
|
||||||
|
* Reads and returns a character, checking for gross input errors
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
readchar(void)
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
ch = md_readchar(stdscr);
|
||||||
|
|
||||||
|
if (ch == 3)
|
||||||
|
{
|
||||||
|
quit(0);
|
||||||
|
return(27);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
wreadchar(WINDOW *win)
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
ch = md_readchar(win);
|
||||||
|
|
||||||
|
if (ch == 3)
|
||||||
|
{
|
||||||
|
quit(0);
|
||||||
|
return(27);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* status:
|
||||||
|
* Display the important stats line. Keep the cursor where it was.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
status(void)
|
||||||
|
{
|
||||||
|
int oy, ox, temp;
|
||||||
|
static int hpwidth = 0;
|
||||||
|
static int s_hungry = 0;
|
||||||
|
static int s_lvl = 0;
|
||||||
|
static int s_pur = -1;
|
||||||
|
static int s_hp = 0;
|
||||||
|
static int s_arm = 0;
|
||||||
|
static int s_str = 0;
|
||||||
|
static int s_exp = 0;
|
||||||
|
static char *state_name[] =
|
||||||
|
{
|
||||||
|
"", "Hungry", "Weak", "Faint"
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If nothing has changed since the last status, don't
|
||||||
|
* bother.
|
||||||
|
*/
|
||||||
|
temp = (cur_armor != NULL ? cur_armor->o_arm : pstats.s_arm);
|
||||||
|
if (s_hp == pstats.s_hpt && s_exp == pstats.s_exp && s_pur == purse
|
||||||
|
&& s_arm == temp && s_str == pstats.s_str && s_lvl == level
|
||||||
|
&& s_hungry == hungry_state
|
||||||
|
&& !stat_msg
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
|
||||||
|
s_arm = temp;
|
||||||
|
|
||||||
|
getyx(stdscr, oy, ox);
|
||||||
|
if (s_hp != max_hp)
|
||||||
|
{
|
||||||
|
temp = max_hp;
|
||||||
|
s_hp = max_hp;
|
||||||
|
for (hpwidth = 0; temp; hpwidth++)
|
||||||
|
temp /= 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Save current status
|
||||||
|
*/
|
||||||
|
s_lvl = level;
|
||||||
|
s_pur = purse;
|
||||||
|
s_hp = pstats.s_hpt;
|
||||||
|
s_str = pstats.s_str;
|
||||||
|
s_exp = pstats.s_exp;
|
||||||
|
s_hungry = hungry_state;
|
||||||
|
|
||||||
|
if (stat_msg)
|
||||||
|
{
|
||||||
|
move(0, 0);
|
||||||
|
msg("Level: %d Gold: %-5d Hp: %*d(%*d) Str: %2d(%d) Arm: %-2d Exp: %d/%d %s",
|
||||||
|
level, purse, hpwidth, pstats.s_hpt, hpwidth, max_hp, pstats.s_str,
|
||||||
|
max_stats.s_str, 10 - s_arm, pstats.s_lvl, pstats.s_exp,
|
||||||
|
state_name[hungry_state]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
move(STATLINE, 0);
|
||||||
|
|
||||||
|
printw("Level: %d Gold: %-5d Hp: %*d(%*d) Str: %2d(%d) Arm: %-2d Exp: %d/%d %s",
|
||||||
|
level, purse, hpwidth, pstats.s_hpt, hpwidth, max_hp, pstats.s_str,
|
||||||
|
max_stats.s_str, 10 - s_arm, pstats.s_lvl, pstats.s_exp,
|
||||||
|
state_name[hungry_state]);
|
||||||
|
}
|
||||||
|
|
||||||
|
clrtoeol();
|
||||||
|
move(oy, ox);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* wait_for
|
||||||
|
* Sit around until the guy types the right key
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
wait_for(WINDOW *win, int ch)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
|
||||||
|
if (ch == '\n')
|
||||||
|
while ((c = wreadchar(win)) != '\n' && c != '\r')
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
while (wreadchar(win) != ch)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* show_win:
|
||||||
|
* Function used to display a window and wait before returning
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
show_win(const char *message)
|
||||||
|
{
|
||||||
|
WINDOW *win;
|
||||||
|
|
||||||
|
win = hw;
|
||||||
|
wmove(win, 0, 0);
|
||||||
|
waddstr(win, message);
|
||||||
|
touchwin(win);
|
||||||
|
wrefresh(win);
|
||||||
|
wait_for(win, ' ');
|
||||||
|
clearok(curscr, TRUE);
|
||||||
|
touchwin(stdscr);
|
||||||
|
}
|
||||||
116
rogue5/list.c
Normal file
116
rogue5/list.c
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
* Functions for dealing with linked lists of goodies
|
||||||
|
*
|
||||||
|
* @(#)list.c 4.12 (Berkeley) 02/05/99
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <curses.h>
|
||||||
|
#include "rogue.h"
|
||||||
|
|
||||||
|
#ifdef MASTER
|
||||||
|
int total = 0; /* total dynamic memory bytes */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* detach:
|
||||||
|
* takes an item out of whatever linked list it might be in
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
_detach(THING **list, THING *item)
|
||||||
|
{
|
||||||
|
if (*list == item)
|
||||||
|
*list = next(item);
|
||||||
|
if (prev(item) != NULL)
|
||||||
|
item->l_prev->l_next = next(item);
|
||||||
|
if (next(item) != NULL)
|
||||||
|
item->l_next->l_prev = prev(item);
|
||||||
|
item->l_next = NULL;
|
||||||
|
item->l_prev = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _attach:
|
||||||
|
* add an item to the head of a list
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
_attach(THING **list, THING *item)
|
||||||
|
{
|
||||||
|
if (*list != NULL)
|
||||||
|
{
|
||||||
|
item->l_next = *list;
|
||||||
|
(*list)->l_prev = item;
|
||||||
|
item->l_prev = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item->l_next = NULL;
|
||||||
|
item->l_prev = NULL;
|
||||||
|
}
|
||||||
|
*list = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* _free_list:
|
||||||
|
* Throw the whole blamed thing away
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
_free_list(THING **ptr)
|
||||||
|
{
|
||||||
|
THING *item;
|
||||||
|
|
||||||
|
while (*ptr != NULL)
|
||||||
|
{
|
||||||
|
item = *ptr;
|
||||||
|
*ptr = next(item);
|
||||||
|
discard(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* discard:
|
||||||
|
* Free up an item
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
discard(THING *item)
|
||||||
|
{
|
||||||
|
#ifdef MASTER
|
||||||
|
total--;
|
||||||
|
#endif
|
||||||
|
free(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* new_item
|
||||||
|
* Get a new item with a specified size
|
||||||
|
*/
|
||||||
|
THING *
|
||||||
|
new_item(void)
|
||||||
|
{
|
||||||
|
THING *item;
|
||||||
|
|
||||||
|
if ((item = calloc(1, sizeof *item)) == NULL) {
|
||||||
|
#ifdef MASTER
|
||||||
|
msg("ran out of memory after %d items", total);
|
||||||
|
#endif
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MASTER
|
||||||
|
total++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
item->l_next = NULL;
|
||||||
|
item->l_prev = NULL;
|
||||||
|
return item;
|
||||||
|
}
|
||||||
454
rogue5/mach_dep.c
Normal file
454
rogue5/mach_dep.c
Normal file
|
|
@ -0,0 +1,454 @@
|
||||||
|
/*
|
||||||
|
* Various installation dependent routines
|
||||||
|
*
|
||||||
|
* @(#)mach_dep.c 4.37 (Berkeley) 05/23/83
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The various tuneable defines are:
|
||||||
|
*
|
||||||
|
* SCOREFILE Where/if the score file should live.
|
||||||
|
* ALLSCORES Score file is top ten scores, not top ten
|
||||||
|
* players. This is only useful when only a few
|
||||||
|
* people will be playing; otherwise the score file
|
||||||
|
* gets hogged by just a few people.
|
||||||
|
* NUMSCORES Number of scores in the score file (default 10).
|
||||||
|
* NUMNAME String version of NUMSCORES (first character
|
||||||
|
* should be capitalized) (default "Ten").
|
||||||
|
* MAXLOAD What (if any) the maximum load average should be
|
||||||
|
* when people are playing. Since it is divided
|
||||||
|
* by 10, to specify a load limit of 4.0, MAXLOAD
|
||||||
|
* should be "40". If defined, then
|
||||||
|
* LOADAV Should it use it's own routine to get
|
||||||
|
* the load average?
|
||||||
|
* NAMELIST If so, where does the system namelist
|
||||||
|
* hide?
|
||||||
|
* MAXUSERS What (if any) the maximum user count should be
|
||||||
|
* when people are playing. If defined, then
|
||||||
|
* UCOUNT Should it use it's own routine to count
|
||||||
|
* users?
|
||||||
|
* UTMP If so, where does the user list hide?
|
||||||
|
* CHECKTIME How often/if it should check during the game
|
||||||
|
* for high load average.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <curses.h>
|
||||||
|
#include "extern.h"
|
||||||
|
|
||||||
|
#define NOOP(x) (x += 0)
|
||||||
|
|
||||||
|
# ifndef NUMSCORES
|
||||||
|
# define NUMSCORES 10
|
||||||
|
# define NUMNAME "Ten"
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#ifdef CHECKTIME
|
||||||
|
static int num_checks = 0; /* times we've gone over in checkout() */
|
||||||
|
#endif /* CHECKTIME */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* init_check:
|
||||||
|
* Check out too see if it is proper to play the game now
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
init_check(void)
|
||||||
|
{
|
||||||
|
#if defined(MAXLOAD) || defined(MAXUSERS)
|
||||||
|
if (too_much())
|
||||||
|
{
|
||||||
|
printf("Sorry, %s, but the system is too loaded now.\n", whoami);
|
||||||
|
printf("Try again later. Meanwhile, why not enjoy a%s %s?\n",
|
||||||
|
vowelstr(fruit), fruit);
|
||||||
|
if (author())
|
||||||
|
printf("However, since you're a good guy, it's up to you\n");
|
||||||
|
else
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* open_score:
|
||||||
|
* Open up the score file for future use
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
open_score(void)
|
||||||
|
{
|
||||||
|
#ifdef SCOREFILE
|
||||||
|
char *scorefile = SCOREFILE;
|
||||||
|
|
||||||
|
numscores = NUMSCORES;
|
||||||
|
Numname = NUMNAME;
|
||||||
|
|
||||||
|
#ifdef ALLSCORES
|
||||||
|
allscore = TRUE;
|
||||||
|
#else /* ALLSCORES */
|
||||||
|
allscore = FALSE;
|
||||||
|
#endif /* ALLSCORES */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We drop setgid privileges after opening the score file, so subsequent
|
||||||
|
* open()'s will fail. Just reuse the earlier filehandle.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (scoreboard != NULL) {
|
||||||
|
rewind(scoreboard);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
scoreboard = fopen(scorefile, "r+");
|
||||||
|
|
||||||
|
if ((scoreboard == NULL) && (errno == ENOENT))
|
||||||
|
{
|
||||||
|
scoreboard = fopen(scorefile, "w+");
|
||||||
|
md_chmod(scorefile,0664);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scoreboard == NULL) {
|
||||||
|
fprintf(stderr, "Could not open %s for writing: %s\n", scorefile, strerror(errno));
|
||||||
|
fflush(stderr);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
scoreboard = NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* getltchars:
|
||||||
|
* Get the local tty chars for later use
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
getltchars(void)
|
||||||
|
{
|
||||||
|
got_ltc = TRUE;
|
||||||
|
orig_dsusp = md_dsuspchar();
|
||||||
|
md_setdsuspchar( md_suspchar() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* setup:
|
||||||
|
* Get starting setup for all games
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
setup(void)
|
||||||
|
{
|
||||||
|
#ifdef DUMP
|
||||||
|
md_onsignal_autosave();
|
||||||
|
#else
|
||||||
|
md_onsignal_default();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CHECKTIME
|
||||||
|
md_start_checkout_timer(CHECKTIME*60);
|
||||||
|
num_checks = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
raw(); /* Raw mode */
|
||||||
|
noecho(); /* Echo off */
|
||||||
|
keypad(stdscr,1);
|
||||||
|
getltchars(); /* get the local tty chars */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* resetltchars:
|
||||||
|
* Reset the local tty chars to original values.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
resetltchars(void)
|
||||||
|
{
|
||||||
|
if (got_ltc) {
|
||||||
|
md_setdsuspchar(orig_dsusp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* playltchars:
|
||||||
|
* Set local tty chars to the values we use when playing.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
playltchars(void)
|
||||||
|
{
|
||||||
|
if (got_ltc) {
|
||||||
|
md_setdsuspchar( md_suspchar() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* start_score:
|
||||||
|
* Start the scoring sequence
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
start_score(void)
|
||||||
|
{
|
||||||
|
#ifdef CHECKTIME
|
||||||
|
md_stop_checkout_timer();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* is_symlink:
|
||||||
|
* See if the file has a symbolic link
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
is_symlink(char *sp)
|
||||||
|
{
|
||||||
|
#ifdef S_IFLNK
|
||||||
|
struct stat sbuf2;
|
||||||
|
|
||||||
|
if (lstat(sp, &sbuf2) < 0)
|
||||||
|
return FALSE;
|
||||||
|
else
|
||||||
|
return ((sbuf2.st_mode & S_IFMT) != S_IFREG);
|
||||||
|
#else
|
||||||
|
NOOP(sp);
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(MAXLOAD) || defined(MAXUSERS)
|
||||||
|
/*
|
||||||
|
* too_much:
|
||||||
|
* See if the system is being used too much for this game
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
too_much(void)
|
||||||
|
{
|
||||||
|
#ifdef MAXLOAD
|
||||||
|
double avec[3];
|
||||||
|
#else
|
||||||
|
int cnt;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MAXLOAD
|
||||||
|
md_loadav(avec);
|
||||||
|
if (avec[1] > (MAXLOAD / 10.0))
|
||||||
|
return TRUE;
|
||||||
|
#endif
|
||||||
|
#ifdef MAXUSERS
|
||||||
|
if (ucount() > MAXUSERS)
|
||||||
|
return TRUE;
|
||||||
|
#endif
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* author:
|
||||||
|
* See if a user is an author of the program
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
author(void)
|
||||||
|
{
|
||||||
|
#ifdef MASTER
|
||||||
|
if (wizard)
|
||||||
|
return TRUE;
|
||||||
|
#endif
|
||||||
|
switch (md_getuid())
|
||||||
|
{
|
||||||
|
case -1:
|
||||||
|
return TRUE;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CHECKTIME
|
||||||
|
/*
|
||||||
|
* checkout:
|
||||||
|
* Check each CHECKTIME seconds to see if the load is too high
|
||||||
|
*/
|
||||||
|
|
||||||
|
checkout(int sig)
|
||||||
|
{
|
||||||
|
char *msgs[] = {
|
||||||
|
"The load is too high to be playing. Please leave in %0.1f minutes",
|
||||||
|
"Please save your game. You have %0.1f minutes",
|
||||||
|
"Last warning. You have %0.1f minutes to leave",
|
||||||
|
};
|
||||||
|
int checktime;
|
||||||
|
|
||||||
|
if (too_much())
|
||||||
|
{
|
||||||
|
if (author())
|
||||||
|
{
|
||||||
|
num_checks = 1;
|
||||||
|
chmsg("The load is rather high, O exaulted one");
|
||||||
|
}
|
||||||
|
else if (num_checks++ == 3)
|
||||||
|
fatal("Sorry. You took too long. You are dead\n");
|
||||||
|
checktime = (CHECKTIME * 60) / num_checks;
|
||||||
|
chmsg(msgs[num_checks - 1], ((double) checktime / 60.0));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (num_checks)
|
||||||
|
{
|
||||||
|
num_checks = 0;
|
||||||
|
chmsg("The load has dropped back down. You have a reprieve");
|
||||||
|
}
|
||||||
|
checktime = (CHECKTIME * 60);
|
||||||
|
}
|
||||||
|
|
||||||
|
md_start_checkout_timer(checktime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* chmsg:
|
||||||
|
* checkout()'s version of msg. If we are in the middle of a
|
||||||
|
* shell, do a printf instead of a msg to a the refresh.
|
||||||
|
*/
|
||||||
|
/* VARARGS1 */
|
||||||
|
|
||||||
|
chmsg(char *fmt, int arg)
|
||||||
|
{
|
||||||
|
if (!in_shell)
|
||||||
|
msg(fmt, arg);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf(fmt, arg);
|
||||||
|
putchar('\n');
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef UCOUNT
|
||||||
|
/*
|
||||||
|
* ucount:
|
||||||
|
* count number of users on the system
|
||||||
|
*/
|
||||||
|
#include <utmp.h>
|
||||||
|
|
||||||
|
struct utmp buf;
|
||||||
|
|
||||||
|
int
|
||||||
|
ucount(void)
|
||||||
|
{
|
||||||
|
struct utmp *up;
|
||||||
|
FILE *utmp;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
if ((utmp = fopen(UTMP, "r")) == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
up = &buf;
|
||||||
|
count = 0;
|
||||||
|
|
||||||
|
while (fread(up, 1, sizeof (*up), utmp) > 0)
|
||||||
|
if (buf.ut_name[0] != '\0')
|
||||||
|
count++;
|
||||||
|
fclose(utmp);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* lock_sc:
|
||||||
|
* lock the score file. If it takes too long, ask the user if
|
||||||
|
* they care to wait. Return TRUE if the lock is successful.
|
||||||
|
*/
|
||||||
|
static FILE *lfd = NULL;
|
||||||
|
int
|
||||||
|
lock_sc(void)
|
||||||
|
{
|
||||||
|
#if defined(SCOREFILE) && defined(LOCKFILE)
|
||||||
|
int cnt;
|
||||||
|
struct stat sbuf;
|
||||||
|
char *lockfile = LOCKFILE;
|
||||||
|
|
||||||
|
over:
|
||||||
|
if ((lfd=fopen(lockfile, "w+")) != NULL)
|
||||||
|
return TRUE;
|
||||||
|
for (cnt = 0; cnt < 5; cnt++)
|
||||||
|
{
|
||||||
|
md_sleep(1);
|
||||||
|
if ((lfd=fopen(lockfile, "w+")) != NULL)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
if (stat(lockfile, &sbuf) < 0)
|
||||||
|
{
|
||||||
|
lfd=fopen(lockfile, "w+");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
if (time(NULL) - sbuf.st_mtime > 10)
|
||||||
|
{
|
||||||
|
if (md_unlink(lockfile) < 0)
|
||||||
|
return FALSE;
|
||||||
|
goto over;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("The score file is very busy. Do you want to wait longer\n");
|
||||||
|
printf("for it to become free so your score can get posted?\n");
|
||||||
|
printf("If so, type \"y\"\n");
|
||||||
|
(void) fgets(prbuf, MAXSTR, stdin);
|
||||||
|
if (prbuf[0] == 'y')
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if ((lfd=fopen(lockfile, "w+")) != 0)
|
||||||
|
return TRUE;
|
||||||
|
if (stat(lockfile, &sbuf) < 0)
|
||||||
|
{
|
||||||
|
lfd=fopen(lockfile, "w+");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
if (time(NULL) - sbuf.st_mtime > 10)
|
||||||
|
{
|
||||||
|
if (md_unlink(lockfile) < 0)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
md_sleep(1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
return TRUE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* unlock_sc:
|
||||||
|
* Unlock the score file
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
unlock_sc(void)
|
||||||
|
{
|
||||||
|
#if defined(SCOREFILE) && defined(LOCKFILE)
|
||||||
|
if (lfd != NULL)
|
||||||
|
fclose(lfd);
|
||||||
|
lfd = NULL;
|
||||||
|
md_unlink(LOCKFILE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* flush_type:
|
||||||
|
* Flush typeahead for traps, etc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
flush_type(void)
|
||||||
|
{
|
||||||
|
flushinp();
|
||||||
|
}
|
||||||
397
rogue5/main.c
Normal file
397
rogue5/main.c
Normal file
|
|
@ -0,0 +1,397 @@
|
||||||
|
/*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*
|
||||||
|
* @(#)main.c 4.22 (Berkeley) 02/05/99
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <curses.h>
|
||||||
|
#include "rogue.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* main:
|
||||||
|
* The main program, of course
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
char *env;
|
||||||
|
time_t lowtime;
|
||||||
|
|
||||||
|
md_init();
|
||||||
|
|
||||||
|
#ifdef MASTER
|
||||||
|
/*
|
||||||
|
* Check to see if he is a wizard
|
||||||
|
*/
|
||||||
|
if (argc >= 2 && argv[1][0] == '\0')
|
||||||
|
if (strcmp(PASSWD, md_crypt(md_getpass("wizard's password: "), "mT")) == 0)
|
||||||
|
{
|
||||||
|
wizard = TRUE;
|
||||||
|
player.t_flags |= SEEMONST;
|
||||||
|
argv++;
|
||||||
|
argc--;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get home and options from environment
|
||||||
|
*/
|
||||||
|
|
||||||
|
strcpy(home, md_gethomedir());
|
||||||
|
|
||||||
|
if (strlen(home) > MAXSTR - strlen("rogue.save") - 1)
|
||||||
|
*home = 0;
|
||||||
|
|
||||||
|
strcpy(file_name, home);
|
||||||
|
strcat(file_name, "rogue.save");
|
||||||
|
|
||||||
|
if ((env = getenv("ROGUEOPTS")) != NULL)
|
||||||
|
parse_opts(env);
|
||||||
|
if (env == NULL || whoami[0] == '\0')
|
||||||
|
strucpy(whoami, md_getusername(), strlen(md_getusername()));
|
||||||
|
lowtime = time(NULL);
|
||||||
|
if (getenv("SEED") != NULL)
|
||||||
|
{
|
||||||
|
dnum = atoi(getenv("SEED"));
|
||||||
|
noscore = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dnum = (unsigned int) lowtime + md_getpid();
|
||||||
|
seed = dnum;
|
||||||
|
|
||||||
|
open_score();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Drop setuid/setgid after opening the scoreboard file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
md_normaluser();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check for print-score option
|
||||||
|
*/
|
||||||
|
|
||||||
|
md_normaluser(); /* we drop any setgid/setuid priveldges here */
|
||||||
|
|
||||||
|
if (argc == 2)
|
||||||
|
{
|
||||||
|
if (strcmp(argv[1], "-s") == 0)
|
||||||
|
{
|
||||||
|
noscore = TRUE;
|
||||||
|
score(0, -1, 0);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
else if (strcmp(argv[1], "-d") == 0)
|
||||||
|
{
|
||||||
|
dnum = rnd(100); /* throw away some rnd()s to break patterns */
|
||||||
|
while (--dnum)
|
||||||
|
rnd(100);
|
||||||
|
purse = rnd(100) + 1;
|
||||||
|
level = rnd(100) + 1;
|
||||||
|
initscr();
|
||||||
|
getltchars();
|
||||||
|
death(death_monst());
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init_check(); /* check for legal startup */
|
||||||
|
if (argc == 2)
|
||||||
|
if (!restore(argv[1])) /* Note: restore will never return */
|
||||||
|
my_exit(1);
|
||||||
|
#ifdef MASTER
|
||||||
|
if (wizard)
|
||||||
|
printf("Hello %s, welcome to dungeon #%d", whoami, dnum);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
printf("Hello %s, just a moment while I dig the dungeon...", whoami);
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
initscr(); /* Start up cursor package */
|
||||||
|
init_probs(); /* Set up prob tables for objects */
|
||||||
|
init_player(); /* Set up initial player stats */
|
||||||
|
init_names(); /* Set up names of scrolls */
|
||||||
|
init_colors(); /* Set up colors of potions */
|
||||||
|
init_stones(); /* Set up stone settings of rings */
|
||||||
|
init_materials(); /* Set up materials of wands */
|
||||||
|
setup();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The screen must be at least NUMLINES x NUMCOLS
|
||||||
|
*/
|
||||||
|
if (LINES < NUMLINES || COLS < NUMCOLS)
|
||||||
|
{
|
||||||
|
printf("\nSorry, the screen must be at least %dx%d\n", NUMLINES, NUMCOLS);
|
||||||
|
endwin();
|
||||||
|
my_exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up windows
|
||||||
|
*/
|
||||||
|
hw = newwin(LINES, COLS, 0, 0);
|
||||||
|
idlok(stdscr, TRUE);
|
||||||
|
idlok(hw, TRUE);
|
||||||
|
#ifdef MASTER
|
||||||
|
noscore = wizard;
|
||||||
|
#endif
|
||||||
|
new_level(); /* Draw current level */
|
||||||
|
/*
|
||||||
|
* Start up daemons and fuses
|
||||||
|
*/
|
||||||
|
start_daemon(runners, 0, AFTER);
|
||||||
|
start_daemon(doctor, 0, AFTER);
|
||||||
|
fuse(swander, 0, WANDERTIME, AFTER);
|
||||||
|
start_daemon(stomach, 0, AFTER);
|
||||||
|
playit();
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* endit:
|
||||||
|
* Exit the program abnormally.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
endit(int sig)
|
||||||
|
{
|
||||||
|
NOOP(sig);
|
||||||
|
fatal("Okay, bye bye!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fatal:
|
||||||
|
* Exit the program, printing a message.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
fatal(const char *s)
|
||||||
|
{
|
||||||
|
mvaddstr(LINES - 2, 0, s);
|
||||||
|
refresh();
|
||||||
|
endwin();
|
||||||
|
my_exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rnd:
|
||||||
|
* Pick a very random number.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
rnd(int range)
|
||||||
|
{
|
||||||
|
return range == 0 ? 0 : abs((int) RN) % range;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* roll:
|
||||||
|
* Roll a number of dice
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
roll(int number, int sides)
|
||||||
|
{
|
||||||
|
int dtotal = 0;
|
||||||
|
|
||||||
|
while (number--)
|
||||||
|
dtotal += rnd(sides)+1;
|
||||||
|
return dtotal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tstp:
|
||||||
|
* Handle stop and start signals
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
tstp(int ignored)
|
||||||
|
{
|
||||||
|
int y, x;
|
||||||
|
int oy, ox;
|
||||||
|
|
||||||
|
NOOP(ignored);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* leave nicely
|
||||||
|
*/
|
||||||
|
getyx(curscr, oy, ox);
|
||||||
|
mvcur(0, COLS - 1, LINES - 1, 0);
|
||||||
|
endwin();
|
||||||
|
resetltchars();
|
||||||
|
fflush(stdout);
|
||||||
|
md_tstpsignal();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* start back up again
|
||||||
|
*/
|
||||||
|
md_tstpresume();
|
||||||
|
raw();
|
||||||
|
noecho();
|
||||||
|
keypad(stdscr,1);
|
||||||
|
playltchars();
|
||||||
|
clearok(curscr, TRUE);
|
||||||
|
wrefresh(curscr);
|
||||||
|
getyx(curscr, y, x);
|
||||||
|
mvcur(y, x, oy, ox);
|
||||||
|
fflush(stdout);
|
||||||
|
curscr->_cury = oy;
|
||||||
|
curscr->_curx = ox;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* playit:
|
||||||
|
* The main loop of the program. Loop until the game is over,
|
||||||
|
* refreshing things and looking at the proper times.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
playit(void)
|
||||||
|
{
|
||||||
|
char *opts;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* set up defaults for slow terminals
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (baudrate() <= 1200)
|
||||||
|
{
|
||||||
|
terse = TRUE;
|
||||||
|
jump = TRUE;
|
||||||
|
see_floor = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (md_hasclreol())
|
||||||
|
inv_type = INV_CLEAR;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* parse environment declaration of options
|
||||||
|
*/
|
||||||
|
if ((opts = getenv("ROGUEOPTS")) != NULL)
|
||||||
|
parse_opts(opts);
|
||||||
|
|
||||||
|
|
||||||
|
oldpos = hero;
|
||||||
|
oldrp = roomin(&hero);
|
||||||
|
while (playing)
|
||||||
|
command(); /* Command execution */
|
||||||
|
endit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* quit:
|
||||||
|
* Have player make certain, then exit.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
quit(int sig)
|
||||||
|
{
|
||||||
|
int oy, ox;
|
||||||
|
|
||||||
|
NOOP(sig);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reset the signal in case we got here via an interrupt
|
||||||
|
*/
|
||||||
|
if (!q_comm)
|
||||||
|
mpos = 0;
|
||||||
|
getyx(curscr, oy, ox);
|
||||||
|
msg("really quit?");
|
||||||
|
if (readchar() == 'y')
|
||||||
|
{
|
||||||
|
signal(SIGINT, leave);
|
||||||
|
clear();
|
||||||
|
mvprintw(LINES - 2, 0, "You quit with %d gold pieces", purse);
|
||||||
|
move(LINES - 1, 0);
|
||||||
|
refresh();
|
||||||
|
score(purse, 1, 0);
|
||||||
|
my_exit(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
move(0, 0);
|
||||||
|
clrtoeol();
|
||||||
|
status();
|
||||||
|
move(oy, ox);
|
||||||
|
refresh();
|
||||||
|
mpos = 0;
|
||||||
|
count = 0;
|
||||||
|
to_death = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* leave:
|
||||||
|
* Leave quickly, but curteously
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
leave(int sig)
|
||||||
|
{
|
||||||
|
static char buf[BUFSIZ];
|
||||||
|
|
||||||
|
NOOP(sig);
|
||||||
|
|
||||||
|
setbuf(stdout, buf); /* throw away pending output */
|
||||||
|
|
||||||
|
if (!isendwin())
|
||||||
|
{
|
||||||
|
mvcur(0, COLS - 1, LINES - 1, 0);
|
||||||
|
endwin();
|
||||||
|
}
|
||||||
|
|
||||||
|
putchar('\n');
|
||||||
|
my_exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* shell:
|
||||||
|
* Let them escape for a while
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
shell(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Set the terminal back to original mode
|
||||||
|
*/
|
||||||
|
move(LINES-1, 0);
|
||||||
|
refresh();
|
||||||
|
endwin();
|
||||||
|
resetltchars();
|
||||||
|
putchar('\n');
|
||||||
|
in_shell = TRUE;
|
||||||
|
after = FALSE;
|
||||||
|
fflush(stdout);
|
||||||
|
/*
|
||||||
|
* Fork and do a shell
|
||||||
|
*/
|
||||||
|
md_shellescape();
|
||||||
|
|
||||||
|
noecho();
|
||||||
|
raw();
|
||||||
|
keypad(stdscr,1);
|
||||||
|
playltchars();
|
||||||
|
in_shell = FALSE;
|
||||||
|
clearok(stdscr, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* my_exit:
|
||||||
|
* Leave the process properly
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
my_exit(int st)
|
||||||
|
{
|
||||||
|
resetltchars();
|
||||||
|
exit(st);
|
||||||
|
}
|
||||||
|
|
||||||
1507
rogue5/mdport.c
Normal file
1507
rogue5/mdport.c
Normal file
File diff suppressed because it is too large
Load diff
600
rogue5/misc.c
Normal file
600
rogue5/misc.c
Normal file
|
|
@ -0,0 +1,600 @@
|
||||||
|
/*
|
||||||
|
* All sorts of miscellaneous routines
|
||||||
|
*
|
||||||
|
* @(#)misc.c 4.66 (Berkeley) 08/06/83
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <curses.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "rogue.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* look:
|
||||||
|
* A quick glance all around the player
|
||||||
|
*/
|
||||||
|
#undef DEBUG
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
look(int wakeup)
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
chtype ch;
|
||||||
|
THING *tp;
|
||||||
|
PLACE *pp;
|
||||||
|
struct room *rp;
|
||||||
|
int ey, ex;
|
||||||
|
int passcount;
|
||||||
|
int pfl, *fp, pch;
|
||||||
|
int sy, sx, sumhero = 0, diffhero = 0;
|
||||||
|
# ifdef DEBUG
|
||||||
|
static int done = FALSE;
|
||||||
|
|
||||||
|
if (done)
|
||||||
|
return;
|
||||||
|
done = TRUE;
|
||||||
|
# endif /* DEBUG */
|
||||||
|
passcount = 0;
|
||||||
|
rp = proom;
|
||||||
|
if (!ce(oldpos, hero))
|
||||||
|
{
|
||||||
|
erase_lamp(&oldpos, oldrp);
|
||||||
|
oldpos = hero;
|
||||||
|
oldrp = rp;
|
||||||
|
}
|
||||||
|
ey = hero.y + 1;
|
||||||
|
ex = hero.x + 1;
|
||||||
|
sx = hero.x - 1;
|
||||||
|
sy = hero.y - 1;
|
||||||
|
if (door_stop && !firstmove && running)
|
||||||
|
{
|
||||||
|
sumhero = hero.y + hero.x;
|
||||||
|
diffhero = hero.y - hero.x;
|
||||||
|
}
|
||||||
|
pp = INDEX(hero.y, hero.x);
|
||||||
|
pch = pp->p_ch;
|
||||||
|
pfl = pp->p_flags;
|
||||||
|
|
||||||
|
for (y = sy; y <= ey; y++)
|
||||||
|
if (y > 0 && y < NUMLINES - 1) for (x = sx; x <= ex; x++)
|
||||||
|
{
|
||||||
|
if (x < 0 || x >= NUMCOLS)
|
||||||
|
continue;
|
||||||
|
if (!on(player, ISBLIND))
|
||||||
|
{
|
||||||
|
if (y == hero.y && x == hero.x)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pp = INDEX(y, x);
|
||||||
|
ch = pp->p_ch;
|
||||||
|
if (ch == ' ') /* nothing need be done with a ' ' */
|
||||||
|
continue;
|
||||||
|
fp = &pp->p_flags;
|
||||||
|
if (pch != DOOR && ch != DOOR)
|
||||||
|
if ((pfl & F_PASS) != (*fp & F_PASS))
|
||||||
|
continue;
|
||||||
|
if (((*fp & F_PASS) || ch == DOOR) &&
|
||||||
|
((pfl & F_PASS) || pch == DOOR))
|
||||||
|
{
|
||||||
|
if (hero.x != x && hero.y != y &&
|
||||||
|
!step_ok(chat(y, hero.x)) && !step_ok(chat(hero.y, x)))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((tp = pp->p_monst) == NULL)
|
||||||
|
ch = trip_ch(y, x, ch);
|
||||||
|
else
|
||||||
|
if (on(player, SEEMONST) && on(*tp, ISINVIS))
|
||||||
|
{
|
||||||
|
if (door_stop && !firstmove)
|
||||||
|
running = FALSE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (wakeup)
|
||||||
|
wake_monster(y, x);
|
||||||
|
if (see_monst(tp))
|
||||||
|
{
|
||||||
|
if (on(player, ISHALU))
|
||||||
|
ch = rnd(26) + 'A';
|
||||||
|
else
|
||||||
|
ch = tp->t_disguise;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (on(player, ISBLIND) && (y != hero.y || x != hero.x))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
move(y, x);
|
||||||
|
|
||||||
|
if ((proom->r_flags & ISDARK) && !see_floor && ch == FLOOR)
|
||||||
|
ch = ' ';
|
||||||
|
|
||||||
|
if (tp != NULL || ch != CCHAR( inch() ))
|
||||||
|
addch(ch);
|
||||||
|
|
||||||
|
if (door_stop && !firstmove && running)
|
||||||
|
{
|
||||||
|
switch (runch)
|
||||||
|
{
|
||||||
|
case 'h':
|
||||||
|
if (x == ex)
|
||||||
|
continue;
|
||||||
|
when 'j':
|
||||||
|
if (y == sy)
|
||||||
|
continue;
|
||||||
|
when 'k':
|
||||||
|
if (y == ey)
|
||||||
|
continue;
|
||||||
|
when 'l':
|
||||||
|
if (x == sx)
|
||||||
|
continue;
|
||||||
|
when 'y':
|
||||||
|
if ((y + x) - sumhero >= 1)
|
||||||
|
continue;
|
||||||
|
when 'u':
|
||||||
|
if ((y - x) - diffhero >= 1)
|
||||||
|
continue;
|
||||||
|
when 'n':
|
||||||
|
if ((y + x) - sumhero <= -1)
|
||||||
|
continue;
|
||||||
|
when 'b':
|
||||||
|
if ((y - x) - diffhero <= -1)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (ch)
|
||||||
|
{
|
||||||
|
case DOOR:
|
||||||
|
if (x == hero.x || y == hero.y)
|
||||||
|
running = FALSE;
|
||||||
|
break;
|
||||||
|
case PASSAGE:
|
||||||
|
if (x == hero.x || y == hero.y)
|
||||||
|
passcount++;
|
||||||
|
break;
|
||||||
|
case FLOOR:
|
||||||
|
case '|':
|
||||||
|
case '-':
|
||||||
|
case ' ':
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
running = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (door_stop && !firstmove && passcount > 1)
|
||||||
|
running = FALSE;
|
||||||
|
if (!running || !jump)
|
||||||
|
mvaddch(hero.y, hero.x, PLAYER);
|
||||||
|
# ifdef DEBUG
|
||||||
|
done = FALSE;
|
||||||
|
# endif /* DEBUG */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* trip_ch:
|
||||||
|
* Return the character appropriate for this space, taking into
|
||||||
|
* account whether or not the player is tripping.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
trip_ch(int y, int x, int ch)
|
||||||
|
{
|
||||||
|
if (on(player, ISHALU) && after)
|
||||||
|
switch (ch)
|
||||||
|
{
|
||||||
|
case FLOOR:
|
||||||
|
case ' ':
|
||||||
|
case PASSAGE:
|
||||||
|
case '-':
|
||||||
|
case '|':
|
||||||
|
case DOOR:
|
||||||
|
case TRAP:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (y != stairs.y || x != stairs.x || !seenstairs)
|
||||||
|
ch = rnd_thing();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* erase_lamp:
|
||||||
|
* Erase the area shown by a lamp in a dark room.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
erase_lamp(const coord *pos, const struct room *rp)
|
||||||
|
{
|
||||||
|
int y, x, ey, sy, ex;
|
||||||
|
|
||||||
|
if (!(see_floor && (rp->r_flags & (ISGONE|ISDARK)) == ISDARK
|
||||||
|
&& !on(player,ISBLIND)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ey = pos->y + 1;
|
||||||
|
ex = pos->x + 1;
|
||||||
|
sy = pos->y - 1;
|
||||||
|
for (x = pos->x - 1; x <= ex; x++)
|
||||||
|
for (y = sy; y <= ey; y++)
|
||||||
|
{
|
||||||
|
if (y == hero.y && x == hero.x)
|
||||||
|
continue;
|
||||||
|
move(y, x);
|
||||||
|
if (CCHAR( inch() ) == FLOOR)
|
||||||
|
addch(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* show_floor:
|
||||||
|
* Should we show the floor in her room at this time?
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
show_floor(void)
|
||||||
|
{
|
||||||
|
if ((proom->r_flags & (ISGONE|ISDARK)) == ISDARK && !on(player, ISBLIND))
|
||||||
|
return see_floor;
|
||||||
|
else
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* find_obj:
|
||||||
|
* Find the unclaimed object at y, x
|
||||||
|
*/
|
||||||
|
THING *
|
||||||
|
find_obj(int y, int x)
|
||||||
|
{
|
||||||
|
THING *obj;
|
||||||
|
|
||||||
|
for (obj = lvl_obj; obj != NULL; obj = next(obj))
|
||||||
|
{
|
||||||
|
if (obj->o_pos.y == y && obj->o_pos.x == x)
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
#ifdef MASTER
|
||||||
|
sprintf(prbuf, "Non-object %d,%d", y, x);
|
||||||
|
msg(prbuf);
|
||||||
|
return NULL;
|
||||||
|
#else
|
||||||
|
/* NOTREACHED */
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* eat:
|
||||||
|
* She wants to eat something, so let her try
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
eat(void)
|
||||||
|
{
|
||||||
|
THING *obj;
|
||||||
|
|
||||||
|
if ((obj = get_item("eat", FOOD)) == NULL)
|
||||||
|
return;
|
||||||
|
if (obj->o_type != FOOD)
|
||||||
|
{
|
||||||
|
if (!terse)
|
||||||
|
msg("ugh, you would get ill if you ate that");
|
||||||
|
else
|
||||||
|
msg("that's Inedible!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (food_left < 0)
|
||||||
|
food_left = 0;
|
||||||
|
if ((food_left += HUNGERTIME - 200 + rnd(400)) > STOMACHSIZE)
|
||||||
|
food_left = STOMACHSIZE;
|
||||||
|
hungry_state = 0;
|
||||||
|
if (obj == cur_weapon)
|
||||||
|
cur_weapon = NULL;
|
||||||
|
if (obj->o_which == 1)
|
||||||
|
msg("my, that was a yummy %s", fruit);
|
||||||
|
else
|
||||||
|
if (rnd(100) > 70)
|
||||||
|
{
|
||||||
|
pstats.s_exp++;
|
||||||
|
msg("%s, this food tastes awful", choose_str("bummer", "yuk"));
|
||||||
|
check_level();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
msg("%s, that tasted good", choose_str("oh, wow", "yum"));
|
||||||
|
leave_pack(obj, FALSE, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check_level:
|
||||||
|
* Check to see if the guy has gone up a level.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
check_level(void)
|
||||||
|
{
|
||||||
|
int i, add, olevel;
|
||||||
|
|
||||||
|
for (i = 0; e_levels[i] != 0; i++)
|
||||||
|
if (e_levels[i] > pstats.s_exp)
|
||||||
|
break;
|
||||||
|
i++;
|
||||||
|
olevel = pstats.s_lvl;
|
||||||
|
pstats.s_lvl = i;
|
||||||
|
if (i > olevel)
|
||||||
|
{
|
||||||
|
add = roll(i - olevel, 10);
|
||||||
|
max_hp += add;
|
||||||
|
pstats.s_hpt += add;
|
||||||
|
msg("welcome to level %d", i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* chg_str:
|
||||||
|
* used to modify the playes strength. It keeps track of the
|
||||||
|
* highest it has been, just in case
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
chg_str(int amt)
|
||||||
|
{
|
||||||
|
int comp;
|
||||||
|
|
||||||
|
if (amt == 0)
|
||||||
|
return;
|
||||||
|
add_str(&pstats.s_str, amt);
|
||||||
|
comp = pstats.s_str;
|
||||||
|
if (ISRING(LEFT, R_ADDSTR))
|
||||||
|
add_str(&comp, -cur_ring[LEFT]->o_arm);
|
||||||
|
if (ISRING(RIGHT, R_ADDSTR))
|
||||||
|
add_str(&comp, -cur_ring[RIGHT]->o_arm);
|
||||||
|
if (comp > max_stats.s_str)
|
||||||
|
max_stats.s_str = comp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* add_str:
|
||||||
|
* Perform the actual add, checking upper and lower bound limits
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
add_str(int *sp, int amt)
|
||||||
|
{
|
||||||
|
if ((*sp += amt) < 3)
|
||||||
|
*sp = 3;
|
||||||
|
else if (*sp > 31)
|
||||||
|
*sp = 31;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* add_haste:
|
||||||
|
* Add a haste to the player
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
add_haste(int potion)
|
||||||
|
{
|
||||||
|
if (on(player, ISHASTE))
|
||||||
|
{
|
||||||
|
no_command += rnd(8);
|
||||||
|
player.t_flags &= ~(ISRUN|ISHASTE);
|
||||||
|
extinguish(nohaste);
|
||||||
|
msg("you faint from exhaustion");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
player.t_flags |= ISHASTE;
|
||||||
|
if (potion)
|
||||||
|
fuse(nohaste, 0, rnd(4)+4, AFTER);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* aggravate:
|
||||||
|
* Aggravate all the monsters on this level
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
aggravate(void)
|
||||||
|
{
|
||||||
|
THING *mp;
|
||||||
|
|
||||||
|
for (mp = mlist; mp != NULL; mp = next(mp))
|
||||||
|
runto(&mp->t_pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vowelstr:
|
||||||
|
* For printfs: if string starts with a vowel, return "n" for an
|
||||||
|
* "an".
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
vowelstr(const char *str)
|
||||||
|
{
|
||||||
|
switch (*str)
|
||||||
|
{
|
||||||
|
case 'a': case 'A':
|
||||||
|
case 'e': case 'E':
|
||||||
|
case 'i': case 'I':
|
||||||
|
case 'o': case 'O':
|
||||||
|
case 'u': case 'U':
|
||||||
|
return "n";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* is_current:
|
||||||
|
* See if the object is one of the currently used items
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
is_current(const THING *obj)
|
||||||
|
{
|
||||||
|
if (obj == NULL)
|
||||||
|
return FALSE;
|
||||||
|
if (obj == cur_armor || obj == cur_weapon || obj == cur_ring[LEFT]
|
||||||
|
|| obj == cur_ring[RIGHT])
|
||||||
|
{
|
||||||
|
if (!terse)
|
||||||
|
addmsg("That's already ");
|
||||||
|
msg("in use");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get_dir:
|
||||||
|
* Set up the direction co_ordinate for use in varios "prefix"
|
||||||
|
* commands
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
get_dir(void)
|
||||||
|
{
|
||||||
|
char *prompt;
|
||||||
|
int gotit;
|
||||||
|
static coord last_delt= {0,0};
|
||||||
|
|
||||||
|
if (again && last_dir != '\0')
|
||||||
|
{
|
||||||
|
delta.y = last_delt.y;
|
||||||
|
delta.x = last_delt.x;
|
||||||
|
dir_ch = last_dir;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!terse)
|
||||||
|
msg(prompt = "which direction? ");
|
||||||
|
else
|
||||||
|
prompt = "direction: ";
|
||||||
|
do
|
||||||
|
{
|
||||||
|
gotit = TRUE;
|
||||||
|
switch (dir_ch = readchar())
|
||||||
|
{
|
||||||
|
case 'h': case'H': delta.y = 0; delta.x = -1;
|
||||||
|
when 'j': case'J': delta.y = 1; delta.x = 0;
|
||||||
|
when 'k': case'K': delta.y = -1; delta.x = 0;
|
||||||
|
when 'l': case'L': delta.y = 0; delta.x = 1;
|
||||||
|
when 'y': case'Y': delta.y = -1; delta.x = -1;
|
||||||
|
when 'u': case'U': delta.y = -1; delta.x = 1;
|
||||||
|
when 'b': case'B': delta.y = 1; delta.x = -1;
|
||||||
|
when 'n': case'N': delta.y = 1; delta.x = 1;
|
||||||
|
when ESCAPE: last_dir = '\0'; reset_last(); msg(""); return FALSE;
|
||||||
|
otherwise:
|
||||||
|
mpos = 0;
|
||||||
|
msg(prompt);
|
||||||
|
gotit = FALSE;
|
||||||
|
}
|
||||||
|
} until (gotit);
|
||||||
|
if (isupper(dir_ch))
|
||||||
|
dir_ch = tolower(dir_ch);
|
||||||
|
last_dir = dir_ch;
|
||||||
|
last_delt.y = delta.y;
|
||||||
|
last_delt.x = delta.x;
|
||||||
|
}
|
||||||
|
if (on(player, ISHUH) && rnd(5) == 0)
|
||||||
|
do
|
||||||
|
{
|
||||||
|
delta.y = rnd(3) - 1;
|
||||||
|
delta.x = rnd(3) - 1;
|
||||||
|
} while (delta.y == 0 && delta.x == 0);
|
||||||
|
mpos = 0;
|
||||||
|
msg("");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sign:
|
||||||
|
* Return the sign of the number
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
sign(int nm)
|
||||||
|
{
|
||||||
|
if (nm < 0)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return (nm > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* spread:
|
||||||
|
* Give a spread around a given number (+/- 20%)
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
spread(int nm)
|
||||||
|
{
|
||||||
|
return nm - nm / 20 + rnd(nm / 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* call_it:
|
||||||
|
* Call an object something after use.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
call_it(struct obj_info *info)
|
||||||
|
{
|
||||||
|
if (info->oi_know)
|
||||||
|
{
|
||||||
|
if (info->oi_guess)
|
||||||
|
{
|
||||||
|
free(info->oi_guess);
|
||||||
|
info->oi_guess = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!info->oi_guess)
|
||||||
|
{
|
||||||
|
msg(terse ? "call it: " : "what do you want to call it? ");
|
||||||
|
if (get_str(prbuf, stdscr) == NORM)
|
||||||
|
{
|
||||||
|
if (info->oi_guess != NULL)
|
||||||
|
free(info->oi_guess);
|
||||||
|
info->oi_guess = malloc(strlen(prbuf) + 1);
|
||||||
|
if (info->oi_guess != NULL)
|
||||||
|
strcpy(info->oi_guess, prbuf);
|
||||||
|
}
|
||||||
|
msg("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rnd_thing:
|
||||||
|
* Pick a random thing appropriate for this level
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
rnd_thing(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int thing_list[] = {
|
||||||
|
POTION, SCROLL, RING, STICK, FOOD, WEAPON, ARMOR, STAIRS, GOLD, AMULET
|
||||||
|
};
|
||||||
|
|
||||||
|
if (level >= AMULETLEVEL)
|
||||||
|
i = rnd(sizeof thing_list / sizeof (int));
|
||||||
|
else
|
||||||
|
i = rnd(sizeof thing_list / sizeof (int) - 1);
|
||||||
|
return thing_list[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
str str:
|
||||||
|
* Choose the first or second string depending on whether it the
|
||||||
|
* player is tripping
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
choose_str(const char *ts, const char *ns)
|
||||||
|
{
|
||||||
|
return (on(player, ISHALU) ? ts : ns);
|
||||||
|
}
|
||||||
261
rogue5/monsters.c
Normal file
261
rogue5/monsters.c
Normal file
|
|
@ -0,0 +1,261 @@
|
||||||
|
/*
|
||||||
|
* File with various monster functions in it
|
||||||
|
*
|
||||||
|
* @(#)monsters.c 4.46 (Berkeley) 02/05/99
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <curses.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "rogue.h"
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* List of monsters in rough order of vorpalness
|
||||||
|
*/
|
||||||
|
static const int lvl_mons[] = {
|
||||||
|
'K', 'E', 'B', 'S', 'H', 'I', 'R', 'O', 'Z', 'L', 'C', 'Q', 'A',
|
||||||
|
'N', 'Y', 'F', 'T', 'W', 'P', 'X', 'U', 'M', 'V', 'G', 'J', 'D'
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int wand_mons[] = {
|
||||||
|
'K', 'E', 'B', 'S', 'H', 0, 'R', 'O', 'Z', 0, 'C', 'Q', 'A',
|
||||||
|
0, 'Y', 0, 'T', 'W', 'P', 0, 'U', 'M', 'V', 'G', 'J', 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* randmonster:
|
||||||
|
* Pick a monster to show up. The lower the level,
|
||||||
|
* the meaner the monster.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
randmonster(int wander)
|
||||||
|
{
|
||||||
|
int d;
|
||||||
|
const int *mons;
|
||||||
|
|
||||||
|
mons = (wander ? wand_mons : lvl_mons);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
d = level + (rnd(10) - 6);
|
||||||
|
if (d < 0)
|
||||||
|
d = rnd(5);
|
||||||
|
if (d > 25)
|
||||||
|
d = rnd(5) + 21;
|
||||||
|
} while (mons[d] == 0);
|
||||||
|
return mons[d];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* new_monster:
|
||||||
|
* Pick a new monster and add it to the list
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
new_monster(THING *tp, int type, const coord *cp)
|
||||||
|
{
|
||||||
|
struct monster *mp;
|
||||||
|
int lev_add;
|
||||||
|
|
||||||
|
if ((lev_add = level - AMULETLEVEL) < 0)
|
||||||
|
lev_add = 0;
|
||||||
|
attach(mlist, tp);
|
||||||
|
tp->t_type = type;
|
||||||
|
tp->t_disguise = type;
|
||||||
|
tp->t_pos = *cp;
|
||||||
|
move(cp->y, cp->x);
|
||||||
|
tp->t_oldch = CCHAR( inch() );
|
||||||
|
tp->t_room = roomin(cp);
|
||||||
|
moat(cp->y, cp->x) = tp;
|
||||||
|
mp = &monsters[tp->t_type-'A'];
|
||||||
|
tp->t_stats.s_lvl = mp->m_stats.s_lvl + lev_add;
|
||||||
|
tp->t_stats.s_maxhp = tp->t_stats.s_hpt = roll(tp->t_stats.s_lvl, 8);
|
||||||
|
tp->t_stats.s_arm = mp->m_stats.s_arm - lev_add;
|
||||||
|
strcpy(tp->t_stats.s_dmg,mp->m_stats.s_dmg);
|
||||||
|
tp->t_stats.s_str = mp->m_stats.s_str;
|
||||||
|
tp->t_stats.s_exp = mp->m_stats.s_exp + lev_add * 10 + exp_add(tp);
|
||||||
|
tp->t_flags = mp->m_flags;
|
||||||
|
if (level > 29)
|
||||||
|
tp->t_flags |= ISHASTE;
|
||||||
|
tp->t_turn = TRUE;
|
||||||
|
tp->t_pack = NULL;
|
||||||
|
if (ISWEARING(R_AGGR))
|
||||||
|
runto(cp);
|
||||||
|
if (type == 'X')
|
||||||
|
tp->t_disguise = rnd_thing();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* expadd:
|
||||||
|
* Experience to add for this monster's level/hit points
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
exp_add(const THING *tp)
|
||||||
|
{
|
||||||
|
int mod;
|
||||||
|
|
||||||
|
if (tp->t_stats.s_lvl == 1)
|
||||||
|
mod = tp->t_stats.s_maxhp / 8;
|
||||||
|
else
|
||||||
|
mod = tp->t_stats.s_maxhp / 6;
|
||||||
|
if (tp->t_stats.s_lvl > 9)
|
||||||
|
mod *= 20;
|
||||||
|
else if (tp->t_stats.s_lvl > 6)
|
||||||
|
mod *= 4;
|
||||||
|
return mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* wanderer:
|
||||||
|
* Create a new wandering monster and aim it at the player
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
wanderer(void)
|
||||||
|
{
|
||||||
|
THING *tp;
|
||||||
|
coord cp;
|
||||||
|
int cnt = 0;
|
||||||
|
|
||||||
|
tp = new_item();
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/* Avoid endless loop when all rooms are filled with monsters
|
||||||
|
* and the player room is not accessible to the monsters.
|
||||||
|
*/
|
||||||
|
if (cnt++ >= 500)
|
||||||
|
{
|
||||||
|
discard(tp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
find_floor(NULL, &cp, FALSE, TRUE);
|
||||||
|
} while (roomin(&cp) == proom && moat(cp.y, cp.x) == NULL);
|
||||||
|
new_monster(tp, randmonster(TRUE), &cp);
|
||||||
|
if (on(player, SEEMONST))
|
||||||
|
{
|
||||||
|
standout();
|
||||||
|
if (!on(player, ISHALU))
|
||||||
|
addch(tp->t_type);
|
||||||
|
else
|
||||||
|
addch(rnd(26) + 'A');
|
||||||
|
standend();
|
||||||
|
}
|
||||||
|
runto(&tp->t_pos);
|
||||||
|
#ifdef MASTER
|
||||||
|
if (wizard)
|
||||||
|
msg("started a wandering %s", monsters[tp->t_type-'A'].m_name);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* wake_monster:
|
||||||
|
* What to do when the hero steps next to a monster
|
||||||
|
*/
|
||||||
|
const THING *
|
||||||
|
wake_monster(int y, int x)
|
||||||
|
{
|
||||||
|
THING *tp;
|
||||||
|
struct room *rp;
|
||||||
|
int ch;
|
||||||
|
const char *mname;
|
||||||
|
|
||||||
|
if ((tp = moat(y, x)) == NULL) {
|
||||||
|
#ifdef MASTER
|
||||||
|
msg("can't find monster in wake_monster");
|
||||||
|
#endif
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ch = tp->t_type;
|
||||||
|
/*
|
||||||
|
* Every time he sees mean monster, it might start chasing him
|
||||||
|
*/
|
||||||
|
if (!on(*tp, ISRUN) && rnd(3) != 0 && on(*tp, ISMEAN) && !on(*tp, ISHELD)
|
||||||
|
&& !ISWEARING(R_STEALTH) && !on(player, ISLEVIT))
|
||||||
|
{
|
||||||
|
tp->t_dest = &hero;
|
||||||
|
tp->t_flags |= ISRUN;
|
||||||
|
}
|
||||||
|
if (ch == 'M' && !on(player, ISBLIND) && !on(player, ISHALU)
|
||||||
|
&& !on(*tp, ISFOUND) && !on(*tp, ISCANC) && on(*tp, ISRUN))
|
||||||
|
{
|
||||||
|
rp = proom;
|
||||||
|
if ((rp != NULL && !(rp->r_flags & ISDARK))
|
||||||
|
|| dist(y, x, hero.y, hero.x) < LAMPDIST)
|
||||||
|
{
|
||||||
|
tp->t_flags |= ISFOUND;
|
||||||
|
if (!save(VS_MAGIC))
|
||||||
|
{
|
||||||
|
if (on(player, ISHUH))
|
||||||
|
lengthen(unconfuse, spread(HUHDURATION));
|
||||||
|
else
|
||||||
|
fuse(unconfuse, 0, spread(HUHDURATION), AFTER);
|
||||||
|
player.t_flags |= ISHUH;
|
||||||
|
mname = set_mname(tp);
|
||||||
|
addmsg("%s", mname);
|
||||||
|
if (strcmp(mname, "it") != 0)
|
||||||
|
addmsg("'");
|
||||||
|
msg("s gaze has confused you");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Let greedy ones guard gold
|
||||||
|
*/
|
||||||
|
if (on(*tp, ISGREED) && !on(*tp, ISRUN))
|
||||||
|
{
|
||||||
|
tp->t_flags |= ISRUN;
|
||||||
|
if (proom->r_goldval)
|
||||||
|
tp->t_dest = &proom->r_gold;
|
||||||
|
else
|
||||||
|
tp->t_dest = &hero;
|
||||||
|
}
|
||||||
|
return tp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* give_pack:
|
||||||
|
* Give a pack to a monster if it deserves one
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
give_pack(THING *tp)
|
||||||
|
{
|
||||||
|
if (level >= max_level && rnd(100) < monsters[tp->t_type-'A'].m_carry)
|
||||||
|
attach(tp->t_pack, new_thing());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* save_throw:
|
||||||
|
* See if a creature save against something
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
save_throw(int which, const THING *tp)
|
||||||
|
{
|
||||||
|
int need;
|
||||||
|
|
||||||
|
need = 14 + which - tp->t_stats.s_lvl / 2;
|
||||||
|
return (roll(1, 20) >= need);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* save:
|
||||||
|
* See if he saves against various nasty things
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
save(int which)
|
||||||
|
{
|
||||||
|
if (which == VS_MAGIC)
|
||||||
|
{
|
||||||
|
if (ISRING(LEFT, R_PROTECT))
|
||||||
|
which -= cur_ring[LEFT]->o_arm;
|
||||||
|
if (ISRING(RIGHT, R_PROTECT))
|
||||||
|
which -= cur_ring[RIGHT]->o_arm;
|
||||||
|
}
|
||||||
|
return save_throw(which, &player);
|
||||||
|
}
|
||||||
425
rogue5/move.c
Normal file
425
rogue5/move.c
Normal file
|
|
@ -0,0 +1,425 @@
|
||||||
|
/*
|
||||||
|
* hero movement commands
|
||||||
|
*
|
||||||
|
* @(#)move.c 4.49 (Berkeley) 02/05/99
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <curses.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "rogue.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* used to hold the new hero position
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* do_run:
|
||||||
|
* Start the hero running
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
do_run(int ch)
|
||||||
|
{
|
||||||
|
running = TRUE;
|
||||||
|
after = FALSE;
|
||||||
|
runch = ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* do_move:
|
||||||
|
* Check to see that a move is legal. If it is handle the
|
||||||
|
* consequences (fighting, picking up, etc.)
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
do_move(int dy, int dx)
|
||||||
|
{
|
||||||
|
int ch, fl;
|
||||||
|
coord nh;
|
||||||
|
|
||||||
|
firstmove = FALSE;
|
||||||
|
if (no_move)
|
||||||
|
{
|
||||||
|
no_move--;
|
||||||
|
msg("you are still stuck in the bear trap");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Do a confused move (maybe)
|
||||||
|
*/
|
||||||
|
if (on(player, ISHUH) && rnd(5) != 0)
|
||||||
|
{
|
||||||
|
nh = rndmove(&player);
|
||||||
|
if (ce(nh, hero))
|
||||||
|
{
|
||||||
|
after = FALSE;
|
||||||
|
running = FALSE;
|
||||||
|
to_death = FALSE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
over:
|
||||||
|
nh.y = hero.y + dy;
|
||||||
|
nh.x = hero.x + dx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if he tried to move off the screen or make an illegal
|
||||||
|
* diagonal move, and stop him if he did.
|
||||||
|
*/
|
||||||
|
if (nh.x < 0 || nh.x >= NUMCOLS || nh.y <= 0 || nh.y >= NUMLINES - 1)
|
||||||
|
goto hit_bound;
|
||||||
|
if (!diag_ok(&hero, &nh))
|
||||||
|
{
|
||||||
|
after = FALSE;
|
||||||
|
running = FALSE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (running && ce(hero, nh))
|
||||||
|
after = running = FALSE;
|
||||||
|
fl = flat(nh.y, nh.x);
|
||||||
|
ch = winat(nh.y, nh.x);
|
||||||
|
if (!(fl & F_REAL) && ch == FLOOR)
|
||||||
|
{
|
||||||
|
if (!on(player, ISLEVIT))
|
||||||
|
{
|
||||||
|
chat(nh.y, nh.x) = ch = TRAP;
|
||||||
|
flat(nh.y, nh.x) |= F_REAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (on(player, ISHELD) && ch != 'F')
|
||||||
|
{
|
||||||
|
msg("you are being held");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (ch)
|
||||||
|
{
|
||||||
|
case ' ':
|
||||||
|
case '|':
|
||||||
|
case '-':
|
||||||
|
hit_bound:
|
||||||
|
if (passgo && running && (proom->r_flags & ISGONE)
|
||||||
|
&& !on(player, ISBLIND))
|
||||||
|
{
|
||||||
|
int b1, b2;
|
||||||
|
|
||||||
|
switch (runch)
|
||||||
|
{
|
||||||
|
case 'h':
|
||||||
|
case 'l':
|
||||||
|
b1 = (hero.y != 1 && turn_ok(hero.y - 1, hero.x));
|
||||||
|
b2 = (hero.y != NUMLINES - 2 && turn_ok(hero.y + 1, hero.x));
|
||||||
|
if (!(b1 ^ b2))
|
||||||
|
break;
|
||||||
|
if (b1)
|
||||||
|
{
|
||||||
|
runch = 'k';
|
||||||
|
dy = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
runch = 'j';
|
||||||
|
dy = 1;
|
||||||
|
}
|
||||||
|
dx = 0;
|
||||||
|
turnref();
|
||||||
|
goto over;
|
||||||
|
case 'j':
|
||||||
|
case 'k':
|
||||||
|
b1 = (hero.x != 0 && turn_ok(hero.y, hero.x - 1));
|
||||||
|
b2 = (hero.x != NUMCOLS - 1 && turn_ok(hero.y, hero.x + 1));
|
||||||
|
if (!(b1 ^ b2))
|
||||||
|
break;
|
||||||
|
if (b1)
|
||||||
|
{
|
||||||
|
runch = 'h';
|
||||||
|
dx = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
runch = 'l';
|
||||||
|
dx = 1;
|
||||||
|
}
|
||||||
|
dy = 0;
|
||||||
|
turnref();
|
||||||
|
goto over;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
running = FALSE;
|
||||||
|
after = FALSE;
|
||||||
|
break;
|
||||||
|
case DOOR:
|
||||||
|
running = FALSE;
|
||||||
|
if (flat(hero.y, hero.x) & F_PASS)
|
||||||
|
enter_room(&nh);
|
||||||
|
goto move_stuff;
|
||||||
|
case TRAP:
|
||||||
|
ch = be_trapped(&nh);
|
||||||
|
if (ch == T_DOOR || ch == T_TELEP)
|
||||||
|
return;
|
||||||
|
goto move_stuff;
|
||||||
|
case PASSAGE:
|
||||||
|
/*
|
||||||
|
* when you're in a corridor, you don't know if you're in
|
||||||
|
* a maze room or not, and there ain't no way to find out
|
||||||
|
* if you're leaving a maze room, so it is necessary to
|
||||||
|
* always recalculate proom.
|
||||||
|
*/
|
||||||
|
proom = roomin(&hero);
|
||||||
|
goto move_stuff;
|
||||||
|
case FLOOR:
|
||||||
|
if (!(fl & F_REAL))
|
||||||
|
be_trapped(&hero);
|
||||||
|
goto move_stuff;
|
||||||
|
case STAIRS:
|
||||||
|
seenstairs = TRUE;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
default:
|
||||||
|
running = FALSE;
|
||||||
|
if (isupper(ch) || moat(nh.y, nh.x))
|
||||||
|
fight(&nh, cur_weapon, FALSE);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ch != STAIRS)
|
||||||
|
take = ch;
|
||||||
|
move_stuff:
|
||||||
|
mvaddch(hero.y, hero.x, floor_at());
|
||||||
|
if ((fl & F_PASS) && chat(oldpos.y, oldpos.x) == DOOR)
|
||||||
|
leave_room(&nh);
|
||||||
|
hero = nh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* turn_ok:
|
||||||
|
* Decide whether it is legal to turn onto the given space
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
turn_ok(int y, int x)
|
||||||
|
{
|
||||||
|
PLACE *pp;
|
||||||
|
|
||||||
|
pp = INDEX(y, x);
|
||||||
|
return (pp->p_ch == DOOR
|
||||||
|
|| (pp->p_flags & (F_REAL|F_PASS)) == (F_REAL|F_PASS));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* turnref:
|
||||||
|
* Decide whether to refresh at a passage turning or not
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
turnref(void)
|
||||||
|
{
|
||||||
|
PLACE *pp;
|
||||||
|
|
||||||
|
pp = INDEX(hero.y, hero.x);
|
||||||
|
if (!(pp->p_flags & F_SEEN))
|
||||||
|
{
|
||||||
|
if (jump)
|
||||||
|
{
|
||||||
|
leaveok(stdscr, TRUE);
|
||||||
|
refresh();
|
||||||
|
leaveok(stdscr, FALSE);
|
||||||
|
}
|
||||||
|
pp->p_flags |= F_SEEN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* door_open:
|
||||||
|
* Called to illuminate a room. If it is dark, remove anything
|
||||||
|
* that might move.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
door_open(const struct room *rp)
|
||||||
|
{
|
||||||
|
int y, x;
|
||||||
|
|
||||||
|
if (!(rp->r_flags & ISGONE))
|
||||||
|
for (y = rp->r_pos.y; y < rp->r_pos.y + rp->r_max.y; y++)
|
||||||
|
for (x = rp->r_pos.x; x < rp->r_pos.x + rp->r_max.x; x++)
|
||||||
|
if (isupper(winat(y, x)))
|
||||||
|
wake_monster(y, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* be_trapped:
|
||||||
|
* The guy stepped on a trap.... Make him pay.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
be_trapped(const coord *tc)
|
||||||
|
{
|
||||||
|
PLACE *pp;
|
||||||
|
THING *arrow;
|
||||||
|
int tr;
|
||||||
|
|
||||||
|
if (on(player, ISLEVIT))
|
||||||
|
return T_RUST; /* anything that's not a door or teleport */
|
||||||
|
running = FALSE;
|
||||||
|
count = FALSE;
|
||||||
|
pp = INDEX(tc->y, tc->x);
|
||||||
|
pp->p_ch = TRAP;
|
||||||
|
tr = pp->p_flags & F_TMASK;
|
||||||
|
pp->p_flags |= F_SEEN;
|
||||||
|
switch (tr)
|
||||||
|
{
|
||||||
|
case T_DOOR:
|
||||||
|
level++;
|
||||||
|
new_level();
|
||||||
|
msg("you fell into a trap!");
|
||||||
|
when T_BEAR:
|
||||||
|
no_move += BEARTIME;
|
||||||
|
msg("you are caught in a bear trap");
|
||||||
|
when T_MYST:
|
||||||
|
switch(rnd(11))
|
||||||
|
{
|
||||||
|
case 0: msg("you are suddenly in a parallel dimension");
|
||||||
|
when 1: msg("the light in here suddenly seems %s", rainbow[rnd(cNCOLORS)]);
|
||||||
|
when 2: msg("you feel a sting in the side of your neck");
|
||||||
|
when 3: msg("multi-colored lines swirl around you, then fade");
|
||||||
|
when 4: msg("a %s light flashes in your eyes", rainbow[rnd(cNCOLORS)]);
|
||||||
|
when 5: msg("a spike shoots past your ear!");
|
||||||
|
when 6: msg("%s sparks dance across your armor", rainbow[rnd(cNCOLORS)]);
|
||||||
|
when 7: msg("you suddenly feel very thirsty");
|
||||||
|
when 8: msg("you feel time speed up suddenly");
|
||||||
|
when 9: msg("time now seems to be going slower");
|
||||||
|
when 10: msg("you pack turns %s!", rainbow[rnd(cNCOLORS)]);
|
||||||
|
}
|
||||||
|
when T_SLEEP:
|
||||||
|
no_command += SLEEPTIME;
|
||||||
|
player.t_flags &= ~ISRUN;
|
||||||
|
msg("a strange white mist envelops you and you fall asleep");
|
||||||
|
when T_ARROW:
|
||||||
|
if (swing(pstats.s_lvl - 1, pstats.s_arm, 1))
|
||||||
|
{
|
||||||
|
pstats.s_hpt -= roll(1, 6);
|
||||||
|
if (pstats.s_hpt <= 0)
|
||||||
|
{
|
||||||
|
msg("an arrow killed you");
|
||||||
|
death('a');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
msg("oh no! An arrow shot you");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
arrow = new_item();
|
||||||
|
init_weapon(arrow, ARROW);
|
||||||
|
arrow->o_count = 1;
|
||||||
|
arrow->o_pos = hero;
|
||||||
|
fall(arrow, FALSE);
|
||||||
|
msg("an arrow shoots past you");
|
||||||
|
}
|
||||||
|
when T_TELEP:
|
||||||
|
/*
|
||||||
|
* since the hero's leaving, look() won't put a TRAP
|
||||||
|
* down for us, so we have to do it ourself
|
||||||
|
*/
|
||||||
|
teleport();
|
||||||
|
mvaddch(tc->y, tc->x, TRAP);
|
||||||
|
when T_DART:
|
||||||
|
if (!swing(pstats.s_lvl+1, pstats.s_arm, 1))
|
||||||
|
msg("a small dart whizzes by your ear and vanishes");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pstats.s_hpt -= roll(1, 4);
|
||||||
|
if (pstats.s_hpt <= 0)
|
||||||
|
{
|
||||||
|
msg("a poisoned dart killed you");
|
||||||
|
death('d');
|
||||||
|
}
|
||||||
|
if (!ISWEARING(R_SUSTSTR) && !save(VS_POISON))
|
||||||
|
chg_str(-1);
|
||||||
|
msg("a small dart just hit you in the shoulder");
|
||||||
|
}
|
||||||
|
when T_RUST:
|
||||||
|
msg("a gush of water hits you on the head");
|
||||||
|
rust_armor(cur_armor);
|
||||||
|
}
|
||||||
|
flush_type();
|
||||||
|
return tr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rndmove:
|
||||||
|
* Move in a random direction if the monster/person is confused
|
||||||
|
*/
|
||||||
|
coord
|
||||||
|
rndmove(const THING *who)
|
||||||
|
{
|
||||||
|
THING *obj;
|
||||||
|
int x, y;
|
||||||
|
int ch;
|
||||||
|
coord ret; /* what we will be returning */
|
||||||
|
|
||||||
|
y = ret.y = who->t_pos.y + rnd(3) - 1;
|
||||||
|
x = ret.x = who->t_pos.x + rnd(3) - 1;
|
||||||
|
/*
|
||||||
|
* Now check to see if that's a legal move. If not, don't move.
|
||||||
|
* (I.e., bump into the wall or whatever)
|
||||||
|
*/
|
||||||
|
if (y == who->t_pos.y && x == who->t_pos.x)
|
||||||
|
return ret;
|
||||||
|
if (!diag_ok(&who->t_pos, &ret))
|
||||||
|
goto bad;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ch = winat(y, x);
|
||||||
|
if (!step_ok(ch))
|
||||||
|
goto bad;
|
||||||
|
if (ch == SCROLL)
|
||||||
|
{
|
||||||
|
for (obj = lvl_obj; obj != NULL; obj = next(obj))
|
||||||
|
if (y == obj->o_pos.y && x == obj->o_pos.x)
|
||||||
|
break;
|
||||||
|
if (obj != NULL && obj->o_which == S_SCARE)
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
bad:
|
||||||
|
ret = who->t_pos;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rust_armor:
|
||||||
|
* Rust the given armor, if it is a legal kind to rust, and we
|
||||||
|
* aren't wearing a magic ring.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
rust_armor(THING *arm)
|
||||||
|
{
|
||||||
|
if (arm == NULL || arm->o_type != ARMOR || arm->o_which == LEATHER ||
|
||||||
|
arm->o_arm >= 9)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((arm->o_flags & ISPROT) || ISWEARING(R_SUSTARM))
|
||||||
|
{
|
||||||
|
if (!to_death)
|
||||||
|
msg("the rust vanishes instantly");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
arm->o_arm++;
|
||||||
|
if (!terse)
|
||||||
|
msg("your armor appears to be weaker now. Oh my!");
|
||||||
|
else
|
||||||
|
msg("your armor weakens");
|
||||||
|
}
|
||||||
|
}
|
||||||
232
rogue5/new_level.c
Normal file
232
rogue5/new_level.c
Normal file
|
|
@ -0,0 +1,232 @@
|
||||||
|
/*
|
||||||
|
* new_level:
|
||||||
|
* Dig and draw a new level
|
||||||
|
*
|
||||||
|
* @(#)new_level.c 4.38 (Berkeley) 02/05/99
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <curses.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "rogue.h"
|
||||||
|
|
||||||
|
#define TREAS_ROOM 20 /* one chance in TREAS_ROOM for a treasure room */
|
||||||
|
#define MAXTREAS 10 /* maximum number of treasures in a treasure room */
|
||||||
|
#define MINTREAS 2 /* minimum number of treasures in a treasure room */
|
||||||
|
|
||||||
|
void
|
||||||
|
new_level(void)
|
||||||
|
{
|
||||||
|
THING *tp;
|
||||||
|
PLACE *pp;
|
||||||
|
int *sp;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
player.t_flags &= ~ISHELD; /* unhold when you go down just in case */
|
||||||
|
if (level > max_level)
|
||||||
|
max_level = level;
|
||||||
|
/*
|
||||||
|
* Clean things off from last level
|
||||||
|
*/
|
||||||
|
for (pp = places; pp < &places[MAXCOLS*MAXLINES]; pp++)
|
||||||
|
{
|
||||||
|
pp->p_ch = ' ';
|
||||||
|
pp->p_flags = F_REAL;
|
||||||
|
pp->p_monst = NULL;
|
||||||
|
}
|
||||||
|
clear();
|
||||||
|
/*
|
||||||
|
* Free up the monsters on the last level
|
||||||
|
*/
|
||||||
|
for (tp = mlist; tp != NULL; tp = next(tp))
|
||||||
|
free_list(tp->t_pack);
|
||||||
|
free_list(mlist);
|
||||||
|
/*
|
||||||
|
* Throw away stuff left on the previous level (if anything)
|
||||||
|
*/
|
||||||
|
free_list(lvl_obj);
|
||||||
|
do_rooms(); /* Draw rooms */
|
||||||
|
do_passages(); /* Draw passages */
|
||||||
|
no_food++;
|
||||||
|
put_things(); /* Place objects (if any) */
|
||||||
|
/*
|
||||||
|
* Place the traps
|
||||||
|
*/
|
||||||
|
if (rnd(10) < level)
|
||||||
|
{
|
||||||
|
ntraps = rnd(level / 4) + 1;
|
||||||
|
if (ntraps > MAXTRAPS)
|
||||||
|
ntraps = MAXTRAPS;
|
||||||
|
i = ntraps;
|
||||||
|
while (i--)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* not only wouldn't it be NICE to have traps in mazes
|
||||||
|
* (not that we care about being nice), since the trap
|
||||||
|
* number is stored where the passage number is, we
|
||||||
|
* can't actually do it.
|
||||||
|
*/
|
||||||
|
do
|
||||||
|
{
|
||||||
|
find_floor(NULL, &stairs, FALSE, FALSE);
|
||||||
|
} while ( (chat(stairs.y, stairs.x) != FLOOR) &&
|
||||||
|
(flat(stairs.y, stairs.x) & F_REAL) );
|
||||||
|
sp = &flat(stairs.y, stairs.x);
|
||||||
|
*sp &= ~(F_REAL | F_TMASK);
|
||||||
|
*sp |= rnd(NTRAPS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Place the staircase down.
|
||||||
|
*/
|
||||||
|
find_floor(NULL, &stairs, FALSE, FALSE);
|
||||||
|
chat(stairs.y, stairs.x) = STAIRS;
|
||||||
|
seenstairs = FALSE;
|
||||||
|
|
||||||
|
for (tp = mlist; tp != NULL; tp = next(tp))
|
||||||
|
tp->t_room = roomin(&tp->t_pos);
|
||||||
|
|
||||||
|
find_floor(NULL, &hero, FALSE, TRUE);
|
||||||
|
enter_room(&hero);
|
||||||
|
mvaddch(hero.y, hero.x, PLAYER);
|
||||||
|
if (on(player, SEEMONST))
|
||||||
|
turn_see(FALSE);
|
||||||
|
if (on(player, ISHALU))
|
||||||
|
visuals();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rnd_room:
|
||||||
|
* Pick a room that is really there
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
rnd_room(void)
|
||||||
|
{
|
||||||
|
int rm;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
rm = rnd(MAXROOMS);
|
||||||
|
} while (rooms[rm].r_flags & ISGONE);
|
||||||
|
return rm;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* put_things:
|
||||||
|
* Put potions and scrolls on this level
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
put_things(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
THING *obj;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Once you have found the amulet, the only way to get new stuff is
|
||||||
|
* go down into the dungeon.
|
||||||
|
*/
|
||||||
|
if (amulet && level < max_level)
|
||||||
|
return;
|
||||||
|
/*
|
||||||
|
* check for treasure rooms, and if so, put it in.
|
||||||
|
*/
|
||||||
|
if (rnd(TREAS_ROOM) == 0)
|
||||||
|
treas_room();
|
||||||
|
/*
|
||||||
|
* Do MAXOBJ attempts to put things on a level
|
||||||
|
*/
|
||||||
|
for (i = 0; i < MAXOBJ; i++)
|
||||||
|
if (rnd(100) < 36)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Pick a new object and link it in the list
|
||||||
|
*/
|
||||||
|
obj = new_thing();
|
||||||
|
attach(lvl_obj, obj);
|
||||||
|
/*
|
||||||
|
* Put it somewhere
|
||||||
|
*/
|
||||||
|
find_floor(NULL, &obj->o_pos, FALSE, FALSE);
|
||||||
|
chat(obj->o_pos.y, obj->o_pos.x) = obj->o_type;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* If he is really deep in the dungeon and he hasn't found the
|
||||||
|
* amulet yet, put it somewhere on the ground
|
||||||
|
*/
|
||||||
|
if (level >= AMULETLEVEL && !amulet)
|
||||||
|
{
|
||||||
|
obj = new_item();
|
||||||
|
attach(lvl_obj, obj);
|
||||||
|
obj->o_hplus = 0;
|
||||||
|
obj->o_dplus = 0;
|
||||||
|
strncpy(obj->o_damage,"0x0",sizeof(obj->o_damage));
|
||||||
|
strncpy(obj->o_hurldmg,"0x0",sizeof(obj->o_hurldmg));
|
||||||
|
obj->o_arm = 11;
|
||||||
|
obj->o_type = AMULET;
|
||||||
|
/*
|
||||||
|
* Put it somewhere
|
||||||
|
*/
|
||||||
|
find_floor(NULL, &obj->o_pos, FALSE, FALSE);
|
||||||
|
chat(obj->o_pos.y, obj->o_pos.x) = AMULET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* treas_room:
|
||||||
|
* Add a treasure room
|
||||||
|
*/
|
||||||
|
#define MAXTRIES 10 /* max number of tries to put down a monster */
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
treas_room(void)
|
||||||
|
{
|
||||||
|
int nm;
|
||||||
|
THING *tp;
|
||||||
|
struct room *rp;
|
||||||
|
int spots, num_monst;
|
||||||
|
coord mp;
|
||||||
|
|
||||||
|
rp = &rooms[rnd_room()];
|
||||||
|
spots = (rp->r_max.y - 2) * (rp->r_max.x - 2) - MINTREAS;
|
||||||
|
if (spots > (MAXTREAS - MINTREAS))
|
||||||
|
spots = (MAXTREAS - MINTREAS);
|
||||||
|
num_monst = nm = rnd(spots) + MINTREAS;
|
||||||
|
while (nm--)
|
||||||
|
{
|
||||||
|
find_floor(rp, &mp, 2 * MAXTRIES, FALSE);
|
||||||
|
tp = new_thing();
|
||||||
|
tp->o_pos = mp;
|
||||||
|
attach(lvl_obj, tp);
|
||||||
|
chat(mp.y, mp.x) = tp->o_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fill up room with monsters from the next level down
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((nm = rnd(spots) + MINTREAS) < num_monst + 2)
|
||||||
|
nm = num_monst + 2;
|
||||||
|
spots = (rp->r_max.y - 2) * (rp->r_max.x - 2);
|
||||||
|
if (nm > spots)
|
||||||
|
nm = spots;
|
||||||
|
level++;
|
||||||
|
while (nm--)
|
||||||
|
{
|
||||||
|
spots = 0;
|
||||||
|
if (find_floor(rp, &mp, MAXTRIES, TRUE))
|
||||||
|
{
|
||||||
|
tp = new_item();
|
||||||
|
new_monster(tp, randmonster(FALSE), &mp);
|
||||||
|
tp->t_flags |= ISMEAN; /* no sloughers in THIS room */
|
||||||
|
give_pack(tp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
level--;
|
||||||
|
}
|
||||||
501
rogue5/options.c
Normal file
501
rogue5/options.c
Normal file
|
|
@ -0,0 +1,501 @@
|
||||||
|
/*
|
||||||
|
* This file has all the code for the option command. I would rather
|
||||||
|
* this command were not necessary, but it is the only way to keep the
|
||||||
|
* wolves off of my back.
|
||||||
|
*
|
||||||
|
* @(#)options.c 4.24 (Berkeley) 05/10/83
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <curses.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "rogue.h"
|
||||||
|
|
||||||
|
#define EQSTR(a, b, c) (strncmp(a, b, c) == 0)
|
||||||
|
|
||||||
|
#define NUM_OPTS (sizeof optlist / sizeof (OPTION))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* description of an option and what to do with it
|
||||||
|
*/
|
||||||
|
struct optstruct {
|
||||||
|
char *o_name; /* option name */
|
||||||
|
char *o_prompt; /* prompt for interactive entry */
|
||||||
|
void *o_opt; /* pointer to thing to set */
|
||||||
|
/* function to print value */
|
||||||
|
void (*o_putfunc)(void *opt);
|
||||||
|
/* function to get value interactively */
|
||||||
|
int (*o_getfunc)(void *opt, WINDOW *win);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct optstruct OPTION;
|
||||||
|
|
||||||
|
void pr_optname(const OPTION *op);
|
||||||
|
|
||||||
|
static const OPTION optlist[] = {
|
||||||
|
{"terse", "Terse output",
|
||||||
|
&terse, put_bool, get_bool },
|
||||||
|
{"flush", "Flush typeahead during battle",
|
||||||
|
&fight_flush, put_bool, get_bool },
|
||||||
|
{"jump", "Show position only at end of run",
|
||||||
|
&jump, put_bool, get_bool },
|
||||||
|
{"seefloor", "Show the lamp-illuminated floor",
|
||||||
|
&see_floor, put_bool, get_sf },
|
||||||
|
{"passgo", "Follow turnings in passageways",
|
||||||
|
&passgo, put_bool, get_bool },
|
||||||
|
{"tombstone", "Print out tombstone when killed",
|
||||||
|
&tombstone, put_bool, get_bool },
|
||||||
|
{"inven", "Inventory style",
|
||||||
|
&inv_type, put_inv_t, get_inv_t },
|
||||||
|
{"name", "Name",
|
||||||
|
whoami, put_str, get_str },
|
||||||
|
{"fruit", "Fruit",
|
||||||
|
fruit, put_str, get_str },
|
||||||
|
{"file", "Save file",
|
||||||
|
file_name, put_str, get_str }
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* option:
|
||||||
|
* Print and then set options from the terminal
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
option(void)
|
||||||
|
{
|
||||||
|
const OPTION *op;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
wclear(hw);
|
||||||
|
/*
|
||||||
|
* Display current values of options
|
||||||
|
*/
|
||||||
|
for (op = optlist; op <= &optlist[NUM_OPTS-1]; op++)
|
||||||
|
{
|
||||||
|
pr_optname(op);
|
||||||
|
(*op->o_putfunc)(op->o_opt);
|
||||||
|
waddch(hw, '\n');
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Set values
|
||||||
|
*/
|
||||||
|
wmove(hw, 0, 0);
|
||||||
|
for (op = optlist; op <= &optlist[NUM_OPTS-1]; op++)
|
||||||
|
{
|
||||||
|
pr_optname(op);
|
||||||
|
retval = (*op->o_getfunc)(op->o_opt, hw);
|
||||||
|
if (retval)
|
||||||
|
{
|
||||||
|
if (retval == QUIT)
|
||||||
|
break;
|
||||||
|
else if (op > optlist) { /* MINUS */
|
||||||
|
wmove(hw, (int)(op - optlist) - 1, 0);
|
||||||
|
op -= 2;
|
||||||
|
}
|
||||||
|
else /* trying to back up beyond the top */
|
||||||
|
{
|
||||||
|
putchar('\007');
|
||||||
|
wmove(hw, 0, 0);
|
||||||
|
op--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Switch back to original screen
|
||||||
|
*/
|
||||||
|
wmove(hw, LINES - 1, 0);
|
||||||
|
waddstr(hw, "--Press space to continue--");
|
||||||
|
wrefresh(hw);
|
||||||
|
wait_for(hw, ' ');
|
||||||
|
clearok(curscr, TRUE);
|
||||||
|
touchwin(stdscr);
|
||||||
|
after = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pr_optname:
|
||||||
|
* Print out the option name prompt
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
pr_optname(const OPTION *op)
|
||||||
|
{
|
||||||
|
wprintw(hw, "%s (\"%s\"): ", op->o_prompt, op->o_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* put_bool
|
||||||
|
* Put out a boolean
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
put_bool(void *b)
|
||||||
|
{
|
||||||
|
waddstr(hw, *(int *) b ? "True" : "False");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* put_str:
|
||||||
|
* Put out a string
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
put_str(void *str)
|
||||||
|
{
|
||||||
|
waddstr(hw, (char *) str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* put_inv_t:
|
||||||
|
* Put out an inventory type
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
put_inv_t(void *ip)
|
||||||
|
{
|
||||||
|
waddstr(hw, inv_t_name[*(int *) ip]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get_bool:
|
||||||
|
* Allow changing a boolean option and print it out
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
get_bool(void *vp, WINDOW *win)
|
||||||
|
{
|
||||||
|
int *bp = (int *) vp;
|
||||||
|
int oy, ox;
|
||||||
|
int op_bad;
|
||||||
|
|
||||||
|
op_bad = TRUE;
|
||||||
|
getyx(win, oy, ox);
|
||||||
|
waddstr(win, *bp ? "True" : "False");
|
||||||
|
while (op_bad)
|
||||||
|
{
|
||||||
|
wmove(win, oy, ox);
|
||||||
|
wrefresh(win);
|
||||||
|
switch (wreadchar(win))
|
||||||
|
{
|
||||||
|
case 't':
|
||||||
|
case 'T':
|
||||||
|
*bp = TRUE;
|
||||||
|
op_bad = FALSE;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
case 'F':
|
||||||
|
*bp = FALSE;
|
||||||
|
op_bad = FALSE;
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
case '\r':
|
||||||
|
op_bad = FALSE;
|
||||||
|
break;
|
||||||
|
case ESCAPE:
|
||||||
|
return QUIT;
|
||||||
|
case '-':
|
||||||
|
return MINUS;
|
||||||
|
default:
|
||||||
|
wmove(win, oy, ox + 10);
|
||||||
|
waddstr(win, "(T or F)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wmove(win, oy, ox);
|
||||||
|
waddstr(win, *bp ? "True" : "False");
|
||||||
|
waddch(win, '\n');
|
||||||
|
return NORM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get_sf:
|
||||||
|
* Change value and handle transition problems from see_floor to
|
||||||
|
* !see_floor.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
get_sf(void *vp, WINDOW *win)
|
||||||
|
{
|
||||||
|
int *bp = (int *) vp;
|
||||||
|
int was_sf;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
was_sf = see_floor;
|
||||||
|
retval = get_bool(bp, win);
|
||||||
|
if (retval == QUIT) return(QUIT);
|
||||||
|
if (was_sf != see_floor)
|
||||||
|
{
|
||||||
|
if (!see_floor) {
|
||||||
|
see_floor = TRUE;
|
||||||
|
erase_lamp(&hero, proom);
|
||||||
|
see_floor = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
look(FALSE);
|
||||||
|
}
|
||||||
|
return(NORM);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get_str:
|
||||||
|
* Set a string option
|
||||||
|
*/
|
||||||
|
#define MAXINP 50 /* max string to read from terminal or environment */
|
||||||
|
|
||||||
|
int
|
||||||
|
get_str(void *vopt, WINDOW *win)
|
||||||
|
{
|
||||||
|
char *opt = (char *) vopt;
|
||||||
|
char *sp;
|
||||||
|
int oy, ox;
|
||||||
|
size_t i;
|
||||||
|
int c;
|
||||||
|
static char buf[MAXSTR];
|
||||||
|
|
||||||
|
getyx(win, oy, ox);
|
||||||
|
wrefresh(win);
|
||||||
|
/*
|
||||||
|
* loop reading in the string, and put it in a temporary buffer
|
||||||
|
*/
|
||||||
|
for (sp = buf; (c = wreadchar(win)) != '\n' && c != '\r' && c != ESCAPE;
|
||||||
|
wclrtoeol(win), wrefresh(win))
|
||||||
|
{
|
||||||
|
if (c == -1)
|
||||||
|
continue;
|
||||||
|
else if (c == erasechar()) /* process erase character */
|
||||||
|
{
|
||||||
|
if (sp > buf)
|
||||||
|
{
|
||||||
|
sp--;
|
||||||
|
for (i = strlen(unctrl(*sp)); i; i--)
|
||||||
|
waddch(win, '\b');
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (c == killchar()) /* process kill character */
|
||||||
|
{
|
||||||
|
sp = buf;
|
||||||
|
wmove(win, oy, ox);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (sp == buf)
|
||||||
|
{
|
||||||
|
if (c == '-' && win != stdscr)
|
||||||
|
break;
|
||||||
|
else if (c == '~')
|
||||||
|
{
|
||||||
|
strcpy(buf, home);
|
||||||
|
waddstr(win, home);
|
||||||
|
sp += strlen(home);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sp >= &buf[MAXINP] || !(isprint(c) || c == ' '))
|
||||||
|
putchar(CTRL('G'));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*sp++ = (char) c;
|
||||||
|
waddstr(win, unctrl(c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*sp = '\0';
|
||||||
|
if (sp > buf) /* only change option if something has been typed */
|
||||||
|
strucpy(opt, buf, strlen(buf));
|
||||||
|
mvwprintw(win, oy, ox, "%s\n", opt);
|
||||||
|
wrefresh(win);
|
||||||
|
if (win == stdscr)
|
||||||
|
mpos += (int)(sp - buf);
|
||||||
|
if (c == '-')
|
||||||
|
return MINUS;
|
||||||
|
else if (c == ESCAPE)
|
||||||
|
return QUIT;
|
||||||
|
else
|
||||||
|
return NORM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get_inv_t
|
||||||
|
* Get an inventory type name
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
get_inv_t(void *vp, WINDOW *win)
|
||||||
|
{
|
||||||
|
int *ip = (int *) vp;
|
||||||
|
int oy, ox;
|
||||||
|
int op_bad;
|
||||||
|
|
||||||
|
op_bad = TRUE;
|
||||||
|
getyx(win, oy, ox);
|
||||||
|
waddstr(win, inv_t_name[*ip]);
|
||||||
|
while (op_bad)
|
||||||
|
{
|
||||||
|
wmove(win, oy, ox);
|
||||||
|
wrefresh(win);
|
||||||
|
switch (wreadchar(win))
|
||||||
|
{
|
||||||
|
case 'o':
|
||||||
|
case 'O':
|
||||||
|
*ip = INV_OVER;
|
||||||
|
op_bad = FALSE;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
case 'S':
|
||||||
|
*ip = INV_SLOW;
|
||||||
|
op_bad = FALSE;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
case 'C':
|
||||||
|
*ip = INV_CLEAR;
|
||||||
|
op_bad = FALSE;
|
||||||
|
break;
|
||||||
|
case '\n':
|
||||||
|
case '\r':
|
||||||
|
op_bad = FALSE;
|
||||||
|
break;
|
||||||
|
case ESCAPE:
|
||||||
|
return QUIT;
|
||||||
|
case '-':
|
||||||
|
return MINUS;
|
||||||
|
default:
|
||||||
|
wmove(win, oy, ox + 15);
|
||||||
|
waddstr(win, "(O, S, or C)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mvwprintw(win, oy, ox, "%s\n", inv_t_name[*ip]);
|
||||||
|
return NORM;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef MASTER
|
||||||
|
/*
|
||||||
|
* get_num:
|
||||||
|
* Get a numeric option
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
get_num(void *vp, WINDOW *win)
|
||||||
|
{
|
||||||
|
int *opt = (int *) vp;
|
||||||
|
int i;
|
||||||
|
static char buf[MAXSTR];
|
||||||
|
|
||||||
|
if ((i = get_str(buf, win)) == NORM)
|
||||||
|
*opt = atoi(buf);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* parse_opts:
|
||||||
|
* Parse options from string, usually taken from the environment.
|
||||||
|
* The string is a series of comma seperated values, with booleans
|
||||||
|
* being stated as "name" (true) or "noname" (false), and strings
|
||||||
|
* being "name=....", with the string being defined up to a comma
|
||||||
|
* or the end of the entire option string.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
parse_opts(char *str)
|
||||||
|
{
|
||||||
|
char *sp;
|
||||||
|
const OPTION *op;
|
||||||
|
int len;
|
||||||
|
const char **i;
|
||||||
|
char *start;
|
||||||
|
|
||||||
|
while (*str)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Get option name
|
||||||
|
*/
|
||||||
|
for (sp = str; isalpha((int)*sp); sp++)
|
||||||
|
continue;
|
||||||
|
len = (int)(sp - str);
|
||||||
|
/*
|
||||||
|
* Look it up and deal with it
|
||||||
|
*/
|
||||||
|
for (op = optlist; op <= &optlist[NUM_OPTS-1]; op++)
|
||||||
|
if (EQSTR(str, op->o_name, len))
|
||||||
|
{
|
||||||
|
if (op->o_putfunc == put_bool) /* if option is a boolean */
|
||||||
|
*(int *)op->o_opt = TRUE; /* NOSTRICT */
|
||||||
|
else /* string option */
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Skip to start of string value
|
||||||
|
*/
|
||||||
|
for (str = sp + 1; *str == '='; str++)
|
||||||
|
continue;
|
||||||
|
if (*str == '~')
|
||||||
|
{
|
||||||
|
strcpy((char *) op->o_opt, home); /* NOSTRICT */
|
||||||
|
start = (char *) op->o_opt + strlen(home);/* NOSTRICT */
|
||||||
|
while (*++str == '/')
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
start = (char *) op->o_opt; /* NOSTRICT */
|
||||||
|
/*
|
||||||
|
* Skip to end of string value
|
||||||
|
*/
|
||||||
|
for (sp = str + 1; *sp && *sp != ','; sp++)
|
||||||
|
continue;
|
||||||
|
/*
|
||||||
|
* check for type of inventory
|
||||||
|
*/
|
||||||
|
if (op->o_putfunc == put_inv_t)
|
||||||
|
{
|
||||||
|
if (islower((int)*str))
|
||||||
|
*str = (char) toupper(*str);
|
||||||
|
for (i = inv_t_name; i <= &inv_t_name[INV_CLEAR]; i++)
|
||||||
|
if (strncmp(str, *i, sp - str) == 0)
|
||||||
|
{
|
||||||
|
inv_type = (int)(i - inv_t_name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
strucpy(start, str, (size_t)(sp - str));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* check for "noname" for booleans
|
||||||
|
*/
|
||||||
|
else if (op->o_putfunc == put_bool
|
||||||
|
&& EQSTR(str, "no", 2) && EQSTR(str + 2, op->o_name, len - 2))
|
||||||
|
{
|
||||||
|
*(int *)op->o_opt = FALSE; /* NOSTRICT */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* skip to start of next option name
|
||||||
|
*/
|
||||||
|
while (*sp && !isalpha((int)*sp))
|
||||||
|
sp++;
|
||||||
|
str = sp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* strucpy:
|
||||||
|
* Copy string using unctrl for things
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
strucpy(char *s1, const char *s2, size_t len)
|
||||||
|
{
|
||||||
|
if (len > MAXINP)
|
||||||
|
len = MAXINP;
|
||||||
|
while (len--)
|
||||||
|
{
|
||||||
|
if (isprint((int)*s2) || *s2 == ' ')
|
||||||
|
*s1++ = *s2;
|
||||||
|
s2++;
|
||||||
|
}
|
||||||
|
*s1 = '\0';
|
||||||
|
}
|
||||||
526
rogue5/pack.c
Normal file
526
rogue5/pack.c
Normal file
|
|
@ -0,0 +1,526 @@
|
||||||
|
/*
|
||||||
|
* Routines to deal with the pack
|
||||||
|
*
|
||||||
|
* @(#)pack.c 4.40 (Berkeley) 02/05/99
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <curses.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "rogue.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* update_mdest:
|
||||||
|
* Called after picking up an object, before discarding it.
|
||||||
|
* If this was the object of something's desire, that monster will
|
||||||
|
* get mad and run at the hero
|
||||||
|
*/
|
||||||
|
update_mdest(obj)
|
||||||
|
register THING *obj;
|
||||||
|
{
|
||||||
|
register THING *mp;
|
||||||
|
|
||||||
|
for (mp = mlist; mp != NULL; mp = next(mp))
|
||||||
|
if (mp->t_dest == &obj->o_pos)
|
||||||
|
mp->t_dest = &hero;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* add_pack:
|
||||||
|
* Pick up an object and add it to the pack. If the argument is
|
||||||
|
* non-null use it as the linked_list pointer instead of gettting
|
||||||
|
* it off the ground.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
add_pack(THING *obj, int silent)
|
||||||
|
{
|
||||||
|
THING *op, *lp;
|
||||||
|
int from_floor;
|
||||||
|
int discarded = 0;
|
||||||
|
|
||||||
|
from_floor = FALSE;
|
||||||
|
if (obj == NULL)
|
||||||
|
{
|
||||||
|
if ((obj = find_obj(hero.y, hero.x)) == NULL)
|
||||||
|
return;
|
||||||
|
from_floor = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for and deal with scare monster scrolls
|
||||||
|
*/
|
||||||
|
if (obj->o_type == SCROLL && obj->o_which == S_SCARE)
|
||||||
|
if (obj->o_flags & ISFOUND)
|
||||||
|
{
|
||||||
|
detach(lvl_obj, obj);
|
||||||
|
mvaddch(hero.y, hero.x, floor_ch());
|
||||||
|
chat(hero.y, hero.x) = (proom->r_flags & ISGONE) ? PASSAGE : FLOOR;
|
||||||
|
update_mdest(obj);
|
||||||
|
discarded = 1;
|
||||||
|
discard(obj);
|
||||||
|
msg("the scroll turns to dust as you pick it up");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pack == NULL)
|
||||||
|
{
|
||||||
|
pack = obj;
|
||||||
|
obj->o_packch = pack_char();
|
||||||
|
inpack++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lp = NULL;
|
||||||
|
for (op = pack; op != NULL; op = next(op))
|
||||||
|
{
|
||||||
|
if (op->o_type != obj->o_type)
|
||||||
|
lp = op;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (op->o_type == obj->o_type && op->o_which != obj->o_which)
|
||||||
|
{
|
||||||
|
lp = op;
|
||||||
|
if (next(op) == NULL)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
op = next(op);
|
||||||
|
}
|
||||||
|
if (op->o_type == obj->o_type && op->o_which == obj->o_which)
|
||||||
|
{
|
||||||
|
if (ISMULT(op->o_type))
|
||||||
|
{
|
||||||
|
if (!pack_room(from_floor, obj))
|
||||||
|
return;
|
||||||
|
op->o_count++;
|
||||||
|
dump_it:
|
||||||
|
update_mdest(obj);
|
||||||
|
discard(obj);
|
||||||
|
obj = op;
|
||||||
|
discarded = 1;
|
||||||
|
lp = NULL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
else if (obj->o_group)
|
||||||
|
{
|
||||||
|
lp = op;
|
||||||
|
while (op->o_type == obj->o_type
|
||||||
|
&& op->o_which == obj->o_which
|
||||||
|
&& op->o_group != obj->o_group)
|
||||||
|
{
|
||||||
|
lp = op;
|
||||||
|
if (next(op) == NULL)
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
op = next(op);
|
||||||
|
}
|
||||||
|
if (op->o_type == obj->o_type
|
||||||
|
&& op->o_which == obj->o_which
|
||||||
|
&& op->o_group == obj->o_group)
|
||||||
|
{
|
||||||
|
op->o_count += obj->o_count;
|
||||||
|
inpack--;
|
||||||
|
if (!pack_room(from_floor, obj))
|
||||||
|
return;
|
||||||
|
goto dump_it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
lp = op;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lp != NULL)
|
||||||
|
{
|
||||||
|
if (!pack_room(from_floor, obj))
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
obj->o_packch = pack_char();
|
||||||
|
next(obj) = next(lp);
|
||||||
|
prev(obj) = lp;
|
||||||
|
if (next(lp) != NULL)
|
||||||
|
prev(next(lp)) = obj;
|
||||||
|
next(lp) = obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
obj->o_flags |= ISFOUND;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If this was the object of something's desire, that monster will
|
||||||
|
* get mad and run at the hero.
|
||||||
|
*/
|
||||||
|
if (!discarded)
|
||||||
|
update_mdest(obj);
|
||||||
|
|
||||||
|
if (obj->o_type == AMULET)
|
||||||
|
amulet = TRUE;
|
||||||
|
/*
|
||||||
|
* Notify the user
|
||||||
|
*/
|
||||||
|
if (!silent)
|
||||||
|
{
|
||||||
|
if (!terse)
|
||||||
|
addmsg("you now have ");
|
||||||
|
msg("%s (%c)", inv_name(obj, !terse), obj->o_packch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pack_room:
|
||||||
|
* See if there's room in the pack. If not, print out an
|
||||||
|
* appropriate message
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
pack_room(int from_floor, THING *obj)
|
||||||
|
{
|
||||||
|
if (++inpack > MAXPACK)
|
||||||
|
{
|
||||||
|
if (!terse)
|
||||||
|
addmsg("there's ");
|
||||||
|
addmsg("no room");
|
||||||
|
if (!terse)
|
||||||
|
addmsg(" in your pack");
|
||||||
|
endmsg();
|
||||||
|
if (from_floor)
|
||||||
|
move_msg(obj);
|
||||||
|
inpack = MAXPACK;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (from_floor)
|
||||||
|
{
|
||||||
|
detach(lvl_obj, obj);
|
||||||
|
mvaddch(hero.y, hero.x, floor_ch());
|
||||||
|
chat(hero.y, hero.x) = (proom->r_flags & ISGONE) ? PASSAGE : FLOOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* leave_pack:
|
||||||
|
* take an item out of the pack
|
||||||
|
*/
|
||||||
|
THING *
|
||||||
|
leave_pack(THING *obj, int newobj, int all)
|
||||||
|
{
|
||||||
|
THING *nobj;
|
||||||
|
|
||||||
|
inpack--;
|
||||||
|
nobj = obj;
|
||||||
|
if (obj->o_count > 1 && !all)
|
||||||
|
{
|
||||||
|
last_pick = obj;
|
||||||
|
obj->o_count--;
|
||||||
|
if (obj->o_group)
|
||||||
|
inpack++;
|
||||||
|
if (newobj)
|
||||||
|
{
|
||||||
|
nobj = new_item();
|
||||||
|
*nobj = *obj;
|
||||||
|
next(nobj) = NULL;
|
||||||
|
prev(nobj) = NULL;
|
||||||
|
nobj->o_count = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
last_pick = NULL;
|
||||||
|
pack_used[obj->o_packch - 'a'] = FALSE;
|
||||||
|
detach(pack, obj);
|
||||||
|
}
|
||||||
|
return nobj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pack_char:
|
||||||
|
* Return the next unused pack character.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
pack_char(void)
|
||||||
|
{
|
||||||
|
int *bp;
|
||||||
|
|
||||||
|
for (bp = pack_used; *bp; bp++)
|
||||||
|
continue;
|
||||||
|
*bp = TRUE;
|
||||||
|
return ((int)(bp - pack_used) + 'a');
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* inventory:
|
||||||
|
* List what is in the pack. Return TRUE if there is something of
|
||||||
|
* the given type.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
inventory(const THING *list, int type)
|
||||||
|
{
|
||||||
|
static char inv_temp[MAXSTR];
|
||||||
|
|
||||||
|
n_objs = 0;
|
||||||
|
for (; list != NULL; list = next(list))
|
||||||
|
{
|
||||||
|
if (type && type != list->o_type && !(type == CALLABLE &&
|
||||||
|
list->o_type != FOOD && list->o_type != AMULET) &&
|
||||||
|
!(type == R_OR_S && (list->o_type == RING || list->o_type == STICK)))
|
||||||
|
continue;
|
||||||
|
n_objs++;
|
||||||
|
#ifdef MASTER
|
||||||
|
if (!list->o_packch)
|
||||||
|
strcpy(inv_temp, "%s");
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
sprintf(inv_temp, "%c) %%s", list->o_packch);
|
||||||
|
msg_esc = TRUE;
|
||||||
|
if (add_line(inv_temp, inv_name(list, FALSE)) == ESCAPE)
|
||||||
|
{
|
||||||
|
msg_esc = FALSE;
|
||||||
|
msg("");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
msg_esc = FALSE;
|
||||||
|
}
|
||||||
|
if (n_objs == 0)
|
||||||
|
{
|
||||||
|
if (terse)
|
||||||
|
msg(type == 0 ? "empty handed" :
|
||||||
|
"nothing appropriate");
|
||||||
|
else
|
||||||
|
msg(type == 0 ? "you are empty handed" :
|
||||||
|
"you don't have anything appropriate");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
end_line();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pick_up:
|
||||||
|
* Add something to characters pack.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
pick_up(int ch)
|
||||||
|
{
|
||||||
|
THING *obj;
|
||||||
|
|
||||||
|
if (on(player, ISLEVIT))
|
||||||
|
return;
|
||||||
|
|
||||||
|
obj = find_obj(hero.y, hero.x);
|
||||||
|
if (move_on)
|
||||||
|
move_msg(obj);
|
||||||
|
else
|
||||||
|
switch (ch)
|
||||||
|
{
|
||||||
|
case GOLD:
|
||||||
|
if (obj == NULL)
|
||||||
|
return;
|
||||||
|
money(obj->o_goldval);
|
||||||
|
detach(lvl_obj, obj);
|
||||||
|
update_mdest(obj);
|
||||||
|
discard(obj);
|
||||||
|
proom->r_goldval = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
#ifdef MASTER
|
||||||
|
debug("Where did you pick a '%s' up???", unctrl(ch));
|
||||||
|
#endif
|
||||||
|
case ARMOR:
|
||||||
|
case POTION:
|
||||||
|
case FOOD:
|
||||||
|
case WEAPON:
|
||||||
|
case SCROLL:
|
||||||
|
case AMULET:
|
||||||
|
case RING:
|
||||||
|
case STICK:
|
||||||
|
add_pack(NULL, FALSE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* move_msg:
|
||||||
|
* Print out the message if you are just moving onto an object
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
move_msg(const THING *obj)
|
||||||
|
{
|
||||||
|
if (!terse)
|
||||||
|
addmsg("you ");
|
||||||
|
msg("moved onto %s", inv_name(obj, TRUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* picky_inven:
|
||||||
|
* Allow player to inventory a single item
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
picky_inven(void)
|
||||||
|
{
|
||||||
|
THING *obj;
|
||||||
|
int mch;
|
||||||
|
|
||||||
|
if (pack == NULL)
|
||||||
|
msg("you aren't carrying anything");
|
||||||
|
else if (next(pack) == NULL)
|
||||||
|
msg("a) %s", inv_name(pack, FALSE));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msg(terse ? "item: " : "which item do you wish to inventory: ");
|
||||||
|
mpos = 0;
|
||||||
|
if ((mch = readchar()) == ESCAPE)
|
||||||
|
{
|
||||||
|
msg("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (obj = pack; obj != NULL; obj = next(obj))
|
||||||
|
if (mch == obj->o_packch)
|
||||||
|
{
|
||||||
|
msg("%c) %s", mch, inv_name(obj, FALSE));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
msg("'%s' not in pack", unctrl(mch));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get_item:
|
||||||
|
* Pick something out of a pack for a purpose
|
||||||
|
*/
|
||||||
|
THING *
|
||||||
|
get_item(const char *purpose, int type)
|
||||||
|
{
|
||||||
|
THING *obj;
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
if (pack == NULL)
|
||||||
|
msg("you aren't carrying anything");
|
||||||
|
else if (again)
|
||||||
|
if (last_pick)
|
||||||
|
return last_pick;
|
||||||
|
else
|
||||||
|
msg("you ran out");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (!terse)
|
||||||
|
addmsg("which object do you want to ");
|
||||||
|
addmsg(purpose);
|
||||||
|
if (terse)
|
||||||
|
addmsg(" what");
|
||||||
|
msg("? (* for list): ");
|
||||||
|
ch = readchar();
|
||||||
|
mpos = 0;
|
||||||
|
/*
|
||||||
|
* Give the poor player a chance to abort the command
|
||||||
|
*/
|
||||||
|
if (ch == ESCAPE)
|
||||||
|
{
|
||||||
|
reset_last();
|
||||||
|
after = FALSE;
|
||||||
|
msg("");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
n_objs = 1; /* normal case: person types one char */
|
||||||
|
if (ch == '*')
|
||||||
|
{
|
||||||
|
mpos = 0;
|
||||||
|
if (inventory(pack, type) == 0)
|
||||||
|
{
|
||||||
|
after = FALSE;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (obj = pack; obj != NULL; obj = next(obj))
|
||||||
|
if (obj->o_packch == ch)
|
||||||
|
break;
|
||||||
|
if (obj == NULL)
|
||||||
|
{
|
||||||
|
msg("'%s' is not a valid item",unctrl(ch));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
msg("");
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* money:
|
||||||
|
* Add or subtract gold from the pack
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
money(int value)
|
||||||
|
{
|
||||||
|
purse += value;
|
||||||
|
mvaddch(hero.y, hero.x, floor_ch());
|
||||||
|
chat(hero.y, hero.x) = (proom->r_flags & ISGONE) ? PASSAGE : FLOOR;
|
||||||
|
if (value > 0)
|
||||||
|
{
|
||||||
|
if (!terse)
|
||||||
|
addmsg("you found ");
|
||||||
|
msg("%d gold pieces", value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* floor_ch:
|
||||||
|
* Return the appropriate floor character for her room
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
floor_ch(void)
|
||||||
|
{
|
||||||
|
if (proom->r_flags & ISGONE)
|
||||||
|
return PASSAGE;
|
||||||
|
return (show_floor() ? FLOOR : ' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* floor_at:
|
||||||
|
* Return the character at hero's position, taking see_floor
|
||||||
|
* into account
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
floor_at(void)
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
ch = chat(hero.y, hero.x);
|
||||||
|
if (ch == FLOOR)
|
||||||
|
ch = floor_ch();
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* reset_last:
|
||||||
|
* Reset the last command when the current one is aborted
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
reset_last(void)
|
||||||
|
{
|
||||||
|
last_comm = l_last_comm;
|
||||||
|
last_dir = l_last_dir;
|
||||||
|
last_pick = l_last_pick;
|
||||||
|
}
|
||||||
424
rogue5/passages.c
Normal file
424
rogue5/passages.c
Normal file
|
|
@ -0,0 +1,424 @@
|
||||||
|
/*
|
||||||
|
* Draw the connecting passages
|
||||||
|
*
|
||||||
|
* @(#)passages.c 4.22 (Berkeley) 02/05/99
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <curses.h>
|
||||||
|
#include "rogue.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* do_passages:
|
||||||
|
* Draw all the passages on a level.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
do_passages(void)
|
||||||
|
{
|
||||||
|
struct rdes *r1, *r2 = NULL;
|
||||||
|
int i, j;
|
||||||
|
int roomcount;
|
||||||
|
struct rdes
|
||||||
|
{
|
||||||
|
int conn[MAXROOMS]; /* possible to connect to room i? */
|
||||||
|
int isconn[MAXROOMS]; /* connection been made to room i? */
|
||||||
|
int ingraph; /* this room in graph already? */
|
||||||
|
} rdes[MAXROOMS] = {
|
||||||
|
{ { 0, 1, 0, 1, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||||
|
{ { 1, 0, 1, 0, 1, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||||
|
{ { 0, 1, 0, 0, 0, 1, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||||
|
{ { 1, 0, 0, 0, 1, 0, 1, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||||
|
{ { 0, 1, 0, 1, 0, 1, 0, 1, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||||
|
{ { 0, 0, 1, 0, 1, 0, 0, 0, 1 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||||
|
{ { 0, 0, 0, 1, 0, 0, 0, 1, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||||
|
{ { 0, 0, 0, 0, 1, 0, 1, 0, 1 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||||
|
{ { 0, 0, 0, 0, 0, 1, 0, 1, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* reinitialize room graph description
|
||||||
|
*/
|
||||||
|
for (r1 = rdes; r1 <= &rdes[MAXROOMS-1]; r1++)
|
||||||
|
{
|
||||||
|
for (j = 0; j < MAXROOMS; j++)
|
||||||
|
r1->isconn[j] = FALSE;
|
||||||
|
r1->ingraph = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* starting with one room, connect it to a random adjacent room and
|
||||||
|
* then pick a new room to start with.
|
||||||
|
*/
|
||||||
|
roomcount = 1;
|
||||||
|
r1 = &rdes[rnd(MAXROOMS)];
|
||||||
|
r1->ingraph = TRUE;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* find a room to connect with
|
||||||
|
*/
|
||||||
|
j = 0;
|
||||||
|
for (i = 0; i < MAXROOMS; i++)
|
||||||
|
if (r1->conn[i] && !rdes[i].ingraph && rnd(++j) == 0)
|
||||||
|
r2 = &rdes[i];
|
||||||
|
/*
|
||||||
|
* if no adjacent rooms are outside the graph, pick a new room
|
||||||
|
* to look from
|
||||||
|
*/
|
||||||
|
if (j == 0)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
r1 = &rdes[rnd(MAXROOMS)];
|
||||||
|
until (r1->ingraph);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* otherwise, connect new room to the graph, and draw a tunnel
|
||||||
|
* to it
|
||||||
|
*/
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r2->ingraph = TRUE;
|
||||||
|
i = (int)(r1 - rdes);
|
||||||
|
j = (int)(r2 - rdes);
|
||||||
|
conn(i, j);
|
||||||
|
r1->isconn[j] = TRUE;
|
||||||
|
r2->isconn[i] = TRUE;
|
||||||
|
roomcount++;
|
||||||
|
}
|
||||||
|
} while (roomcount < MAXROOMS);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* attempt to add passages to the graph a random number of times so
|
||||||
|
* that there isn't always just one unique passage through it.
|
||||||
|
*/
|
||||||
|
for (roomcount = rnd(5); roomcount > 0; roomcount--)
|
||||||
|
{
|
||||||
|
r1 = &rdes[rnd(MAXROOMS)]; /* a random room to look from */
|
||||||
|
/*
|
||||||
|
* find an adjacent room not already connected
|
||||||
|
*/
|
||||||
|
j = 0;
|
||||||
|
for (i = 0; i < MAXROOMS; i++)
|
||||||
|
if (r1->conn[i] && !r1->isconn[i] && rnd(++j) == 0)
|
||||||
|
r2 = &rdes[i];
|
||||||
|
/*
|
||||||
|
* if there is one, connect it and look for the next added
|
||||||
|
* passage
|
||||||
|
*/
|
||||||
|
if (j != 0)
|
||||||
|
{
|
||||||
|
i = (int)(r1 - rdes);
|
||||||
|
j = (int)(r2 - rdes);
|
||||||
|
conn(i, j);
|
||||||
|
r1->isconn[j] = TRUE;
|
||||||
|
r2->isconn[i] = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
passnum();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* conn:
|
||||||
|
* Draw a corridor from a room in a certain direction.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
conn(int r1, int r2)
|
||||||
|
{
|
||||||
|
struct room *rpf, *rpt = NULL;
|
||||||
|
int rmt;
|
||||||
|
int distance = 0, turn_spot, turn_distance = 0;
|
||||||
|
int rm;
|
||||||
|
int direc;
|
||||||
|
static coord del, turn_delta;
|
||||||
|
coord curr, spos, epos;
|
||||||
|
|
||||||
|
if (r1 < r2)
|
||||||
|
{
|
||||||
|
rm = r1;
|
||||||
|
if (r1 + 1 == r2)
|
||||||
|
direc = 'r';
|
||||||
|
else
|
||||||
|
direc = 'd';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rm = r2;
|
||||||
|
if (r2 + 1 == r1)
|
||||||
|
direc = 'r';
|
||||||
|
else
|
||||||
|
direc = 'd';
|
||||||
|
}
|
||||||
|
rpf = &rooms[rm];
|
||||||
|
/*
|
||||||
|
* Set up the movement variables, in two cases:
|
||||||
|
* first drawing one down.
|
||||||
|
*/
|
||||||
|
if (direc == 'd')
|
||||||
|
{
|
||||||
|
rmt = rm + 3; /* room # of dest */
|
||||||
|
rpt = &rooms[rmt]; /* room pointer of dest */
|
||||||
|
del.x = 0; /* direction of move */
|
||||||
|
del.y = 1;
|
||||||
|
spos.x = rpf->r_pos.x; /* start of move */
|
||||||
|
spos.y = rpf->r_pos.y;
|
||||||
|
epos.x = rpt->r_pos.x; /* end of move */
|
||||||
|
epos.y = rpt->r_pos.y;
|
||||||
|
if (!(rpf->r_flags & ISGONE)) /* if not gone pick door pos */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
spos.x = rpf->r_pos.x + rnd(rpf->r_max.x - 2) + 1;
|
||||||
|
spos.y = rpf->r_pos.y + rpf->r_max.y - 1;
|
||||||
|
} while ((rpf->r_flags&ISMAZE) && !(flat(spos.y, spos.x)&F_PASS));
|
||||||
|
if (!(rpt->r_flags & ISGONE))
|
||||||
|
do
|
||||||
|
{
|
||||||
|
epos.x = rpt->r_pos.x + rnd(rpt->r_max.x - 2) + 1;
|
||||||
|
} while ((rpt->r_flags&ISMAZE) && !(flat(epos.y, epos.x)&F_PASS));
|
||||||
|
distance = abs(spos.y - epos.y) - 1; /* distance to move */
|
||||||
|
turn_delta.y = 0; /* direction to turn */
|
||||||
|
turn_delta.x = (spos.x < epos.x ? 1 : -1);
|
||||||
|
turn_distance = abs(spos.x - epos.x); /* how far to turn */
|
||||||
|
}
|
||||||
|
else if (direc == 'r') /* setup for moving right */
|
||||||
|
{
|
||||||
|
rmt = rm + 1;
|
||||||
|
rpt = &rooms[rmt];
|
||||||
|
del.x = 1;
|
||||||
|
del.y = 0;
|
||||||
|
spos.x = rpf->r_pos.x;
|
||||||
|
spos.y = rpf->r_pos.y;
|
||||||
|
epos.x = rpt->r_pos.x;
|
||||||
|
epos.y = rpt->r_pos.y;
|
||||||
|
if (!(rpf->r_flags & ISGONE))
|
||||||
|
do
|
||||||
|
{
|
||||||
|
spos.x = rpf->r_pos.x + rpf->r_max.x - 1;
|
||||||
|
spos.y = rpf->r_pos.y + rnd(rpf->r_max.y - 2) + 1;
|
||||||
|
} while ((rpf->r_flags&ISMAZE) && !(flat(spos.y, spos.x)&F_PASS));
|
||||||
|
if (!(rpt->r_flags & ISGONE))
|
||||||
|
do
|
||||||
|
{
|
||||||
|
epos.y = rpt->r_pos.y + rnd(rpt->r_max.y - 2) + 1;
|
||||||
|
} while ((rpt->r_flags&ISMAZE) && !(flat(epos.y, epos.x)&F_PASS));
|
||||||
|
distance = abs(spos.x - epos.x) - 1;
|
||||||
|
turn_delta.y = (spos.y < epos.y ? 1 : -1);
|
||||||
|
turn_delta.x = 0;
|
||||||
|
turn_distance = abs(spos.y - epos.y);
|
||||||
|
}
|
||||||
|
#ifdef MASTER
|
||||||
|
else
|
||||||
|
debug("error in connection tables");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
turn_spot = rnd(distance - 1) + 1; /* where turn starts */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Draw in the doors on either side of the passage or just put #'s
|
||||||
|
* if the rooms are gone.
|
||||||
|
*/
|
||||||
|
if (!(rpf->r_flags & ISGONE))
|
||||||
|
door(rpf, &spos);
|
||||||
|
else
|
||||||
|
putpass(&spos);
|
||||||
|
if (!(rpt->r_flags & ISGONE))
|
||||||
|
door(rpt, &epos);
|
||||||
|
else
|
||||||
|
putpass(&epos);
|
||||||
|
/*
|
||||||
|
* Get ready to move...
|
||||||
|
*/
|
||||||
|
curr.x = spos.x;
|
||||||
|
curr.y = spos.y;
|
||||||
|
while (distance > 0)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Move to new position
|
||||||
|
*/
|
||||||
|
curr.x += del.x;
|
||||||
|
curr.y += del.y;
|
||||||
|
/*
|
||||||
|
* Check if we are at the turn place, if so do the turn
|
||||||
|
*/
|
||||||
|
if (distance == turn_spot)
|
||||||
|
while (turn_distance--)
|
||||||
|
{
|
||||||
|
putpass(&curr);
|
||||||
|
curr.x += turn_delta.x;
|
||||||
|
curr.y += turn_delta.y;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Continue digging along
|
||||||
|
*/
|
||||||
|
putpass(&curr);
|
||||||
|
distance--;
|
||||||
|
}
|
||||||
|
curr.x += del.x;
|
||||||
|
curr.y += del.y;
|
||||||
|
if (!ce(curr, epos))
|
||||||
|
msg("warning, connectivity problem on this level");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* putpass:
|
||||||
|
* add a passage character or secret passage here
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
putpass(const coord *cp)
|
||||||
|
{
|
||||||
|
PLACE *pp;
|
||||||
|
|
||||||
|
pp = INDEX(cp->y, cp->x);
|
||||||
|
pp->p_flags |= F_PASS;
|
||||||
|
if (rnd(10) + 1 < level && rnd(40) == 0)
|
||||||
|
pp->p_flags &= ~F_REAL;
|
||||||
|
else
|
||||||
|
pp->p_ch = PASSAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* door:
|
||||||
|
* Add a door or possibly a secret door. Also enters the door in
|
||||||
|
* the exits array of the room.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
door(struct room *rm, const coord *cp)
|
||||||
|
{
|
||||||
|
PLACE *pp;
|
||||||
|
|
||||||
|
rm->r_exit[rm->r_nexits++] = *cp;
|
||||||
|
|
||||||
|
if (rm->r_flags & ISMAZE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pp = INDEX(cp->y, cp->x);
|
||||||
|
if (rnd(10) + 1 < level && rnd(5) == 0)
|
||||||
|
{
|
||||||
|
if (cp->y == rm->r_pos.y || cp->y == rm->r_pos.y + rm->r_max.y - 1)
|
||||||
|
pp->p_ch = '-';
|
||||||
|
else
|
||||||
|
pp->p_ch = '|';
|
||||||
|
pp->p_flags &= ~F_REAL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pp->p_ch = DOOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MASTER
|
||||||
|
/*
|
||||||
|
* add_pass:
|
||||||
|
* Add the passages to the current window (wizard command)
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
add_pass(void)
|
||||||
|
{
|
||||||
|
PLACE *pp;
|
||||||
|
int y, x;
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
for (y = 1; y < NUMLINES - 1; y++)
|
||||||
|
for (x = 0; x < NUMCOLS; x++)
|
||||||
|
{
|
||||||
|
pp = INDEX(y, x);
|
||||||
|
if ((pp->p_flags & F_PASS) || pp->p_ch == DOOR ||
|
||||||
|
(!(pp->p_flags&F_REAL) && (pp->p_ch == '|' || pp->p_ch == '-')))
|
||||||
|
{
|
||||||
|
ch = pp->p_ch;
|
||||||
|
if (pp->p_flags & F_PASS)
|
||||||
|
ch = PASSAGE;
|
||||||
|
pp->p_flags |= F_SEEN;
|
||||||
|
move(y, x);
|
||||||
|
if (pp->p_monst != NULL)
|
||||||
|
pp->p_monst->t_oldch = pp->p_ch;
|
||||||
|
else if (pp->p_flags & F_REAL)
|
||||||
|
addch(ch);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
standout();
|
||||||
|
addch((pp->p_flags & F_PASS) ? PASSAGE : DOOR);
|
||||||
|
standend();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* passnum:
|
||||||
|
* Assign a number to each passageway
|
||||||
|
*/
|
||||||
|
static int pnum;
|
||||||
|
static int newpnum;
|
||||||
|
|
||||||
|
void
|
||||||
|
passnum(void)
|
||||||
|
{
|
||||||
|
struct room *rp;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
pnum = 0;
|
||||||
|
newpnum = FALSE;
|
||||||
|
for (rp = passages; rp < &passages[MAXPASS]; rp++)
|
||||||
|
rp->r_nexits = 0;
|
||||||
|
for (rp = rooms; rp < &rooms[MAXROOMS]; rp++)
|
||||||
|
for (i = 0; i < rp->r_nexits; i++)
|
||||||
|
{
|
||||||
|
newpnum++;
|
||||||
|
numpass(rp->r_exit[i].y, rp->r_exit[i].x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* numpass:
|
||||||
|
* Number a passageway square and its brethren
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
numpass(int y, int x)
|
||||||
|
{
|
||||||
|
int *fp;
|
||||||
|
struct room *rp;
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
if (x >= NUMCOLS || x < 0 || y >= NUMLINES || y <= 0)
|
||||||
|
return;
|
||||||
|
fp = &flat(y, x);
|
||||||
|
if (*fp & F_PNUM)
|
||||||
|
return;
|
||||||
|
if (newpnum)
|
||||||
|
{
|
||||||
|
pnum++;
|
||||||
|
newpnum = FALSE;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* check to see if it is a door or secret door, i.e., a new exit,
|
||||||
|
* or a numerable type of place
|
||||||
|
*/
|
||||||
|
if ((ch = chat(y, x)) == DOOR ||
|
||||||
|
(!(*fp & F_REAL) && (ch == '|' || ch == '-')))
|
||||||
|
{
|
||||||
|
rp = &passages[pnum];
|
||||||
|
rp->r_exit[rp->r_nexits].y = y;
|
||||||
|
rp->r_exit[rp->r_nexits++].x = x;
|
||||||
|
}
|
||||||
|
else if (!(*fp & F_PASS))
|
||||||
|
return;
|
||||||
|
*fp |= pnum;
|
||||||
|
/*
|
||||||
|
* recurse on the surrounding places
|
||||||
|
*/
|
||||||
|
numpass(y + 1, x);
|
||||||
|
numpass(y - 1, x);
|
||||||
|
numpass(y, x + 1);
|
||||||
|
numpass(y, x - 1);
|
||||||
|
}
|
||||||
375
rogue5/potions.c
Normal file
375
rogue5/potions.c
Normal file
|
|
@ -0,0 +1,375 @@
|
||||||
|
/*
|
||||||
|
* Function(s) for dealing with potions
|
||||||
|
*
|
||||||
|
* @(#)potions.c 4.46 (Berkeley) 06/07/83
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <curses.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "rogue.h"
|
||||||
|
|
||||||
|
typedef struct PACT
|
||||||
|
{
|
||||||
|
const int pa_flags;
|
||||||
|
void (*pa_daemon)();
|
||||||
|
const int pa_time;
|
||||||
|
const char *pa_high, *pa_straight;
|
||||||
|
} PACT;
|
||||||
|
|
||||||
|
static const PACT p_actions[] =
|
||||||
|
{
|
||||||
|
{ ISHUH, unconfuse, HUHDURATION, /* P_CONFUSE */
|
||||||
|
"what a tripy feeling!",
|
||||||
|
"wait, what's going on here. Huh? What? Who?" },
|
||||||
|
{ ISHALU, come_down, SEEDURATION, /* P_LSD */
|
||||||
|
"Oh, wow! Everything seems so cosmic!",
|
||||||
|
"Oh, wow! Everything seems so cosmic!" },
|
||||||
|
{ 0, NULL, 0 }, /* P_POISON */
|
||||||
|
{ 0, NULL, 0 }, /* P_STRENGTH */
|
||||||
|
{ CANSEE, unsee, SEEDURATION, /* P_SEEINVIS */
|
||||||
|
prbuf,
|
||||||
|
prbuf },
|
||||||
|
{ 0, NULL, 0 }, /* P_HEALING */
|
||||||
|
{ 0, NULL, 0 }, /* P_MFIND */
|
||||||
|
{ 0, NULL, 0 }, /* P_TFIND */
|
||||||
|
{ 0, NULL, 0 }, /* P_RAISE */
|
||||||
|
{ 0, NULL, 0 }, /* P_XHEAL */
|
||||||
|
{ 0, NULL, 0 }, /* P_HASTE */
|
||||||
|
{ 0, NULL, 0 }, /* P_RESTORE */
|
||||||
|
{ ISBLIND, sight, SEEDURATION, /* P_BLIND */
|
||||||
|
"oh, bummer! Everything is dark! Help!",
|
||||||
|
"a cloak of darkness falls around you" },
|
||||||
|
{ ISLEVIT, land, HEALTIME, /* P_LEVIT */
|
||||||
|
"oh, wow! You're floating in the air!",
|
||||||
|
"you start to float in the air" }
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* quaff:
|
||||||
|
* Quaff a potion from the pack
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
quaff(void)
|
||||||
|
{
|
||||||
|
THING *obj, *tp, *mp;
|
||||||
|
int discardit = FALSE;
|
||||||
|
int show, trip;
|
||||||
|
|
||||||
|
obj = get_item("quaff", POTION);
|
||||||
|
/*
|
||||||
|
* Make certain that it is somethings that we want to drink
|
||||||
|
*/
|
||||||
|
if (obj == NULL)
|
||||||
|
return;
|
||||||
|
if (obj->o_type != POTION)
|
||||||
|
{
|
||||||
|
if (!terse)
|
||||||
|
msg("yuk! Why would you want to drink that?");
|
||||||
|
else
|
||||||
|
msg("that's undrinkable");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (obj == cur_weapon)
|
||||||
|
cur_weapon = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculate the effect it has on the poor guy.
|
||||||
|
*/
|
||||||
|
trip = on(player, ISHALU);
|
||||||
|
discardit = (obj->o_count == 1);
|
||||||
|
leave_pack(obj, FALSE, FALSE);
|
||||||
|
switch (obj->o_which)
|
||||||
|
{
|
||||||
|
case P_CONFUSE:
|
||||||
|
do_pot(P_CONFUSE, !trip);
|
||||||
|
when P_POISON:
|
||||||
|
pot_info[P_POISON].oi_know = TRUE;
|
||||||
|
if (ISWEARING(R_SUSTSTR))
|
||||||
|
msg("you feel momentarily sick");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
chg_str(-(rnd(3) + 1));
|
||||||
|
msg("you feel very sick now");
|
||||||
|
come_down();
|
||||||
|
}
|
||||||
|
when P_HEALING:
|
||||||
|
pot_info[P_HEALING].oi_know = TRUE;
|
||||||
|
if ((pstats.s_hpt += roll(pstats.s_lvl, 4)) > max_hp)
|
||||||
|
pstats.s_hpt = ++max_hp;
|
||||||
|
sight();
|
||||||
|
msg("you begin to feel better");
|
||||||
|
when P_STRENGTH:
|
||||||
|
pot_info[P_STRENGTH].oi_know = TRUE;
|
||||||
|
chg_str(1);
|
||||||
|
msg("you feel stronger, now. What bulging muscles!");
|
||||||
|
when P_MFIND:
|
||||||
|
player.t_flags |= SEEMONST;
|
||||||
|
fuse((void(*)())turn_see, TRUE, HUHDURATION, AFTER);
|
||||||
|
if (!turn_see(FALSE))
|
||||||
|
msg("you have a %s feeling for a moment, then it passes",
|
||||||
|
choose_str("normal", "strange"));
|
||||||
|
when P_TFIND:
|
||||||
|
/*
|
||||||
|
* Potion of magic detection. Show the potions and scrolls
|
||||||
|
*/
|
||||||
|
show = FALSE;
|
||||||
|
if (lvl_obj != NULL)
|
||||||
|
{
|
||||||
|
wclear(hw);
|
||||||
|
for (tp = lvl_obj; tp != NULL; tp = next(tp))
|
||||||
|
{
|
||||||
|
if (is_magic(tp))
|
||||||
|
{
|
||||||
|
show = TRUE;
|
||||||
|
wmove(hw, tp->o_pos.y, tp->o_pos.x);
|
||||||
|
waddch(hw, MAGIC);
|
||||||
|
pot_info[P_TFIND].oi_know = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (mp = mlist; mp != NULL; mp = next(mp))
|
||||||
|
{
|
||||||
|
for (tp = mp->t_pack; tp != NULL; tp = next(tp))
|
||||||
|
{
|
||||||
|
if (is_magic(tp))
|
||||||
|
{
|
||||||
|
show = TRUE;
|
||||||
|
wmove(hw, mp->t_pos.y, mp->t_pos.x);
|
||||||
|
waddch(hw, MAGIC);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (show)
|
||||||
|
{
|
||||||
|
pot_info[P_TFIND].oi_know = TRUE;
|
||||||
|
show_win("You sense the presence of magic on this level.--More--");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
msg("you have a %s feeling for a moment, then it passes",
|
||||||
|
choose_str("normal", "strange"));
|
||||||
|
when P_LSD:
|
||||||
|
if (!trip)
|
||||||
|
{
|
||||||
|
if (on(player, SEEMONST))
|
||||||
|
turn_see(FALSE);
|
||||||
|
start_daemon(visuals, 0, BEFORE);
|
||||||
|
seenstairs = seen_stairs();
|
||||||
|
}
|
||||||
|
do_pot(P_LSD, TRUE);
|
||||||
|
when P_SEEINVIS:
|
||||||
|
sprintf(prbuf, "this potion tastes like %s juice", fruit);
|
||||||
|
show = on(player, CANSEE);
|
||||||
|
do_pot(P_SEEINVIS, FALSE);
|
||||||
|
if (!show)
|
||||||
|
invis_on();
|
||||||
|
sight();
|
||||||
|
when P_RAISE:
|
||||||
|
pot_info[P_RAISE].oi_know = TRUE;
|
||||||
|
msg("you suddenly feel much more skillful");
|
||||||
|
raise_level();
|
||||||
|
when P_XHEAL:
|
||||||
|
pot_info[P_XHEAL].oi_know = TRUE;
|
||||||
|
if ((pstats.s_hpt += roll(pstats.s_lvl, 8)) > max_hp)
|
||||||
|
{
|
||||||
|
if (pstats.s_hpt > max_hp + pstats.s_lvl + 1)
|
||||||
|
++max_hp;
|
||||||
|
pstats.s_hpt = ++max_hp;
|
||||||
|
}
|
||||||
|
sight();
|
||||||
|
come_down();
|
||||||
|
msg("you begin to feel much better");
|
||||||
|
when P_HASTE:
|
||||||
|
pot_info[P_HASTE].oi_know = TRUE;
|
||||||
|
after = FALSE;
|
||||||
|
if (add_haste(TRUE))
|
||||||
|
msg("you feel yourself moving much faster");
|
||||||
|
when P_RESTORE:
|
||||||
|
if (ISRING(LEFT, R_ADDSTR))
|
||||||
|
add_str(&pstats.s_str, -cur_ring[LEFT]->o_arm);
|
||||||
|
if (ISRING(RIGHT, R_ADDSTR))
|
||||||
|
add_str(&pstats.s_str, -cur_ring[RIGHT]->o_arm);
|
||||||
|
if (pstats.s_str < max_stats.s_str)
|
||||||
|
pstats.s_str = max_stats.s_str;
|
||||||
|
if (ISRING(LEFT, R_ADDSTR))
|
||||||
|
add_str(&pstats.s_str, cur_ring[LEFT]->o_arm);
|
||||||
|
if (ISRING(RIGHT, R_ADDSTR))
|
||||||
|
add_str(&pstats.s_str, cur_ring[RIGHT]->o_arm);
|
||||||
|
msg("hey, this tastes great. It make you feel warm all over");
|
||||||
|
when P_BLIND:
|
||||||
|
do_pot(P_BLIND, TRUE);
|
||||||
|
when P_LEVIT:
|
||||||
|
do_pot(P_LEVIT, TRUE);
|
||||||
|
#ifdef MASTER
|
||||||
|
otherwise:
|
||||||
|
msg("what an odd tasting potion!");
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
status();
|
||||||
|
/*
|
||||||
|
* Throw the item away
|
||||||
|
*/
|
||||||
|
|
||||||
|
call_it(&pot_info[obj->o_which]);
|
||||||
|
|
||||||
|
if (discardit)
|
||||||
|
discard(obj);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* is_magic:
|
||||||
|
* Returns true if an object radiates magic
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
is_magic(const THING *obj)
|
||||||
|
{
|
||||||
|
switch (obj->o_type)
|
||||||
|
{
|
||||||
|
case ARMOR:
|
||||||
|
return ((obj->o_flags&ISPROT) || obj->o_arm != a_class[obj->o_which]);
|
||||||
|
case WEAPON:
|
||||||
|
return (obj->o_hplus != 0 || obj->o_dplus != 0);
|
||||||
|
case POTION:
|
||||||
|
case SCROLL:
|
||||||
|
case STICK:
|
||||||
|
case RING:
|
||||||
|
case AMULET:
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* invis_on:
|
||||||
|
* Turn on the ability to see invisible
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
invis_on(void)
|
||||||
|
{
|
||||||
|
THING *mp;
|
||||||
|
|
||||||
|
player.t_flags |= CANSEE;
|
||||||
|
for (mp = mlist; mp != NULL; mp = next(mp))
|
||||||
|
if (on(*mp, ISINVIS) && see_monst(mp) && !on(player, ISHALU))
|
||||||
|
mvaddch(mp->t_pos.y, mp->t_pos.x, mp->t_disguise);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* turn_see:
|
||||||
|
* Put on or off seeing monsters on this level
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
turn_see(int turn_off)
|
||||||
|
{
|
||||||
|
THING *mp;
|
||||||
|
int can_see, add_new;
|
||||||
|
|
||||||
|
add_new = FALSE;
|
||||||
|
for (mp = mlist; mp != NULL; mp = next(mp))
|
||||||
|
{
|
||||||
|
move(mp->t_pos.y, mp->t_pos.x);
|
||||||
|
can_see = see_monst(mp);
|
||||||
|
if (turn_off)
|
||||||
|
{
|
||||||
|
if (!can_see)
|
||||||
|
addch(mp->t_oldch);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!can_see)
|
||||||
|
standout();
|
||||||
|
if (!on(player, ISHALU))
|
||||||
|
addch(mp->t_type);
|
||||||
|
else
|
||||||
|
addch(rnd(26) + 'A');
|
||||||
|
if (!can_see)
|
||||||
|
{
|
||||||
|
standend();
|
||||||
|
add_new++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (turn_off)
|
||||||
|
player.t_flags &= ~SEEMONST;
|
||||||
|
else
|
||||||
|
player.t_flags |= SEEMONST;
|
||||||
|
return add_new;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* seen_stairs:
|
||||||
|
* Return TRUE if the player has seen the stairs
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
seen_stairs(void)
|
||||||
|
{
|
||||||
|
THING *tp;
|
||||||
|
|
||||||
|
move(stairs.y, stairs.x);
|
||||||
|
if (CCHAR( inch() ) == STAIRS) /* it's on the map */
|
||||||
|
return TRUE;
|
||||||
|
if (ce(hero, stairs)) /* It's under him */
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if a monster is on the stairs, this gets hairy
|
||||||
|
*/
|
||||||
|
if ((tp = moat(stairs.y, stairs.x)) != NULL)
|
||||||
|
{
|
||||||
|
if (see_monst(tp) && on(*tp, ISRUN)) /* if it's visible and awake */
|
||||||
|
return TRUE; /* it must have moved there */
|
||||||
|
|
||||||
|
if (on(player, SEEMONST) /* if she can detect monster */
|
||||||
|
&& tp->t_oldch == STAIRS) /* and there once were stairs */
|
||||||
|
return TRUE; /* it must have moved there */
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* raise_level:
|
||||||
|
* The guy just magically went up a level.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
raise_level(void)
|
||||||
|
{
|
||||||
|
pstats.s_exp = e_levels[pstats.s_lvl-1] + 1L;
|
||||||
|
check_level();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* do_pot:
|
||||||
|
* Do a potion with standard setup. This means it uses a fuse and
|
||||||
|
* turns on a flag
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
do_pot(int type, int knowit)
|
||||||
|
{
|
||||||
|
const PACT *pp;
|
||||||
|
int t;
|
||||||
|
|
||||||
|
pp = &p_actions[type];
|
||||||
|
if (!pot_info[type].oi_know)
|
||||||
|
pot_info[type].oi_know = knowit;
|
||||||
|
t = spread(pp->pa_time);
|
||||||
|
if (!on(player, pp->pa_flags))
|
||||||
|
{
|
||||||
|
player.t_flags |= pp->pa_flags;
|
||||||
|
fuse(pp->pa_daemon, 0, t, AFTER);
|
||||||
|
look(FALSE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
lengthen(pp->pa_daemon, t);
|
||||||
|
msg(choose_str(pp->pa_high, pp->pa_straight));
|
||||||
|
}
|
||||||
204
rogue5/rings.c
Normal file
204
rogue5/rings.c
Normal file
|
|
@ -0,0 +1,204 @@
|
||||||
|
/*
|
||||||
|
* Routines dealing specifically with rings
|
||||||
|
*
|
||||||
|
* @(#)rings.c 4.19 (Berkeley) 05/29/83
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <curses.h>
|
||||||
|
#include "rogue.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ring_on:
|
||||||
|
* Put a ring on a hand
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
ring_on(void)
|
||||||
|
{
|
||||||
|
THING *obj;
|
||||||
|
int ring;
|
||||||
|
|
||||||
|
obj = get_item("put on", RING);
|
||||||
|
/*
|
||||||
|
* Make certain that it is somethings that we want to wear
|
||||||
|
*/
|
||||||
|
if (obj == NULL)
|
||||||
|
return;
|
||||||
|
if (obj->o_type != RING)
|
||||||
|
{
|
||||||
|
if (!terse)
|
||||||
|
msg("it would be difficult to wrap that around a finger");
|
||||||
|
else
|
||||||
|
msg("not a ring");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* find out which hand to put it on
|
||||||
|
*/
|
||||||
|
if (is_current(obj))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (cur_ring[LEFT] == NULL && cur_ring[RIGHT] == NULL)
|
||||||
|
{
|
||||||
|
if ((ring = gethand()) < 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (cur_ring[LEFT] == NULL)
|
||||||
|
ring = LEFT;
|
||||||
|
else if (cur_ring[RIGHT] == NULL)
|
||||||
|
ring = RIGHT;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!terse)
|
||||||
|
msg("you already have a ring on each hand");
|
||||||
|
else
|
||||||
|
msg("wearing two");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cur_ring[ring] = obj;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculate the effect it has on the poor guy.
|
||||||
|
*/
|
||||||
|
switch (obj->o_which)
|
||||||
|
{
|
||||||
|
case R_ADDSTR:
|
||||||
|
chg_str(obj->o_arm);
|
||||||
|
break;
|
||||||
|
case R_SEEINVIS:
|
||||||
|
invis_on();
|
||||||
|
break;
|
||||||
|
case R_AGGR:
|
||||||
|
aggravate();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!terse)
|
||||||
|
addmsg("you are now wearing ");
|
||||||
|
msg("%s (%c)", inv_name(obj, TRUE), obj->o_packch);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ring_off:
|
||||||
|
* take off a ring
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
ring_off(void)
|
||||||
|
{
|
||||||
|
int ring;
|
||||||
|
THING *obj;
|
||||||
|
|
||||||
|
if (cur_ring[LEFT] == NULL && cur_ring[RIGHT] == NULL)
|
||||||
|
{
|
||||||
|
if (terse)
|
||||||
|
msg("no rings");
|
||||||
|
else
|
||||||
|
msg("you aren't wearing any rings");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (cur_ring[LEFT] == NULL)
|
||||||
|
ring = RIGHT;
|
||||||
|
else if (cur_ring[RIGHT] == NULL)
|
||||||
|
ring = LEFT;
|
||||||
|
else
|
||||||
|
if ((ring = gethand()) < 0)
|
||||||
|
return;
|
||||||
|
mpos = 0;
|
||||||
|
obj = cur_ring[ring];
|
||||||
|
if (obj == NULL)
|
||||||
|
{
|
||||||
|
msg("not wearing such a ring");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (dropcheck(obj))
|
||||||
|
msg("was wearing %s(%c)", inv_name(obj, TRUE), obj->o_packch);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* gethand:
|
||||||
|
* Which hand is the hero interested in?
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
gethand(void)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (terse)
|
||||||
|
msg("left or right ring? ");
|
||||||
|
else
|
||||||
|
msg("left hand or right hand? ");
|
||||||
|
if ((c = readchar()) == ESCAPE)
|
||||||
|
return -1;
|
||||||
|
mpos = 0;
|
||||||
|
if (c == 'l' || c == 'L')
|
||||||
|
return LEFT;
|
||||||
|
else if (c == 'r' || c == 'R')
|
||||||
|
return RIGHT;
|
||||||
|
if (terse)
|
||||||
|
msg("L or R");
|
||||||
|
else
|
||||||
|
msg("please type L or R");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ring_eat:
|
||||||
|
* How much food does this ring use up?
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ring_eat(int hand)
|
||||||
|
{
|
||||||
|
THING *ring;
|
||||||
|
int eat;
|
||||||
|
int uses[] = {
|
||||||
|
1, /* R_PROTECT */ 1, /* R_ADDSTR */
|
||||||
|
1, /* R_SUSTSTR */ -3, /* R_SEARCH */
|
||||||
|
-5, /* R_SEEINVIS */ 0, /* R_NOP */
|
||||||
|
0, /* R_AGGR */ -3, /* R_ADDHIT */
|
||||||
|
-3, /* R_ADDDAM */ 2, /* R_REGEN */
|
||||||
|
-2, /* R_DIGEST */ 0, /* R_TELEPORT */
|
||||||
|
1, /* R_STEALTH */ 1 /* R_SUSTARM */
|
||||||
|
};
|
||||||
|
|
||||||
|
if ((ring = cur_ring[hand]) == NULL)
|
||||||
|
return 0;
|
||||||
|
if ((eat = uses[ring->o_which]) < 0)
|
||||||
|
eat = (rnd(-eat) == 0);
|
||||||
|
if (ring->o_which == R_DIGEST)
|
||||||
|
eat = -eat;
|
||||||
|
return eat;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ring_num:
|
||||||
|
* Print ring bonuses
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
ring_num(const THING *obj)
|
||||||
|
{
|
||||||
|
static char buf[10];
|
||||||
|
|
||||||
|
if (!(obj->o_flags & ISKNOW))
|
||||||
|
return "";
|
||||||
|
switch (obj->o_which)
|
||||||
|
{
|
||||||
|
case R_PROTECT:
|
||||||
|
case R_ADDSTR:
|
||||||
|
case R_ADDDAM:
|
||||||
|
case R_ADDHIT:
|
||||||
|
sprintf(buf, " [%s]", num(obj->o_arm, 0, RING));
|
||||||
|
otherwise:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
450
rogue5/rip.c
Normal file
450
rogue5/rip.c
Normal file
|
|
@ -0,0 +1,450 @@
|
||||||
|
/*
|
||||||
|
* File for the fun ends
|
||||||
|
* Death or a total win
|
||||||
|
*
|
||||||
|
* @(#)rip.c 4.57 (Berkeley) 02/05/99
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <curses.h>
|
||||||
|
#include "rogue.h"
|
||||||
|
#include "score.h"
|
||||||
|
|
||||||
|
static char *rip[] = {
|
||||||
|
" __________\n",
|
||||||
|
" / \\\n",
|
||||||
|
" / REST \\\n",
|
||||||
|
" / IN \\\n",
|
||||||
|
" / PEACE \\\n",
|
||||||
|
" / \\\n",
|
||||||
|
" | |\n",
|
||||||
|
" | |\n",
|
||||||
|
" | killed by a |\n",
|
||||||
|
" | |\n",
|
||||||
|
" | 1980 |\n",
|
||||||
|
" *| * * * | *\n",
|
||||||
|
" ________)/\\\\_//(\\/(/\\)/\\//\\/|_)_______\n",
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* score:
|
||||||
|
* Figure score and post it.
|
||||||
|
*/
|
||||||
|
/* VARARGS2 */
|
||||||
|
|
||||||
|
void
|
||||||
|
score(int amount, int flags, int monst)
|
||||||
|
{
|
||||||
|
SCORE *scp;
|
||||||
|
int i;
|
||||||
|
SCORE *sc2;
|
||||||
|
SCORE *top_ten, *endp;
|
||||||
|
# ifdef MASTER
|
||||||
|
int prflags = 0;
|
||||||
|
# endif
|
||||||
|
void (*fp)(int);
|
||||||
|
uid_t uid;
|
||||||
|
char *reason[] = {
|
||||||
|
"killed",
|
||||||
|
"quit",
|
||||||
|
"A total winner",
|
||||||
|
"killed with Amulet"
|
||||||
|
};
|
||||||
|
|
||||||
|
start_score();
|
||||||
|
|
||||||
|
if (flags >= 0
|
||||||
|
#ifdef MASTER
|
||||||
|
|| wizard
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
{
|
||||||
|
mvaddstr(LINES - 1, 0 , "[Press return to continue]");
|
||||||
|
refresh();
|
||||||
|
wgetnstr(stdscr,prbuf,80);
|
||||||
|
endwin();
|
||||||
|
printf("\n");
|
||||||
|
resetltchars();
|
||||||
|
/*
|
||||||
|
* free up space to "guarantee" there is space for the top_ten
|
||||||
|
*/
|
||||||
|
delwin(stdscr);
|
||||||
|
delwin(curscr);
|
||||||
|
if (hw != NULL)
|
||||||
|
delwin(hw);
|
||||||
|
}
|
||||||
|
|
||||||
|
top_ten = malloc(numscores * sizeof (SCORE));
|
||||||
|
|
||||||
|
if (top_ten == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
endp = &top_ten[numscores];
|
||||||
|
for (scp = top_ten; scp < endp; scp++)
|
||||||
|
{
|
||||||
|
scp->sc_score = 0;
|
||||||
|
for (i = 0; i < MAXSTR; i++)
|
||||||
|
scp->sc_name[i] = (char) rnd(255);
|
||||||
|
scp->sc_flags = RN;
|
||||||
|
scp->sc_level = RN;
|
||||||
|
scp->sc_monster = RN;
|
||||||
|
scp->sc_uid = RN;
|
||||||
|
}
|
||||||
|
|
||||||
|
signal(SIGINT, SIG_DFL);
|
||||||
|
|
||||||
|
#ifdef MASTER
|
||||||
|
if (wizard)
|
||||||
|
if (strcmp(prbuf, "names") == 0)
|
||||||
|
prflags = 1;
|
||||||
|
else if (strcmp(prbuf, "edit") == 0)
|
||||||
|
prflags = 2;
|
||||||
|
#endif
|
||||||
|
rd_score(top_ten);
|
||||||
|
/*
|
||||||
|
* Insert her in list if need be
|
||||||
|
*/
|
||||||
|
sc2 = NULL;
|
||||||
|
if (!noscore)
|
||||||
|
{
|
||||||
|
uid = md_getuid();
|
||||||
|
for (scp = top_ten; scp < endp; scp++)
|
||||||
|
if (amount > scp->sc_score)
|
||||||
|
break;
|
||||||
|
else if (!allscore && /* only one score per nowin uid */
|
||||||
|
flags != 2 && scp->sc_uid == uid && scp->sc_flags != 2)
|
||||||
|
scp = endp;
|
||||||
|
if (scp < endp)
|
||||||
|
{
|
||||||
|
if (flags != 2 && !allscore)
|
||||||
|
{
|
||||||
|
for (sc2 = scp; sc2 < endp; sc2++)
|
||||||
|
{
|
||||||
|
if (sc2->sc_uid == uid && sc2->sc_flags != 2)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (sc2 >= endp)
|
||||||
|
sc2 = endp - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sc2 = endp - 1;
|
||||||
|
while (sc2 > scp)
|
||||||
|
{
|
||||||
|
*sc2 = sc2[-1];
|
||||||
|
sc2--;
|
||||||
|
}
|
||||||
|
scp->sc_score = amount;
|
||||||
|
strncpy(scp->sc_name, whoami, MAXSTR);
|
||||||
|
scp->sc_flags = flags;
|
||||||
|
if (flags == 2)
|
||||||
|
scp->sc_level = max_level;
|
||||||
|
else
|
||||||
|
scp->sc_level = level;
|
||||||
|
scp->sc_monster = monst;
|
||||||
|
scp->sc_uid = uid;
|
||||||
|
sc2 = scp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Print the list
|
||||||
|
*/
|
||||||
|
if (flags != -1)
|
||||||
|
putchar('\n');
|
||||||
|
printf("Top %s %s:\n", Numname, allscore ? "Scores" : "Rogueists");
|
||||||
|
printf(" Score Name\n");
|
||||||
|
for (scp = top_ten; scp < endp; scp++)
|
||||||
|
{
|
||||||
|
if (scp->sc_score) {
|
||||||
|
if (sc2 == scp)
|
||||||
|
md_raw_standout();
|
||||||
|
printf("%2d %5d %s: %s on level %d", (int) (scp - top_ten + 1),
|
||||||
|
scp->sc_score, scp->sc_name, reason[scp->sc_flags],
|
||||||
|
scp->sc_level);
|
||||||
|
if (scp->sc_flags == 0 || scp->sc_flags == 3)
|
||||||
|
printf(" by %s", killname(scp->sc_monster, TRUE));
|
||||||
|
#ifdef MASTER
|
||||||
|
if (prflags == 1)
|
||||||
|
{
|
||||||
|
printf(" (%s)", md_getrealname(scp->sc_uid));
|
||||||
|
}
|
||||||
|
else if (prflags == 2)
|
||||||
|
{
|
||||||
|
fflush(stdout);
|
||||||
|
(void) fgets(prbuf,10,stdin);
|
||||||
|
if (prbuf[0] == 'd')
|
||||||
|
{
|
||||||
|
for (sc2 = scp; sc2 < endp - 1; sc2++)
|
||||||
|
*sc2 = *(sc2 + 1);
|
||||||
|
sc2 = endp - 1;
|
||||||
|
sc2->sc_score = 0;
|
||||||
|
for (i = 0; i < MAXSTR; i++)
|
||||||
|
sc2->sc_name[i] = (char) rnd(255);
|
||||||
|
sc2->sc_flags = RN;
|
||||||
|
sc2->sc_level = RN;
|
||||||
|
sc2->sc_monster = RN;
|
||||||
|
scp--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif /* MASTER */
|
||||||
|
printf(".");
|
||||||
|
if (sc2 == scp)
|
||||||
|
md_raw_standend();
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Update the list file
|
||||||
|
*/
|
||||||
|
if (sc2 != NULL)
|
||||||
|
{
|
||||||
|
if (lock_sc())
|
||||||
|
{
|
||||||
|
fp = signal(SIGINT, SIG_IGN);
|
||||||
|
wr_score(top_ten);
|
||||||
|
unlock_sc();
|
||||||
|
signal(SIGINT, fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* death:
|
||||||
|
* Do something really fun when he dies
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
death(int monst)
|
||||||
|
{
|
||||||
|
char **dp;
|
||||||
|
const char *killer;
|
||||||
|
struct tm *lt;
|
||||||
|
time_t date;
|
||||||
|
|
||||||
|
signal(SIGINT, SIG_IGN);
|
||||||
|
purse -= purse / 10;
|
||||||
|
signal(SIGINT, leave);
|
||||||
|
clear();
|
||||||
|
killer = killname(monst, FALSE);
|
||||||
|
if (!tombstone)
|
||||||
|
{
|
||||||
|
mvprintw(LINES - 2, 0, "Killed by ");
|
||||||
|
killer = killname(monst, FALSE);
|
||||||
|
if (monst != 's' && monst != 'h')
|
||||||
|
printw("a%s ", vowelstr(killer));
|
||||||
|
printw("%s with %d gold", killer, purse);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
time(&date);
|
||||||
|
lt = localtime(&date);
|
||||||
|
move(8, 0);
|
||||||
|
dp = rip;
|
||||||
|
while (*dp)
|
||||||
|
addstr(*dp++);
|
||||||
|
mvaddstr(17, center(killer), killer);
|
||||||
|
if (monst == 's' || monst == 'h')
|
||||||
|
mvaddch(16, 32, ' ');
|
||||||
|
else
|
||||||
|
mvaddstr(16, 33, vowelstr(killer));
|
||||||
|
mvaddstr(14, center(whoami), whoami);
|
||||||
|
sprintf(prbuf, "%d Au", purse);
|
||||||
|
move(15, center(prbuf));
|
||||||
|
addstr(prbuf);
|
||||||
|
sprintf(prbuf, "%4d", 1900+lt->tm_year);
|
||||||
|
mvaddstr(18, 26, prbuf);
|
||||||
|
}
|
||||||
|
move(LINES - 1, 0);
|
||||||
|
refresh();
|
||||||
|
score(purse, amulet ? 3 : 0, monst);
|
||||||
|
my_exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* center:
|
||||||
|
* Return the index to center the given string
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
center(const char *str)
|
||||||
|
{
|
||||||
|
return 28 - (((int)strlen(str) + 1) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* total_winner:
|
||||||
|
* Code for a winner
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
total_winner(void)
|
||||||
|
{
|
||||||
|
THING *obj;
|
||||||
|
struct obj_info *op;
|
||||||
|
int worth = 0;
|
||||||
|
int oldpurse;
|
||||||
|
|
||||||
|
clear();
|
||||||
|
standout();
|
||||||
|
addstr(" \n");
|
||||||
|
addstr(" @ @ @ @ @ @@@ @ @ \n");
|
||||||
|
addstr(" @ @ @@ @@ @ @ @ @ \n");
|
||||||
|
addstr(" @ @ @@@ @ @ @ @ @ @@@ @@@@ @@@ @ @@@ @ \n");
|
||||||
|
addstr(" @@@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ \n");
|
||||||
|
addstr(" @ @ @ @ @ @ @ @@@@ @ @ @@@@@ @ @ @ \n");
|
||||||
|
addstr(" @ @ @ @ @ @@ @ @ @ @ @ @ @ @ @ @ \n");
|
||||||
|
addstr(" @@@ @@@ @@ @ @ @ @@@@ @@@@ @@@ @@@ @@ @ \n");
|
||||||
|
addstr(" \n");
|
||||||
|
addstr(" Congratulations, you have made it to the light of day! \n");
|
||||||
|
standend();
|
||||||
|
addstr("\nYou have joined the elite ranks of those who have escaped the\n");
|
||||||
|
addstr("Dungeons of Doom alive. You journey home and sell all your loot at\n");
|
||||||
|
addstr("a great profit and are admitted to the Fighters' Guild.\n");
|
||||||
|
mvaddstr(LINES - 1, 0, "--Press space to continue--");
|
||||||
|
refresh();
|
||||||
|
wait_for(stdscr, ' ');
|
||||||
|
clear();
|
||||||
|
mvaddstr(0, 0, " Worth Item\n");
|
||||||
|
oldpurse = purse;
|
||||||
|
for (obj = pack; obj != NULL; obj = next(obj))
|
||||||
|
{
|
||||||
|
switch (obj->o_type)
|
||||||
|
{
|
||||||
|
case FOOD:
|
||||||
|
worth = 2 * obj->o_count;
|
||||||
|
when WEAPON:
|
||||||
|
worth = weap_info[obj->o_which].oi_worth;
|
||||||
|
worth *= 3 * (obj->o_hplus + obj->o_dplus) + obj->o_count;
|
||||||
|
obj->o_flags |= ISKNOW;
|
||||||
|
when ARMOR:
|
||||||
|
worth = arm_info[obj->o_which].oi_worth;
|
||||||
|
worth += (9 - obj->o_arm) * 100;
|
||||||
|
worth += (10 * (a_class[obj->o_which] - obj->o_arm));
|
||||||
|
obj->o_flags |= ISKNOW;
|
||||||
|
when SCROLL:
|
||||||
|
worth = scr_info[obj->o_which].oi_worth;
|
||||||
|
worth *= obj->o_count;
|
||||||
|
op = &scr_info[obj->o_which];
|
||||||
|
if (!op->oi_know)
|
||||||
|
worth /= 2;
|
||||||
|
op->oi_know = TRUE;
|
||||||
|
when POTION:
|
||||||
|
worth = pot_info[obj->o_which].oi_worth;
|
||||||
|
worth *= obj->o_count;
|
||||||
|
op = &pot_info[obj->o_which];
|
||||||
|
if (!op->oi_know)
|
||||||
|
worth /= 2;
|
||||||
|
op->oi_know = TRUE;
|
||||||
|
when RING:
|
||||||
|
op = &ring_info[obj->o_which];
|
||||||
|
worth = op->oi_worth;
|
||||||
|
if (obj->o_which == R_ADDSTR || obj->o_which == R_ADDDAM ||
|
||||||
|
obj->o_which == R_PROTECT || obj->o_which == R_ADDHIT)
|
||||||
|
{
|
||||||
|
if (obj->o_arm > 0)
|
||||||
|
worth += obj->o_arm * 100;
|
||||||
|
else
|
||||||
|
worth = 10;
|
||||||
|
}
|
||||||
|
if (!(obj->o_flags & ISKNOW))
|
||||||
|
worth /= 2;
|
||||||
|
obj->o_flags |= ISKNOW;
|
||||||
|
op->oi_know = TRUE;
|
||||||
|
when STICK:
|
||||||
|
op = &ws_info[obj->o_which];
|
||||||
|
worth = op->oi_worth;
|
||||||
|
worth += 20 * obj->o_charges;
|
||||||
|
if (!(obj->o_flags & ISKNOW))
|
||||||
|
worth /= 2;
|
||||||
|
obj->o_flags |= ISKNOW;
|
||||||
|
op->oi_know = TRUE;
|
||||||
|
when AMULET:
|
||||||
|
worth = 1000;
|
||||||
|
}
|
||||||
|
if (worth < 0)
|
||||||
|
worth = 0;
|
||||||
|
printw("%c) %5d %s\n", obj->o_packch, worth, inv_name(obj, FALSE));
|
||||||
|
purse += worth;
|
||||||
|
}
|
||||||
|
printw(" %5d Gold Pieces ", oldpurse);
|
||||||
|
refresh();
|
||||||
|
score(purse, 2, ' ');
|
||||||
|
my_exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* killname:
|
||||||
|
* Convert a code to a monster name
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
killname(int monst, int doart)
|
||||||
|
{
|
||||||
|
struct h_list *hp;
|
||||||
|
const char *sp;
|
||||||
|
int article;
|
||||||
|
struct h_list nlist[] = {
|
||||||
|
{'a', "arrow", TRUE},
|
||||||
|
{'b', "bolt", TRUE},
|
||||||
|
{'d', "dart", TRUE},
|
||||||
|
{'h', "hypothermia", FALSE},
|
||||||
|
{'s', "starvation", FALSE},
|
||||||
|
{'\0'}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isupper(monst))
|
||||||
|
{
|
||||||
|
sp = monsters[monst-'A'].m_name;
|
||||||
|
article = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sp = "Wally the Wonder Badger";
|
||||||
|
article = FALSE;
|
||||||
|
for (hp = nlist; hp->h_ch; hp++)
|
||||||
|
if (hp->h_ch == monst)
|
||||||
|
{
|
||||||
|
sp = hp->h_desc;
|
||||||
|
article = hp->h_print;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (doart && article)
|
||||||
|
sprintf(prbuf, "a%s ", vowelstr(sp));
|
||||||
|
else
|
||||||
|
prbuf[0] = '\0';
|
||||||
|
strcat(prbuf, sp);
|
||||||
|
return prbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* death_monst:
|
||||||
|
* Return a monster appropriate for a random death.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
death_monst(void)
|
||||||
|
{
|
||||||
|
int poss[] =
|
||||||
|
{
|
||||||
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
|
||||||
|
'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||||
|
'Y', 'Z', 'a', 'b', 'h', 'd', 's',
|
||||||
|
' ' /* This is provided to generate the "Wally the Wonder Badger"
|
||||||
|
message for killer */
|
||||||
|
};
|
||||||
|
|
||||||
|
return poss[rnd(sizeof poss / sizeof (int))];
|
||||||
|
}
|
||||||
96
rogue5/rogue.6.in
Normal file
96
rogue5/rogue.6.in
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
.\"
|
||||||
|
.\" @(#)rogue.6 6.2 (Berkeley) 5/6/86
|
||||||
|
.\"
|
||||||
|
.\" Rogue: Exploring the Dungeons of Doom
|
||||||
|
.\" Copyright (C) 1980-1983, 1985, 1986 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
.\" All rights reserved.
|
||||||
|
.\"
|
||||||
|
.\" See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
.\"
|
||||||
|
.TH ROGUE 6 "May 6, 1986"
|
||||||
|
.UC 4
|
||||||
|
.SH NAME
|
||||||
|
rogue \- Exploring The Dungeons of Doom
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.B @PROGRAM@
|
||||||
|
[
|
||||||
|
.B \-r
|
||||||
|
]
|
||||||
|
[
|
||||||
|
.I save_file
|
||||||
|
]
|
||||||
|
[
|
||||||
|
.B \-s
|
||||||
|
]
|
||||||
|
[
|
||||||
|
.B \-d
|
||||||
|
]
|
||||||
|
.SH DESCRIPTION
|
||||||
|
.PP
|
||||||
|
.I Rogue
|
||||||
|
is a computer fantasy game with a new twist. It is crt oriented and the
|
||||||
|
object of the game is to survive the attacks of various monsters and get
|
||||||
|
a lot of gold, rather than the puzzle solving orientation of most computer
|
||||||
|
fantasy games.
|
||||||
|
.PP
|
||||||
|
To get started you really only need to know two commands. The command
|
||||||
|
.B ?
|
||||||
|
will give you a list of the available commands and the command
|
||||||
|
.B /
|
||||||
|
will identify the things you see on the screen.
|
||||||
|
.PP
|
||||||
|
To win the game (as opposed to merely playing to beat other people's high
|
||||||
|
scores) you must locate the Amulet of Yendor which is somewhere below
|
||||||
|
the 20th level of the dungeon and get it out. Nobody has achieved this
|
||||||
|
yet and if somebody does, they will probably go down in history as a hero
|
||||||
|
among heroes.
|
||||||
|
.PP
|
||||||
|
When the game ends, either by your death, when you quit, or if you (by
|
||||||
|
some miracle) manage to win,
|
||||||
|
.I rogue
|
||||||
|
will give you a list of the top-ten scorers. The scoring is based entirely
|
||||||
|
upon how much gold you get. There is a 10% penalty for getting yourself
|
||||||
|
killed.
|
||||||
|
.PP
|
||||||
|
If
|
||||||
|
.I save_file
|
||||||
|
is specified,
|
||||||
|
rogue will be restored from the specified saved game file.
|
||||||
|
If the
|
||||||
|
.B \-r
|
||||||
|
option is used, the save game file is presumed to be the default.
|
||||||
|
.PP
|
||||||
|
The
|
||||||
|
.B \-s
|
||||||
|
option will print out the list of scores.
|
||||||
|
.PP
|
||||||
|
The
|
||||||
|
.B \-d
|
||||||
|
option will kill you and try to add you to the score file.
|
||||||
|
.PP
|
||||||
|
For more detailed directions, read the document
|
||||||
|
.I "A Guide to the Dungeons of Doom."
|
||||||
|
.SH AUTHORS
|
||||||
|
Michael C. Toy,
|
||||||
|
Kenneth C. R. C. Arnold,
|
||||||
|
Glenn Wichman
|
||||||
|
.SH FILES
|
||||||
|
.DT
|
||||||
|
.ta \w'@SCOREFILE@\ \ \ 'u
|
||||||
|
@SCOREFILE@ Score file
|
||||||
|
.br
|
||||||
|
\fB~\fP/rogue.save Default save file
|
||||||
|
.SH SEE ALSO
|
||||||
|
Michael C. Toy
|
||||||
|
and
|
||||||
|
Kenneth C. R. C. Arnold,
|
||||||
|
.I "A guide to the Dungeons of Doom"
|
||||||
|
.SH BUGS
|
||||||
|
.PP
|
||||||
|
Probably infinite
|
||||||
|
(although countably infinite).
|
||||||
|
However,
|
||||||
|
that Ice Monsters sometimes transfix you permanently is
|
||||||
|
.I not
|
||||||
|
a bug.
|
||||||
|
It's a feature.
|
||||||
61
rogue5/rogue.cat.in
Normal file
61
rogue5/rogue.cat.in
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
ROGUE(6) ROGUE(6)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
NAME
|
||||||
|
rogue - Exploring The Dungeons of Doom
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
@PROGRAM@ [ -r ] [ save_file ] [ -s ] [ -d ]
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Rogue is a computer fantasy game with a new twist. It is crt oriented
|
||||||
|
and the object of the game is to survive the attacks of various mon-
|
||||||
|
sters and get a lot of gold, rather than the puzzle solving orientation
|
||||||
|
of most computer fantasy games.
|
||||||
|
|
||||||
|
To get started you really only need to know two commands. The command
|
||||||
|
? will give you a list of the available commands and the command /
|
||||||
|
will identify the things you see on the screen.
|
||||||
|
|
||||||
|
To win the game (as opposed to merely playing to beat other people's
|
||||||
|
high scores) you must locate the Amulet of Yendor which is somewhere
|
||||||
|
below the 20th level of the dungeon and get it out. Nobody has
|
||||||
|
achieved this yet and if somebody does, they will probably go down in
|
||||||
|
history as a hero among heroes.
|
||||||
|
|
||||||
|
When the game ends, either by your death, when you quit, or if you (by
|
||||||
|
some miracle) manage to win, rogue will give you a list of the top-ten
|
||||||
|
scorers. The scoring is based entirely upon how much gold you get.
|
||||||
|
There is a 10% penalty for getting yourself killed.
|
||||||
|
|
||||||
|
If save_file is specified, rogue will be restored from the specified
|
||||||
|
saved game file. If the -r option is used, the save game file is pre-
|
||||||
|
sumed to be the default.
|
||||||
|
|
||||||
|
The -s option will print out the list of scores.
|
||||||
|
|
||||||
|
The -d option will kill you and try to add you to the score file.
|
||||||
|
|
||||||
|
For more detailed directions, read the document A Guide to the Dungeons
|
||||||
|
of Doom.
|
||||||
|
|
||||||
|
AUTHORS
|
||||||
|
Michael C. Toy, Kenneth C. R. C. Arnold, Glenn Wichman
|
||||||
|
|
||||||
|
FILES
|
||||||
|
@SCOREFILE@ Score file
|
||||||
|
~/rogue.save Default save file
|
||||||
|
|
||||||
|
SEE ALSO
|
||||||
|
Michael C. Toy and Kenneth C. R. C. Arnold, A guide to the Dungeons of
|
||||||
|
Doom
|
||||||
|
|
||||||
|
BUGS
|
||||||
|
Probably infinite (although countably infinite). However, that Ice
|
||||||
|
Monsters sometimes transfix you permanently is not a bug. It's a fea-
|
||||||
|
ture.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
4th Berkeley Distribution May 6, 1986 ROGUE(6)
|
||||||
11
rogue5/rogue.desktop
Normal file
11
rogue5/rogue.desktop
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Encoding=UTF-8
|
||||||
|
Name=Rogue
|
||||||
|
GenericName=Rogue
|
||||||
|
Comment=The original curses-based adventure game
|
||||||
|
Exec=rogue
|
||||||
|
Icon=rogue.png
|
||||||
|
Terminal=true
|
||||||
|
Type=Application
|
||||||
|
Categories=Game;RolePlaying;
|
||||||
|
Version=1.0
|
||||||
858
rogue5/rogue.doc.in
Normal file
858
rogue5/rogue.doc.in
Normal file
|
|
@ -0,0 +1,858 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
A Guide to the Dungeons of Doom
|
||||||
|
|
||||||
|
|
||||||
|
Michael C. Toy
|
||||||
|
Kenneth C. R. C. Arnold
|
||||||
|
|
||||||
|
|
||||||
|
Computer Systems Research Group
|
||||||
|
Department of Electrical Engineering and Computer Science
|
||||||
|
University of California
|
||||||
|
Berkeley, California 94720
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ABSTRACT
|
||||||
|
|
||||||
|
Rogue is a visual CRT based fantasy game which runs
|
||||||
|
under the UNIX timesharing system. This paper de-
|
||||||
|
scribes how to play rogue, and gives a few hints for
|
||||||
|
those who might otherwise get lost in the Dungeons
|
||||||
|
of Doom.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
1. Introduction
|
||||||
|
|
||||||
|
You have just finished your years as a student at the
|
||||||
|
local fighter's guild. After much practice and sweat you
|
||||||
|
have finally completed your training and are ready to embark
|
||||||
|
upon a perilous adventure. As a test of your skills, the
|
||||||
|
local guildmasters have sent you into the Dungeons of Doom.
|
||||||
|
Your task is to return with the Amulet of Yendor. Your
|
||||||
|
reward for the completion of this task will be a full mem-
|
||||||
|
bership in the local guild. In addition, you are allowed to
|
||||||
|
keep all the loot you bring back from the dungeons.
|
||||||
|
|
||||||
|
In preparation for your journey, you are given an
|
||||||
|
enchanted mace, a bow, and a quiver of arrows taken from a
|
||||||
|
dragon's hoard in the far off Dark Mountains. You are also
|
||||||
|
outfitted with elf-crafted armor and given enough food to
|
||||||
|
reach the dungeons. You say goodbye to family and friends
|
||||||
|
for what may be the last time and head up the road.
|
||||||
|
|
||||||
|
You set out on your way to the dungeons and after sev-
|
||||||
|
eral days of uneventful travel, you see the ancient ruins
|
||||||
|
that mark the entrance to the Dungeons of Doom. It is late
|
||||||
|
at night, so you make camp at the entrance and spend the
|
||||||
|
____________________
|
||||||
|
UNIX is a trademark of Bell Laboratories
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
USD:33-2 A Guide to the Dungeons of Doom
|
||||||
|
|
||||||
|
|
||||||
|
night sleeping under the open skies. In the morning you
|
||||||
|
gather your weapons, put on your armor, eat what is almost
|
||||||
|
your last food, and enter the dungeons.
|
||||||
|
|
||||||
|
2. What is going on here?
|
||||||
|
|
||||||
|
You have just begun a game of rogue. Your goal is to
|
||||||
|
grab as much treasure as you can, find the Amulet of Yendor,
|
||||||
|
and get out of the Dungeons of Doom alive. On the screen, a
|
||||||
|
map of where you have been and what you have seen on the
|
||||||
|
current dungeon level is kept. As you explore more of the
|
||||||
|
level, it appears on the screen in front of you.
|
||||||
|
|
||||||
|
Rogue differs from most computer fantasy games in that
|
||||||
|
it is screen oriented. Commands are all one or two
|
||||||
|
keystrokes1 and the results of your commands are displayed
|
||||||
|
graphically on the screen rather than being explained in
|
||||||
|
words.2
|
||||||
|
|
||||||
|
Another major difference between rogue and other com-
|
||||||
|
puter fantasy games is that once you have solved all the
|
||||||
|
puzzles in a standard fantasy game, it has lost most of its
|
||||||
|
excitement and it ceases to be fun. Rogue, on the other
|
||||||
|
hand, generates a new dungeon every time you play it and
|
||||||
|
even the author finds it an entertaining and exciting game.
|
||||||
|
|
||||||
|
3. What do all those things on the screen mean?
|
||||||
|
|
||||||
|
In order to understand what is going on in rogue you
|
||||||
|
have to first get some grasp of what rogue is doing with the
|
||||||
|
screen. The rogue screen is intended to replace the "You
|
||||||
|
can see ..." descriptions of standard fantasy games. Figure
|
||||||
|
1 is a sample of what a rogue screen might look like.
|
||||||
|
|
||||||
|
3.1. The bottom line
|
||||||
|
|
||||||
|
At the bottom line of the screen are a few pieces of
|
||||||
|
cryptic information describing your current status. Here is
|
||||||
|
an explanation of what these things mean:
|
||||||
|
|
||||||
|
Level This number indicates how deep you have gone in the
|
||||||
|
dungeon. It starts at one and goes up as you go
|
||||||
|
deeper into the dungeon.
|
||||||
|
|
||||||
|
Gold The number of gold pieces you have managed to find
|
||||||
|
and keep with you so far.
|
||||||
|
____________________
|
||||||
|
1 As opposed to pseudo English sentences.
|
||||||
|
2 A minimum screen size of 24 lines by 80 columns is re-
|
||||||
|
quired. If the screen is larger, only the 24x80 section
|
||||||
|
will be used for the map.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
A Guide to the Dungeons of Doom USD:33-3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
____________________________________________________________
|
||||||
|
|
||||||
|
|
||||||
|
------------
|
||||||
|
|..........+
|
||||||
|
|..@....]..|
|
||||||
|
|....B.....|
|
||||||
|
|..........|
|
||||||
|
-----+------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Level: 1 Gold: 0 Hp: 12(12) Str: 16(16) Arm: 4 Exp: 1/0
|
||||||
|
|
||||||
|
Figure 1
|
||||||
|
____________________________________________________________
|
||||||
|
|
||||||
|
|
||||||
|
Hp Your current and maximum health points. Health
|
||||||
|
points indicate how much damage you can take before
|
||||||
|
you die. The more you get hit in a fight, the lower
|
||||||
|
they get. You can regain health points by resting.
|
||||||
|
The number in parentheses is the maximum number your
|
||||||
|
health points can reach.
|
||||||
|
|
||||||
|
Str Your current strength and maximum ever strength.
|
||||||
|
This can be any integer less than or equal to 31, or
|
||||||
|
greater than or equal to three. The higher the num-
|
||||||
|
ber, the stronger you are. The number in the paren-
|
||||||
|
theses is the maximum strength you have attained so
|
||||||
|
far this game.
|
||||||
|
|
||||||
|
Arm Your current armor protection. This number indicates
|
||||||
|
how effective your armor is in stopping blows from
|
||||||
|
unfriendly creatures. The higher this number is, the
|
||||||
|
more effective the armor.
|
||||||
|
|
||||||
|
Exp These two numbers give your current experience level
|
||||||
|
and experience points. As you do things, you gain
|
||||||
|
experience points. At certain experience point
|
||||||
|
totals, you gain an experience level. The more expe-
|
||||||
|
rienced you are, the better you are able to fight and
|
||||||
|
to withstand magical attacks.
|
||||||
|
|
||||||
|
3.2. The top line
|
||||||
|
|
||||||
|
The top line of the screen is reserved for printing
|
||||||
|
messages that describe things that are impossible to repre-
|
||||||
|
sent visually. If you see a "--More--" on the top line,
|
||||||
|
this means that rogue wants to print another message on the
|
||||||
|
screen, but it wants to make certain that you have read the
|
||||||
|
one that is there first. To read the next message, just
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
USD:33-4 A Guide to the Dungeons of Doom
|
||||||
|
|
||||||
|
|
||||||
|
type a space.
|
||||||
|
|
||||||
|
3.3. The rest of the screen
|
||||||
|
|
||||||
|
The rest of the screen is the map of the level as you
|
||||||
|
have explored it so far. Each symbol on the screen repre-
|
||||||
|
sents something. Here is a list of what the various symbols
|
||||||
|
mean:
|
||||||
|
|
||||||
|
@ This symbol represents you, the adventurer.
|
||||||
|
|
||||||
|
-| These symbols represent the walls of rooms.
|
||||||
|
|
||||||
|
+ A door to/from a room.
|
||||||
|
|
||||||
|
. The floor of a room.
|
||||||
|
|
||||||
|
# The floor of a passage between rooms.
|
||||||
|
|
||||||
|
* A pile or pot of gold.
|
||||||
|
|
||||||
|
) A weapon of some sort.
|
||||||
|
|
||||||
|
] A piece of armor.
|
||||||
|
|
||||||
|
! A flask containing a magic potion.
|
||||||
|
|
||||||
|
? A piece of paper, usually a magic scroll.
|
||||||
|
|
||||||
|
= A ring with magic properties
|
||||||
|
|
||||||
|
/ A magical staff or wand
|
||||||
|
|
||||||
|
^ A trap, watch out for these.
|
||||||
|
|
||||||
|
% A staircase to other levels
|
||||||
|
|
||||||
|
: A piece of food.
|
||||||
|
|
||||||
|
A-Z The uppercase letters represent the various inhabitants
|
||||||
|
of the Dungeons of Doom. Watch out, they can be nasty
|
||||||
|
and vicious.
|
||||||
|
|
||||||
|
4. Commands
|
||||||
|
|
||||||
|
Commands are given to rogue by typing one or two char-
|
||||||
|
acters. Most commands can be preceded by a count to repeat
|
||||||
|
them (e.g. typing "10s" will do ten searches). Commands for
|
||||||
|
which counts make no sense have the count ignored. To can-
|
||||||
|
cel a count or a prefix, type <ESCAPE>. The list of com-
|
||||||
|
mands is rather long, but it can be read at any time during
|
||||||
|
the game with the "?" command. Here it is for reference,
|
||||||
|
with a short explanation of each command.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
A Guide to the Dungeons of Doom USD:33-5
|
||||||
|
|
||||||
|
|
||||||
|
? The help command. Asks for a character to give help
|
||||||
|
on. If you type a "*", it will list all the commands,
|
||||||
|
otherwise it will explain what the character you typed
|
||||||
|
does.
|
||||||
|
|
||||||
|
/ This is the "What is that on the screen?" command. A
|
||||||
|
"/" followed by any character that you see on the
|
||||||
|
level, will tell you what that character is. For
|
||||||
|
instance, typing "/@" will tell you that the "@" symbol
|
||||||
|
represents you, the player.
|
||||||
|
|
||||||
|
h, H, ^H
|
||||||
|
Move left. You move one space to the left. If you use
|
||||||
|
upper case "h", you will continue to move left until
|
||||||
|
you run into something. This works for all movement
|
||||||
|
commands (e.g. "L" means run in direction "l") If you
|
||||||
|
use the "control" "h", you will continue moving in the
|
||||||
|
specified direction until you pass something interest-
|
||||||
|
ing or run into a wall. You should experiment with
|
||||||
|
this, since it is a very useful command, but very dif-
|
||||||
|
ficult to describe. This also works for all movement
|
||||||
|
commands.
|
||||||
|
|
||||||
|
j Move down.
|
||||||
|
|
||||||
|
k Move up.
|
||||||
|
|
||||||
|
l Move right.
|
||||||
|
|
||||||
|
y Move diagonally up and left.
|
||||||
|
|
||||||
|
u Move diagonally up and right.
|
||||||
|
|
||||||
|
b Move diagonally down and left.
|
||||||
|
|
||||||
|
n Move diagonally down and right.
|
||||||
|
|
||||||
|
t Throw an object. This is a prefix command. When fol-
|
||||||
|
lowed with a direction it throws an object in the spec-
|
||||||
|
ified direction. (e.g. type "th" to throw something to
|
||||||
|
the left.)
|
||||||
|
|
||||||
|
f Fight until someone dies. When followed with a direc-
|
||||||
|
tion this will force you to fight the creature in that
|
||||||
|
direction until either you or it bites the big one.
|
||||||
|
|
||||||
|
m Move onto something without picking it up. This will
|
||||||
|
move you one space in the direction you specify and, if
|
||||||
|
there is an object there you can pick up, it won't do
|
||||||
|
it.
|
||||||
|
|
||||||
|
z Zap prefix. Point a staff or wand in a given direction
|
||||||
|
and fire it. Even non-directional staves must be
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
USD:33-6 A Guide to the Dungeons of Doom
|
||||||
|
|
||||||
|
|
||||||
|
pointed in some direction to be used.
|
||||||
|
|
||||||
|
^ Identify trap command. If a trap is on your map and
|
||||||
|
you can't remember what type it is, you can get rogue
|
||||||
|
to remind you by getting next to it and typing "^" fol-
|
||||||
|
lowed by the direction that would move you on top of
|
||||||
|
it.
|
||||||
|
|
||||||
|
s Search for traps and secret doors. Examine each space
|
||||||
|
immediately adjacent to you for the existence of a trap
|
||||||
|
or secret door. There is a large chance that even if
|
||||||
|
there is something there, you won't find it, so you
|
||||||
|
might have to search a while before you find something.
|
||||||
|
|
||||||
|
> Climb down a staircase to the next level. Not surpris-
|
||||||
|
ingly, this can only be done if you are standing on
|
||||||
|
staircase.
|
||||||
|
|
||||||
|
< Climb up a staircase to the level above. This can't be
|
||||||
|
done without the Amulet of Yendor in your possession.
|
||||||
|
|
||||||
|
. Rest. This is the "do nothing" command. This is good
|
||||||
|
for waiting and healing.
|
||||||
|
|
||||||
|
, Pick up something. This picks up whatever you are cur-
|
||||||
|
rently standing on, if you are standing on anything at
|
||||||
|
all.
|
||||||
|
|
||||||
|
i Inventory. List what you are carrying in your pack.
|
||||||
|
|
||||||
|
I Selective inventory. Tells you what a single item in
|
||||||
|
your pack is.
|
||||||
|
|
||||||
|
q Quaff one of the potions you are carrying.
|
||||||
|
|
||||||
|
r Read one of the scrolls in your pack.
|
||||||
|
|
||||||
|
e Eat food from your pack.
|
||||||
|
|
||||||
|
w Wield a weapon. Take a weapon out of your pack and
|
||||||
|
carry it for use in combat, replacing the one you are
|
||||||
|
currently using (if any).
|
||||||
|
|
||||||
|
W Wear armor. You can only wear one suit of armor at a
|
||||||
|
time. This takes extra time.
|
||||||
|
|
||||||
|
T Take armor off. You can't remove armor that is cursed.
|
||||||
|
This takes extra time.
|
||||||
|
|
||||||
|
P Put on a ring. You can wear only two rings at a time
|
||||||
|
(one on each hand). If you aren't wearing any rings,
|
||||||
|
this command will ask you which hand you want to wear
|
||||||
|
it on, otherwise, it will place it on the unused hand.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
A Guide to the Dungeons of Doom USD:33-7
|
||||||
|
|
||||||
|
|
||||||
|
The program assumes that you wield your sword in your
|
||||||
|
right hand.
|
||||||
|
|
||||||
|
R Remove a ring. If you are only wearing one ring, this
|
||||||
|
command takes it off. If you are wearing two, it will
|
||||||
|
ask you which one you wish to remove,
|
||||||
|
|
||||||
|
d Drop an object. Take something out of your pack and
|
||||||
|
leave it lying on the floor. Only one object can
|
||||||
|
occupy each space. You cannot drop a cursed object at
|
||||||
|
all if you are wielding or wearing it.
|
||||||
|
|
||||||
|
c Call an object something. If you have a type of object
|
||||||
|
in your pack which you wish to remember something
|
||||||
|
about, you can use the call command to give a name to
|
||||||
|
that type of object. This is usually used when you
|
||||||
|
figure out what a potion, scroll, ring, or staff is
|
||||||
|
after you pick it up, or when you want to remember
|
||||||
|
which of those swords in your pack you were wielding.
|
||||||
|
|
||||||
|
D Print out which things you've discovered something
|
||||||
|
about. This command will ask you what type of thing
|
||||||
|
you are interested in. If you type the character for a
|
||||||
|
given type of object (e.g. "!" for potion) it will
|
||||||
|
tell you which kinds of that type of object you've dis-
|
||||||
|
covered (i.e., figured out what they are). This com-
|
||||||
|
mand works for potions, scrolls, rings, and staves and
|
||||||
|
wands.
|
||||||
|
|
||||||
|
o Examine and set options. This command is further
|
||||||
|
explained in the section on options.
|
||||||
|
|
||||||
|
^R Redraws the screen. Useful if spurious messages or
|
||||||
|
transmission errors have messed up the display.
|
||||||
|
|
||||||
|
^P Print last message. Useful when a message disappears
|
||||||
|
before you can read it. This only repeats the last
|
||||||
|
message that was not a mistyped command so that you
|
||||||
|
don't loose anything by accidentally typing the wrong
|
||||||
|
character instead of ^P.
|
||||||
|
|
||||||
|
<ESCAPE>
|
||||||
|
Cancel a command, prefix, or count.
|
||||||
|
|
||||||
|
! Escape to a shell for some commands.
|
||||||
|
|
||||||
|
Q Quit. Leave the game.
|
||||||
|
|
||||||
|
S Save the current game in a file. It will ask you
|
||||||
|
whether you wish to use the default save file. Caveat:
|
||||||
|
Rogue won't let you start up a copy of a saved game,
|
||||||
|
and it removes the save file as soon as you start up a
|
||||||
|
restored game. This is to prevent people from saving a
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
USD:33-8 A Guide to the Dungeons of Doom
|
||||||
|
|
||||||
|
|
||||||
|
game just before a dangerous position and then restart-
|
||||||
|
ing it if they die. To restore a saved game, give the
|
||||||
|
file name as an argument to rogue. As in
|
||||||
|
% rogue save_file
|
||||||
|
|
||||||
|
To restart from the default save file (see below), run
|
||||||
|
% rogue -r
|
||||||
|
|
||||||
|
v Prints the program version number.
|
||||||
|
|
||||||
|
) Print the weapon you are currently wielding
|
||||||
|
|
||||||
|
] Print the armor you are currently wearing
|
||||||
|
|
||||||
|
= Print the rings you are currently wearing
|
||||||
|
|
||||||
|
@ Reprint the status line on the message line
|
||||||
|
|
||||||
|
5. Rooms
|
||||||
|
|
||||||
|
Rooms in the dungeons are either lit or dark. If you
|
||||||
|
walk into a lit room, the entire room will be drawn on the
|
||||||
|
screen as soon as you enter. If you walk into a dark room,
|
||||||
|
it will only be displayed as you explore it. Upon leaving a
|
||||||
|
room, all monsters inside the room are erased from the
|
||||||
|
screen. In the darkness you can only see one space in all
|
||||||
|
directions around you. A corridor is always dark.
|
||||||
|
|
||||||
|
6. Fighting
|
||||||
|
|
||||||
|
If you see a monster and you wish to fight it, just
|
||||||
|
attempt to run into it. Many times a monster you find will
|
||||||
|
mind its own business unless you attack it. It is often the
|
||||||
|
case that discretion is the better part of valor.
|
||||||
|
|
||||||
|
7. Objects you can find
|
||||||
|
|
||||||
|
When you find something in the dungeon, it is common to
|
||||||
|
want to pick the object up. This is accomplished in rogue
|
||||||
|
by walking over the object (unless you use the "m" prefix,
|
||||||
|
see above). If you are carrying too many things, the pro-
|
||||||
|
gram will tell you and it won't pick up the object, other-
|
||||||
|
wise it will add it to your pack and tell you what you just
|
||||||
|
picked up.
|
||||||
|
|
||||||
|
Many of the commands that operate on objects must
|
||||||
|
prompt you to find out which object you want to use. If you
|
||||||
|
change your mind and don't want to do that command after
|
||||||
|
all, just type an <ESCAPE> and the command will be aborted.
|
||||||
|
|
||||||
|
Some objects, like armor and weapons, are easily dif-
|
||||||
|
ferentiated. Others, like scrolls and potions, are given
|
||||||
|
labels which vary according to type. During a game, any two
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
A Guide to the Dungeons of Doom USD:33-9
|
||||||
|
|
||||||
|
|
||||||
|
of the same kind of object with the same label are the same
|
||||||
|
type. However, the labels will vary from game to game.
|
||||||
|
|
||||||
|
When you use one of these labeled objects, if its
|
||||||
|
effect is obvious, rogue will remember what it is for you.
|
||||||
|
If it's effect isn't extremely obvious you will be asked
|
||||||
|
what you want to scribble on it so you will recognize it
|
||||||
|
later, or you can use the "call" command (see above).
|
||||||
|
|
||||||
|
7.1. Weapons
|
||||||
|
|
||||||
|
Some weapons, like arrows, come in bunches, but most
|
||||||
|
come one at a time. In order to use a weapon, you must
|
||||||
|
wield it. To fire an arrow out of a bow, you must first
|
||||||
|
wield the bow, then throw the arrow. You can only wield one
|
||||||
|
weapon at a time, but you can't change weapons if the one
|
||||||
|
you are currently wielding is cursed. The commands to use
|
||||||
|
weapons are "w" (wield) and "t" (throw).
|
||||||
|
|
||||||
|
7.2. Armor
|
||||||
|
|
||||||
|
There are various sorts of armor lying around in the
|
||||||
|
dungeon. Some of it is enchanted, some is cursed, and some
|
||||||
|
is just normal. Different armor types have different armor
|
||||||
|
protection. The higher the armor protection, the more pro-
|
||||||
|
tection the armor affords against the blows of monsters.
|
||||||
|
Here is a list of the various armor types and their normal
|
||||||
|
armor protection:
|
||||||
|
|
||||||
|
|
||||||
|
+-----------------------------------------+
|
||||||
|
| Type Protection |
|
||||||
|
|None 0 |
|
||||||
|
|Leather armor 2 |
|
||||||
|
|Studded leather / Ring mail 3 |
|
||||||
|
|Scale mail 4 |
|
||||||
|
|Chain mail 5 |
|
||||||
|
|Banded mail / Splint mail 6 |
|
||||||
|
|Plate mail 7 |
|
||||||
|
+-----------------------------------------+
|
||||||
|
|
||||||
|
|
||||||
|
If a piece of armor is enchanted, its armor protection will
|
||||||
|
be higher than normal. If a suit of armor is cursed, its
|
||||||
|
armor protection will be lower, and you will not be able to
|
||||||
|
remove it. However, not all armor with a protection that is
|
||||||
|
lower than normal is cursed.
|
||||||
|
|
||||||
|
The commands to use weapons are "W" (wear) and "T"
|
||||||
|
(take off).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
USD:33-10 A Guide to the Dungeons of Doom
|
||||||
|
|
||||||
|
|
||||||
|
7.3. Scrolls
|
||||||
|
|
||||||
|
Scrolls come with titles in an unknown tongue3. After
|
||||||
|
you read a scroll, it disappears from your pack. The com-
|
||||||
|
mand to use a scroll is "r" (read).
|
||||||
|
|
||||||
|
7.4. Potions
|
||||||
|
|
||||||
|
Potions are labeled by the color of the liquid inside
|
||||||
|
the flask. They disappear after being quaffed. The command
|
||||||
|
to use a scroll is "q" (quaff).
|
||||||
|
|
||||||
|
7.5. Staves and Wands
|
||||||
|
|
||||||
|
Staves and wands do the same kinds of things. Staves
|
||||||
|
are identified by a type of wood; wands by a type of metal
|
||||||
|
or bone. They are generally things you want to do to some-
|
||||||
|
thing over a long distance, so you must point them at what
|
||||||
|
you wish to affect to use them. Some staves are not
|
||||||
|
affected by the direction they are pointed, though. Staves
|
||||||
|
come with multiple magic charges, the number being random,
|
||||||
|
and when they are used up, the staff is just a piece of wood
|
||||||
|
or metal.
|
||||||
|
|
||||||
|
The command to use a wand or staff is "z" (zap)
|
||||||
|
|
||||||
|
7.6. Rings
|
||||||
|
|
||||||
|
Rings are very useful items, since they are relatively
|
||||||
|
permanent magic, unlike the usually fleeting effects of
|
||||||
|
potions, scrolls, and staves. Of course, the bad rings are
|
||||||
|
also more powerful. Most rings also cause you to use up
|
||||||
|
food more rapidly, the rate varying with the type of ring.
|
||||||
|
Rings are differentiated by their stone settings. The com-
|
||||||
|
mands to use rings are "P" (put on) and "R" (remove).
|
||||||
|
|
||||||
|
7.7. Food
|
||||||
|
|
||||||
|
Food is necessary to keep you going. If you go too
|
||||||
|
long without eating you will faint, and eventually die of
|
||||||
|
starvation. The command to use food is "e" (eat).
|
||||||
|
|
||||||
|
8. Options
|
||||||
|
|
||||||
|
Due to variations in personal tastes and conceptions of
|
||||||
|
the way rogue should do things, there are a set of options
|
||||||
|
you can set that cause rogue to behave in various different
|
||||||
|
____________________
|
||||||
|
3 Actually, it's a dialect spoken only by the twenty-sev-
|
||||||
|
en members of a tribe in Outer Mongolia, but you're not sup-
|
||||||
|
posed to know that.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
A Guide to the Dungeons of Doom USD:33-11
|
||||||
|
|
||||||
|
|
||||||
|
ways.
|
||||||
|
|
||||||
|
8.1. Setting the options
|
||||||
|
|
||||||
|
There are two ways to set the options. The first is
|
||||||
|
with the "o" command of rogue; the second is with the
|
||||||
|
"ROGUEOPTS" environment variable4.
|
||||||
|
|
||||||
|
8.1.1. Using the `o' command
|
||||||
|
|
||||||
|
When you type "o" in rogue, it clears the screen and
|
||||||
|
displays the current settings for all the options. It then
|
||||||
|
places the cursor by the value of the first option and waits
|
||||||
|
for you to type. You can type a <RETURN> which means to go
|
||||||
|
to the next option, a "-" which means to go to the previous
|
||||||
|
option, an <ESCAPE> which means to return to the game, or
|
||||||
|
you can give the option a value. For boolean options this
|
||||||
|
merely involves typing "t" for true or "f" for false. For
|
||||||
|
string options, type the new value followed by a <RETURN>.
|
||||||
|
|
||||||
|
8.1.2. Using the ROGUEOPTS variable
|
||||||
|
|
||||||
|
The ROGUEOPTS variable is a string containing a comma
|
||||||
|
separated list of initial values for the various options.
|
||||||
|
Boolean variables can be turned on by listing their name or
|
||||||
|
turned off by putting a "no" in front of the name. Thus to
|
||||||
|
set up an environment variable so that jump is on, terse is
|
||||||
|
off, and the name is set to "Blue Meanie", use the command
|
||||||
|
% setenv ROGUEOPTS "jump,noterse,name=Blue Meanie"5
|
||||||
|
|
||||||
|
8.2. Option list
|
||||||
|
|
||||||
|
Here is a list of the options and an explanation of
|
||||||
|
what each one is for. The default value for each is
|
||||||
|
enclosed in square brackets. For character string options,
|
||||||
|
input over fifty characters will be ignored.
|
||||||
|
|
||||||
|
terse [noterse]
|
||||||
|
Useful for those who are tired of the sometimes lengthy
|
||||||
|
messages of rogue. This is a useful option for playing
|
||||||
|
on slow terminals, so this option defaults to terse if
|
||||||
|
you are on a slow (1200 baud or under) terminal.
|
||||||
|
|
||||||
|
|
||||||
|
____________________
|
||||||
|
4 On Version 6 systems, there is no equivalent of the
|
||||||
|
ROGUEOPTS feature.
|
||||||
|
5 For those of you who use the Bourne shell sh (1), the
|
||||||
|
commands would be
|
||||||
|
$ ROGUEOPTS="jump,noterse,name=Blue Meanie"
|
||||||
|
$ export ROGUEOPTS
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
USD:33-12 A Guide to the Dungeons of Doom
|
||||||
|
|
||||||
|
|
||||||
|
jump [nojump]
|
||||||
|
If this option is set, running moves will not be dis-
|
||||||
|
played until you reach the end of the move. This saves
|
||||||
|
considerable cpu and display time. This option
|
||||||
|
defaults to jump if you are using a slow terminal.
|
||||||
|
|
||||||
|
flush [noflush]
|
||||||
|
All typeahead is thrown away after each round of bat-
|
||||||
|
tle. This is useful for those who type far ahead and
|
||||||
|
then watch in dismay as a Bat kills them.
|
||||||
|
|
||||||
|
seefloor [seefloor]
|
||||||
|
Display the floor around you on the screen as you move
|
||||||
|
through dark rooms. Due to the amount of characters
|
||||||
|
generated, this option defaults to noseefloor if you
|
||||||
|
are using a slow terminal.
|
||||||
|
|
||||||
|
passgo [nopassgo]
|
||||||
|
Follow turnings in passageways. If you run in a pas-
|
||||||
|
sage and you run into stone or a wall, rogue will see
|
||||||
|
if it can turn to the right or left. If it can only
|
||||||
|
turn one way, it will turn that way. If it can turn
|
||||||
|
either or neither, it will stop. This algorithm can
|
||||||
|
sometimes lead to slightly confusing occurrences which
|
||||||
|
is why it defaults to nopassgo.
|
||||||
|
|
||||||
|
tombstone [tombstone]
|
||||||
|
Print out the tombstone at the end if you get killed.
|
||||||
|
This is nice but slow, so you can turn it off if you
|
||||||
|
like.
|
||||||
|
|
||||||
|
inven [overwrite]
|
||||||
|
Inventory type. This can have one of three values:
|
||||||
|
overwrite, slow, or clear. With overwrite the top
|
||||||
|
lines of the map are overwritten with the list when
|
||||||
|
inventory is requested or when "Which item do you wish
|
||||||
|
to . . .? " questions are answered with a "*". How-
|
||||||
|
ever, if the list is longer than a screenful, the
|
||||||
|
screen is cleared. With slow, lists are displayed one
|
||||||
|
item at a time on the top of the screen, and with
|
||||||
|
clear, the screen is cleared, the list is displayed,
|
||||||
|
and then the dungeon level is re-displayed. Due to
|
||||||
|
speed considerations, clear is the default for termi-
|
||||||
|
nals without clear-to-end-of-line capabilities.
|
||||||
|
|
||||||
|
name [account name]
|
||||||
|
This is the name of your character. It is used if you
|
||||||
|
get on the top ten scorer's list.
|
||||||
|
|
||||||
|
fruit [slime-mold]
|
||||||
|
This should hold the name of a fruit that you enjoy
|
||||||
|
eating. It is basically a whimsey that rogue uses in a
|
||||||
|
couple of places.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
A Guide to the Dungeons of Doom USD:33-13
|
||||||
|
|
||||||
|
|
||||||
|
file [~/rogue.save]
|
||||||
|
The default file name for saving the game. If your
|
||||||
|
phone is hung up by accident, rogue will automatically
|
||||||
|
save the game in this file. The file name may start
|
||||||
|
with the special character "~" which expands to be your
|
||||||
|
home directory.
|
||||||
|
|
||||||
|
9. Scoring
|
||||||
|
|
||||||
|
Rogue usually maintains a list of the top scoring peo-
|
||||||
|
ple or scores on your machine. Depending on how it is set
|
||||||
|
up, it can post either the top scores or the top players.
|
||||||
|
In the latter case, each account on the machine can post
|
||||||
|
only one non-winning score on this list. If you score
|
||||||
|
higher than someone else on this list, or better your previ-
|
||||||
|
ous score on the list, you will be inserted in the proper
|
||||||
|
place under your current name. How many scores are kept can
|
||||||
|
also be set up by whoever installs it on your machine.
|
||||||
|
|
||||||
|
If you quit the game, you get out with all of your gold
|
||||||
|
intact. If, however, you get killed in the Dungeons of
|
||||||
|
Doom, your body is forwarded to your next-of-kin, along with
|
||||||
|
90% of your gold; ten percent of your gold is kept by the
|
||||||
|
Dungeons' wizard as a fee6. This should make you consider
|
||||||
|
whether you want to take one last hit at that monster and
|
||||||
|
possibly live, or quit and thus stop with whatever you have.
|
||||||
|
If you quit, you do get all your gold, but if you swing and
|
||||||
|
live, you might find more.
|
||||||
|
|
||||||
|
If you just want to see what the current top play-
|
||||||
|
ers/games list is, you can type
|
||||||
|
% @PROGRAM@ -s
|
||||||
|
|
||||||
|
10. Acknowledgements
|
||||||
|
|
||||||
|
Rogue was originally conceived of by Glenn Wichman and
|
||||||
|
Michael Toy. Ken Arnold and Michael Toy then smoothed out
|
||||||
|
the user interface, and added jillions of new features. We
|
||||||
|
would like to thank Bob Arnold, Michelle Busch, Andy
|
||||||
|
Hatcher, Kipp Hickman, Mark Horton, Daniel Jensen, Bill Joy,
|
||||||
|
Joe Kalash, Steve Maurer, Marty McNary, Jan Miller, and
|
||||||
|
Scott Nelson for their ideas and assistance; and also the
|
||||||
|
teeming multitudes who graciously ignored work, school, and
|
||||||
|
social life to play rogue and send us bugs, complaints, sug-
|
||||||
|
gestions, and just plain flames. And also Mom.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
____________________
|
||||||
|
6 The Dungeon's wizard is named Wally the Wonder Badger.
|
||||||
|
Invocations should be accompanied by a sizable donation.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
778
rogue5/rogue.h
Normal file
778
rogue5/rogue.h
Normal file
|
|
@ -0,0 +1,778 @@
|
||||||
|
/*
|
||||||
|
* Rogue definitions and variable declarations
|
||||||
|
*
|
||||||
|
* @(#)rogue.h 5.42 (Berkeley) 08/06/83
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "extern.h"
|
||||||
|
|
||||||
|
#undef lines
|
||||||
|
|
||||||
|
#define NOOP(x) (x += 0)
|
||||||
|
#define CCHAR(x) ( (x) & A_CHARTEXT )
|
||||||
|
|
||||||
|
#define MAXDAEMONS 20
|
||||||
|
#define EMPTY 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Maximum number of different things
|
||||||
|
*/
|
||||||
|
#define MAXROOMS 9
|
||||||
|
#define MAXTHINGS 9
|
||||||
|
#define MAXOBJ 9
|
||||||
|
#define MAXPACK 23
|
||||||
|
#define MAXTRAPS 10
|
||||||
|
#define AMULETLEVEL 26
|
||||||
|
#define NUMTHINGS 7 /* number of types of things */
|
||||||
|
#define MAXPASS 13 /* upper limit on number of passages */
|
||||||
|
#define NUMLINES 24
|
||||||
|
#define NUMCOLS 80
|
||||||
|
#define STATLINE (NUMLINES - 1)
|
||||||
|
#define BORE_LEVEL 50
|
||||||
|
|
||||||
|
/*
|
||||||
|
* return values for get functions
|
||||||
|
*/
|
||||||
|
#define NORM 0 /* normal exit */
|
||||||
|
#define QUIT 1 /* quit option setting */
|
||||||
|
#define MINUS 2 /* back up one option */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* inventory types
|
||||||
|
*/
|
||||||
|
#define INV_OVER 0
|
||||||
|
#define INV_SLOW 1
|
||||||
|
#define INV_CLEAR 2
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All the fun defines
|
||||||
|
*/
|
||||||
|
#define when break;case
|
||||||
|
#define otherwise break;default
|
||||||
|
#define until(expr) while(!(expr))
|
||||||
|
#define next(ptr) (*ptr).l_next
|
||||||
|
#define prev(ptr) (*ptr).l_prev
|
||||||
|
#define winat(y,x) (moat(y,x) != NULL ? moat(y,x)->t_disguise : chat(y,x))
|
||||||
|
#define ce(a,b) ((a).x == (b).x && (a).y == (b).y)
|
||||||
|
#define hero player.t_pos
|
||||||
|
#define pstats player.t_stats
|
||||||
|
#define pack player.t_pack
|
||||||
|
#define proom player.t_room
|
||||||
|
#define max_hp player.t_stats.s_maxhp
|
||||||
|
#define attach(a,b) _attach(&a,b)
|
||||||
|
#define detach(a,b) _detach(&a,b)
|
||||||
|
#define free_list(a) _free_list(&a)
|
||||||
|
#undef max
|
||||||
|
#define max(a,b) ((a) > (b) ? (a) : (b))
|
||||||
|
#define on(thing,flag) ((((thing).t_flags & (flag)) != 0))
|
||||||
|
#define GOLDCALC (rnd(50 + 10 * level) + 2)
|
||||||
|
#define ISRING(h,r) (cur_ring[h] != NULL && cur_ring[h]->o_which == r)
|
||||||
|
#define ISWEARING(r) (ISRING(LEFT, r) || ISRING(RIGHT, r))
|
||||||
|
#define ISMULT(type) (type == POTION || type == SCROLL || type == FOOD)
|
||||||
|
#define INDEX(y,x) (&places[((x) << 5) + (y)])
|
||||||
|
#define chat(y,x) (places[((x) << 5) + (y)].p_ch)
|
||||||
|
#define flat(y,x) (places[((x) << 5) + (y)].p_flags)
|
||||||
|
#define moat(y,x) (places[((x) << 5) + (y)].p_monst)
|
||||||
|
#define unc(cp) (cp).y, (cp).x
|
||||||
|
#ifdef MASTER
|
||||||
|
#define debug if (wizard) msg
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* things that appear on the screens
|
||||||
|
*/
|
||||||
|
#define PASSAGE '#'
|
||||||
|
#define DOOR '+'
|
||||||
|
#define FLOOR '.'
|
||||||
|
#define PLAYER '@'
|
||||||
|
#define TRAP '^'
|
||||||
|
#define STAIRS '%'
|
||||||
|
#define GOLD '*'
|
||||||
|
#define POTION '!'
|
||||||
|
#define SCROLL '?'
|
||||||
|
#define MAGIC '$'
|
||||||
|
#define FOOD ':'
|
||||||
|
#define WEAPON ')'
|
||||||
|
#define ARMOR ']'
|
||||||
|
#define AMULET ','
|
||||||
|
#define RING '='
|
||||||
|
#define STICK '/'
|
||||||
|
#define CALLABLE -1
|
||||||
|
#define R_OR_S -2
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Various constants
|
||||||
|
*/
|
||||||
|
#define BEARTIME spread(3)
|
||||||
|
#define SLEEPTIME spread(5)
|
||||||
|
#define HOLDTIME spread(2)
|
||||||
|
#define WANDERTIME spread(70)
|
||||||
|
#define BEFORE spread(1)
|
||||||
|
#define AFTER spread(2)
|
||||||
|
#define HEALTIME 30
|
||||||
|
#define HUHDURATION 20
|
||||||
|
#define SEEDURATION 850
|
||||||
|
#define HUNGERTIME 1300
|
||||||
|
#define MORETIME 150
|
||||||
|
#define STOMACHSIZE 2000
|
||||||
|
#define STARVETIME 850
|
||||||
|
#define ESCAPE 27
|
||||||
|
#define LEFT 0
|
||||||
|
#define RIGHT 1
|
||||||
|
#define BOLT_LENGTH 6
|
||||||
|
#define LAMPDIST 3
|
||||||
|
#ifdef MASTER
|
||||||
|
#ifndef PASSWD
|
||||||
|
#define PASSWD "mTBellIQOsLNA"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Save against things
|
||||||
|
*/
|
||||||
|
#define VS_POISON 00
|
||||||
|
#define VS_PARALYZATION 00
|
||||||
|
#define VS_DEATH 00
|
||||||
|
#define VS_BREATH 02
|
||||||
|
#define VS_MAGIC 03
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Various flag bits
|
||||||
|
*/
|
||||||
|
/* flags for rooms */
|
||||||
|
#define ISDARK 0000001 /* room is dark */
|
||||||
|
#define ISGONE 0000002 /* room is gone (a corridor) */
|
||||||
|
#define ISMAZE 0000004 /* room is gone (a corridor) */
|
||||||
|
|
||||||
|
/* flags for objects */
|
||||||
|
#define ISCURSED 000001 /* object is cursed */
|
||||||
|
#define ISKNOW 0000002 /* player knows details about the object */
|
||||||
|
#define ISMISL 0000004 /* object is a missile type */
|
||||||
|
#define ISMANY 0000010 /* object comes in groups */
|
||||||
|
/* ISFOUND 0000020 ...is used for both objects and creatures */
|
||||||
|
#define ISPROT 0000040 /* armor is permanently protected */
|
||||||
|
|
||||||
|
/* flags for creatures */
|
||||||
|
#define CANHUH 0000001 /* creature can confuse */
|
||||||
|
#define CANSEE 0000002 /* creature can see invisible creatures */
|
||||||
|
#define ISBLIND 0000004 /* creature is blind */
|
||||||
|
#define ISCANC 0000010 /* creature has special qualities cancelled */
|
||||||
|
#define ISLEVIT 0000010 /* hero is levitating */
|
||||||
|
#define ISFOUND 0000020 /* creature has been seen (used for objects) */
|
||||||
|
#define ISGREED 0000040 /* creature runs to protect gold */
|
||||||
|
#define ISHASTE 0000100 /* creature has been hastened */
|
||||||
|
#define ISTARGET 000200 /* creature is the target of an 'f' command */
|
||||||
|
#define ISHELD 0000400 /* creature has been held */
|
||||||
|
#define ISHUH 0001000 /* creature is confused */
|
||||||
|
#define ISINVIS 0002000 /* creature is invisible */
|
||||||
|
#define ISMEAN 0004000 /* creature can wake when player enters room */
|
||||||
|
#define ISHALU 0004000 /* hero is on acid trip */
|
||||||
|
#define ISREGEN 0010000 /* creature can regenerate */
|
||||||
|
#define ISRUN 0020000 /* creature is running at the player */
|
||||||
|
#define SEEMONST 040000 /* hero can detect unseen monsters */
|
||||||
|
#define ISFLY 0040000 /* creature can fly */
|
||||||
|
#define ISSLOW 0100000 /* creature has been slowed */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flags for level map
|
||||||
|
*/
|
||||||
|
#define F_PASS 0x80 /* is a passageway */
|
||||||
|
#define F_SEEN 0x40 /* have seen this spot before */
|
||||||
|
#define F_DROPPED 0x20 /* object was dropped here */
|
||||||
|
#define F_LOCKED 0x20 /* door is locked */
|
||||||
|
#define F_REAL 0x10 /* what you see is what you get */
|
||||||
|
#define F_PNUM 0x0f /* passage number mask */
|
||||||
|
#define F_TMASK 0x07 /* trap number mask */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Trap types
|
||||||
|
*/
|
||||||
|
#define T_DOOR 00
|
||||||
|
#define T_ARROW 01
|
||||||
|
#define T_SLEEP 02
|
||||||
|
#define T_BEAR 03
|
||||||
|
#define T_TELEP 04
|
||||||
|
#define T_DART 05
|
||||||
|
#define T_RUST 06
|
||||||
|
#define T_MYST 07
|
||||||
|
#define NTRAPS 8
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Potion types
|
||||||
|
*/
|
||||||
|
#define P_CONFUSE 0
|
||||||
|
#define P_LSD 1
|
||||||
|
#define P_POISON 2
|
||||||
|
#define P_STRENGTH 3
|
||||||
|
#define P_SEEINVIS 4
|
||||||
|
#define P_HEALING 5
|
||||||
|
#define P_MFIND 6
|
||||||
|
#define P_TFIND 7
|
||||||
|
#define P_RAISE 8
|
||||||
|
#define P_XHEAL 9
|
||||||
|
#define P_HASTE 10
|
||||||
|
#define P_RESTORE 11
|
||||||
|
#define P_BLIND 12
|
||||||
|
#define P_LEVIT 13
|
||||||
|
#define MAXPOTIONS 14
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Scroll types
|
||||||
|
*/
|
||||||
|
#define S_CONFUSE 0
|
||||||
|
#define S_MAP 1
|
||||||
|
#define S_HOLD 2
|
||||||
|
#define S_SLEEP 3
|
||||||
|
#define S_ARMOR 4
|
||||||
|
#define S_ID_POTION 5
|
||||||
|
#define S_ID_SCROLL 6
|
||||||
|
#define S_ID_WEAPON 7
|
||||||
|
#define S_ID_ARMOR 8
|
||||||
|
#define S_ID_R_OR_S 9
|
||||||
|
#define S_SCARE 10
|
||||||
|
#define S_FDET 11
|
||||||
|
#define S_TELEP 12
|
||||||
|
#define S_ENCH 13
|
||||||
|
#define S_CREATE 14
|
||||||
|
#define S_REMOVE 15
|
||||||
|
#define S_AGGR 16
|
||||||
|
#define S_PROTECT 17
|
||||||
|
#define MAXSCROLLS 18
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Weapon types
|
||||||
|
*/
|
||||||
|
#define MACE 0
|
||||||
|
#define SWORD 1
|
||||||
|
#define BOW 2
|
||||||
|
#define ARROW 3
|
||||||
|
#define DAGGER 4
|
||||||
|
#define TWOSWORD 5
|
||||||
|
#define DART 6
|
||||||
|
#define SHIRAKEN 7
|
||||||
|
#define SPEAR 8
|
||||||
|
#define FLAME 9 /* fake entry for dragon breath (ick) */
|
||||||
|
#define MAXWEAPONS 9 /* this should equal FLAME */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Armor types
|
||||||
|
*/
|
||||||
|
#define LEATHER 0
|
||||||
|
#define RING_MAIL 1
|
||||||
|
#define STUDDED_LEATHER 2
|
||||||
|
#define SCALE_MAIL 3
|
||||||
|
#define CHAIN_MAIL 4
|
||||||
|
#define SPLINT_MAIL 5
|
||||||
|
#define BANDED_MAIL 6
|
||||||
|
#define PLATE_MAIL 7
|
||||||
|
#define MAXARMORS 8
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ring types
|
||||||
|
*/
|
||||||
|
#define R_PROTECT 0
|
||||||
|
#define R_ADDSTR 1
|
||||||
|
#define R_SUSTSTR 2
|
||||||
|
#define R_SEARCH 3
|
||||||
|
#define R_SEEINVIS 4
|
||||||
|
#define R_NOP 5
|
||||||
|
#define R_AGGR 6
|
||||||
|
#define R_ADDHIT 7
|
||||||
|
#define R_ADDDAM 8
|
||||||
|
#define R_REGEN 9
|
||||||
|
#define R_DIGEST 10
|
||||||
|
#define R_TELEPORT 11
|
||||||
|
#define R_STEALTH 12
|
||||||
|
#define R_SUSTARM 13
|
||||||
|
#define MAXRINGS 14
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Rod/Wand/Staff types
|
||||||
|
*/
|
||||||
|
#define WS_LIGHT 0
|
||||||
|
#define WS_INVIS 1
|
||||||
|
#define WS_ELECT 2
|
||||||
|
#define WS_FIRE 3
|
||||||
|
#define WS_COLD 4
|
||||||
|
#define WS_POLYMORPH 5
|
||||||
|
#define WS_MISSILE 6
|
||||||
|
#define WS_HASTE_M 7
|
||||||
|
#define WS_SLOW_M 8
|
||||||
|
#define WS_DRAIN 9
|
||||||
|
#define WS_NOP 10
|
||||||
|
#define WS_TELAWAY 11
|
||||||
|
#define WS_TELTO 12
|
||||||
|
#define WS_CANCEL 13
|
||||||
|
#define MAXSTICKS 14
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now we define the structures and types
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Help list
|
||||||
|
*/
|
||||||
|
struct h_list {
|
||||||
|
int h_ch;
|
||||||
|
const char *h_desc;
|
||||||
|
int h_print;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Coordinate data type
|
||||||
|
*/
|
||||||
|
typedef struct coord {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
} coord;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Stuff about objects
|
||||||
|
*/
|
||||||
|
struct obj_info {
|
||||||
|
const char *oi_name;
|
||||||
|
int oi_prob;
|
||||||
|
int oi_worth;
|
||||||
|
char *oi_guess;
|
||||||
|
int oi_know;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Room structure
|
||||||
|
*/
|
||||||
|
struct room {
|
||||||
|
coord r_pos; /* Upper left corner */
|
||||||
|
coord r_max; /* Size of room */
|
||||||
|
coord r_gold; /* Where the gold is */
|
||||||
|
int r_goldval; /* How much the gold is worth */
|
||||||
|
int r_flags; /* info about the room */
|
||||||
|
int r_nexits; /* Number of exits */
|
||||||
|
coord r_exit[12]; /* Where the exits are */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structure describing a fighting being
|
||||||
|
*/
|
||||||
|
struct stats {
|
||||||
|
int s_str; /* Strength */
|
||||||
|
int s_exp; /* Experience */
|
||||||
|
int s_lvl; /* level of mastery */
|
||||||
|
int s_arm; /* Armor class */
|
||||||
|
int s_hpt; /* Hit points */
|
||||||
|
char s_dmg[13]; /* String describing damage done */
|
||||||
|
int s_maxhp; /* Max hit points */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structure for monsters and player
|
||||||
|
*/
|
||||||
|
union thing {
|
||||||
|
struct {
|
||||||
|
union thing *_l_next, *_l_prev; /* Next pointer in link */
|
||||||
|
coord _t_pos; /* Position */
|
||||||
|
int _t_turn; /* If slowed, is it a turn to move */
|
||||||
|
int _t_type; /* What it is */
|
||||||
|
int _t_disguise; /* What mimic looks like */
|
||||||
|
int _t_oldch; /* Character that was where it was */
|
||||||
|
const coord *_t_dest; /* Where it is running to */
|
||||||
|
int _t_flags; /* State word */
|
||||||
|
struct stats _t_stats; /* Physical description */
|
||||||
|
struct room *_t_room; /* Current room for thing */
|
||||||
|
union thing *_t_pack; /* What the thing is carrying */
|
||||||
|
int _t_reserved;
|
||||||
|
} _t;
|
||||||
|
struct {
|
||||||
|
union thing *_l_next, *_l_prev; /* Next pointer in link */
|
||||||
|
int _o_type; /* What kind of object it is */
|
||||||
|
coord _o_pos; /* Where it lives on the screen */
|
||||||
|
char *_o_text; /* What it says if you read it */
|
||||||
|
int _o_launch; /* What you need to launch it */
|
||||||
|
int _o_packch; /* What character it is in the pack */
|
||||||
|
char _o_damage[8]; /* Damage if used like sword */
|
||||||
|
char _o_hurldmg[8]; /* Damage if thrown */
|
||||||
|
int _o_count; /* count for plural objects */
|
||||||
|
int _o_which; /* Which object of a type it is */
|
||||||
|
int _o_hplus; /* Plusses to hit */
|
||||||
|
int _o_dplus; /* Plusses to damage */
|
||||||
|
int _o_arm; /* Armor protection */
|
||||||
|
int _o_flags; /* information about objects */
|
||||||
|
int _o_group; /* group number for this object */
|
||||||
|
char *_o_label; /* Label for object */
|
||||||
|
} _o;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef union thing THING;
|
||||||
|
|
||||||
|
#define l_next _t._l_next
|
||||||
|
#define l_prev _t._l_prev
|
||||||
|
#define t_pos _t._t_pos
|
||||||
|
#define t_turn _t._t_turn
|
||||||
|
#define t_type _t._t_type
|
||||||
|
#define t_disguise _t._t_disguise
|
||||||
|
#define t_oldch _t._t_oldch
|
||||||
|
#define t_dest _t._t_dest
|
||||||
|
#define t_flags _t._t_flags
|
||||||
|
#define t_stats _t._t_stats
|
||||||
|
#define t_pack _t._t_pack
|
||||||
|
#define t_room _t._t_room
|
||||||
|
#define t_reserved _t._t_reserved
|
||||||
|
#define o_type _o._o_type
|
||||||
|
#define o_pos _o._o_pos
|
||||||
|
#define o_text _o._o_text
|
||||||
|
#define o_launch _o._o_launch
|
||||||
|
#define o_packch _o._o_packch
|
||||||
|
#define o_damage _o._o_damage
|
||||||
|
#define o_hurldmg _o._o_hurldmg
|
||||||
|
#define o_count _o._o_count
|
||||||
|
#define o_which _o._o_which
|
||||||
|
#define o_hplus _o._o_hplus
|
||||||
|
#define o_dplus _o._o_dplus
|
||||||
|
#define o_arm _o._o_arm
|
||||||
|
#define o_charges o_arm
|
||||||
|
#define o_goldval o_arm
|
||||||
|
#define o_flags _o._o_flags
|
||||||
|
#define o_group _o._o_group
|
||||||
|
#define o_label _o._o_label
|
||||||
|
|
||||||
|
/*
|
||||||
|
* describe a place on the level map
|
||||||
|
*/
|
||||||
|
typedef struct PLACE {
|
||||||
|
int p_ch;
|
||||||
|
int p_flags;
|
||||||
|
THING *p_monst;
|
||||||
|
} PLACE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Array containing information on all the various types of monsters
|
||||||
|
*/
|
||||||
|
struct monster {
|
||||||
|
const char *m_name; /* What to call the monster */
|
||||||
|
int m_carry; /* Probability of carrying something */
|
||||||
|
int m_flags; /* things about the monster */
|
||||||
|
struct stats m_stats; /* Initial stats */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct delayed_action {
|
||||||
|
int d_type;
|
||||||
|
void (*d_func)();
|
||||||
|
int d_arg;
|
||||||
|
int d_time;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct STONE {
|
||||||
|
char *st_name;
|
||||||
|
int st_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct STONE STONE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* External variables
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern int after, again, allscore, door_stop, fight_flush,
|
||||||
|
firstmove, has_hit, inv_describe, jump, kamikaze,
|
||||||
|
lower_msg, move_on, msg_esc, pack_used[],
|
||||||
|
passgo, playing, q_comm, running, save_msg, see_floor,
|
||||||
|
seenstairs, stat_msg, terse, to_death, tombstone,
|
||||||
|
amulet, count, dir_ch, food_left, hungry_state, inpack,
|
||||||
|
inv_type, lastscore, level, max_hit, max_level, mpos, take,
|
||||||
|
n_objs, no_command, no_food, no_move, noscore, ntraps, purse,
|
||||||
|
quiet, vf_hit, runch, last_comm, l_last_comm, last_dir, l_last_dir,
|
||||||
|
numscores, total, between, group, cNWOOD, cNMETAL, cNSTONES,
|
||||||
|
cNCOLORS;
|
||||||
|
|
||||||
|
extern char file_name[], home[], huh[], *Numname, outbuf[],
|
||||||
|
*ws_type[], *s_names[];
|
||||||
|
|
||||||
|
extern const char *ws_made[], *inv_t_name[], *p_colors[], *r_stones[],
|
||||||
|
*release, *tr_name[], *rainbow[], *wood[], *metal[],
|
||||||
|
encstr[], statlist[], version[];
|
||||||
|
|
||||||
|
extern const int a_class[], e_levels[];
|
||||||
|
|
||||||
|
extern unsigned int dnum, seed;
|
||||||
|
|
||||||
|
extern WINDOW *hw;
|
||||||
|
|
||||||
|
extern coord delta, oldpos, stairs;
|
||||||
|
|
||||||
|
extern PLACE places[];
|
||||||
|
|
||||||
|
extern THING *cur_armor, *cur_ring[], *cur_weapon, *l_last_pick,
|
||||||
|
*last_pick, *lvl_obj, *mlist, player;
|
||||||
|
|
||||||
|
extern const struct h_list helpstr[];
|
||||||
|
|
||||||
|
extern struct room *oldrp, passages[], rooms[];
|
||||||
|
|
||||||
|
extern struct stats max_stats;
|
||||||
|
|
||||||
|
extern struct monster monsters[];
|
||||||
|
|
||||||
|
extern struct obj_info arm_info[], pot_info[], ring_info[],
|
||||||
|
scr_info[], things[], ws_info[], weap_info[];
|
||||||
|
|
||||||
|
extern struct delayed_action d_list[MAXDAEMONS];
|
||||||
|
|
||||||
|
extern const STONE stones[];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function types
|
||||||
|
*/
|
||||||
|
|
||||||
|
void _attach(THING **list, THING *item);
|
||||||
|
void _detach(THING **list, THING *item);
|
||||||
|
void _free_list(THING **ptr);
|
||||||
|
void addmsg(const char *fmt, ...);
|
||||||
|
int add_haste(int potion);
|
||||||
|
int add_line(const char *fmt, const char *arg);
|
||||||
|
void add_pack(THING *obj, int silent);
|
||||||
|
void add_pass(void);
|
||||||
|
void add_str(int *sp, int amt);
|
||||||
|
void accnt_maze(int y, int x, int ny, int nx);
|
||||||
|
void aggravate(void);
|
||||||
|
int attack(THING *mp);
|
||||||
|
void auto_save(int);
|
||||||
|
void badcheck(const char *name, const struct obj_info *info, int bound);
|
||||||
|
int be_trapped(const coord *tc);
|
||||||
|
void bounce(const THING *weap, const char *mname, int noend);
|
||||||
|
void call(void);
|
||||||
|
void call_it(struct obj_info *info);
|
||||||
|
int cansee(int y, int x);
|
||||||
|
int center(const char *str);
|
||||||
|
int chase(THING *tp, const coord *ee);
|
||||||
|
int checkout(void);
|
||||||
|
const char *charge_str(const THING *obj);
|
||||||
|
void chg_str(int amt);
|
||||||
|
void check_level(void);
|
||||||
|
const char *choose_str(const char *ts, const char *ns);
|
||||||
|
void conn(int r1, int r2);
|
||||||
|
void come_down(void);
|
||||||
|
void command(void);
|
||||||
|
void create_obj(void);
|
||||||
|
void current(const THING *cur, const char *how, const char *where);
|
||||||
|
void d_level(void);
|
||||||
|
void death(int monst);
|
||||||
|
int death_monst(void);
|
||||||
|
int diag_ok(const coord *sp, const coord *ep);
|
||||||
|
void dig(int y, int x);
|
||||||
|
void discard(THING *item);
|
||||||
|
void discovered(void);
|
||||||
|
int dist(int y1, int x1, int y2, int x2);
|
||||||
|
int dist_cp(const coord *c1, const coord *c2);
|
||||||
|
int do_chase(THING *th);
|
||||||
|
void do_daemons(int flag);
|
||||||
|
void do_fuses(int flag);
|
||||||
|
void do_maze(const struct room *rp);
|
||||||
|
void do_motion(THING *obj, int ydelta, int xdelta);
|
||||||
|
void do_move(int dy, int dx);
|
||||||
|
void do_passages(void);
|
||||||
|
void do_pot(int type, int knowit);
|
||||||
|
void do_rooms(void);
|
||||||
|
void do_run(int ch);
|
||||||
|
void do_zap(void);
|
||||||
|
void doadd(const char *fmt, va_list args);
|
||||||
|
void doctor(void);
|
||||||
|
void door(struct room *rm, const coord *cp);
|
||||||
|
void door_open(const struct room *rp);
|
||||||
|
void drain(void);
|
||||||
|
void draw_room(const struct room *rp);
|
||||||
|
void drop(void);
|
||||||
|
int dropcheck(const THING *obj);
|
||||||
|
void eat(void);
|
||||||
|
int encclearerr();
|
||||||
|
int encerror();
|
||||||
|
void encseterr();
|
||||||
|
size_t encread(char *start, size_t size, FILE *inf);
|
||||||
|
size_t encwrite(const char *start, size_t size, FILE *outf);
|
||||||
|
void end_line(void);
|
||||||
|
void endit(int sig);
|
||||||
|
int endmsg(void);
|
||||||
|
void enter_room(const coord *cp);
|
||||||
|
void erase_lamp(const coord *pos, const struct room *rp);
|
||||||
|
int exp_add(const THING *tp);
|
||||||
|
void extinguish(void (*func)());
|
||||||
|
void fall(THING *obj, int pr);
|
||||||
|
int fallpos(const coord *pos, coord *newpos);
|
||||||
|
void fatal(const char *s);
|
||||||
|
void fire_bolt(const coord *start, coord *dir, const char *name);
|
||||||
|
int floor_at(void);
|
||||||
|
int floor_ch(void);
|
||||||
|
void flush_type(void);
|
||||||
|
const coord *find_dest(const THING *tp);
|
||||||
|
int find_floor(const struct room *rp, coord *cp, int limit, int monst);
|
||||||
|
THING *find_obj(int y, int x);
|
||||||
|
int fight(const coord *mp, const THING *weap, int thrown);
|
||||||
|
void fix_stick(THING *cur);
|
||||||
|
void fuse(void (*func)(), int arg, int time, int type);
|
||||||
|
int get_bool(void *vp, WINDOW *win);
|
||||||
|
int get_dir(void);
|
||||||
|
int get_inv_t(void *vp, WINDOW *win);
|
||||||
|
THING *get_item(const char *purpose, int type);
|
||||||
|
int get_num(void *vp, WINDOW *win);
|
||||||
|
int get_sf(void *vp, WINDOW *win);
|
||||||
|
int get_str(void *vopt, WINDOW *win);
|
||||||
|
int gethand(void);
|
||||||
|
void getltchars(void);
|
||||||
|
void give_pack(THING *tp);
|
||||||
|
void help(void);
|
||||||
|
void hit(const char *er, const char *ee, int noend);
|
||||||
|
void horiz(const struct room *rp, int starty);
|
||||||
|
void leave_room(const coord *cp);
|
||||||
|
void lengthen(void (*func)(), int xtime);
|
||||||
|
void look(int wakeup);
|
||||||
|
int hit_monster(int y, int x, const THING *obj);
|
||||||
|
void identify(void);
|
||||||
|
void illcom(int ch);
|
||||||
|
void init_check(void);
|
||||||
|
void init_colors(void);
|
||||||
|
void init_materials(void);
|
||||||
|
void init_names(void);
|
||||||
|
void init_player(void);
|
||||||
|
void init_probs(void);
|
||||||
|
void init_stones(void);
|
||||||
|
void init_weapon(THING *weap, int which);
|
||||||
|
char *inv_name(const THING *obj, int drop);
|
||||||
|
int inventory(const THING *list, int type);
|
||||||
|
void invis_on(void);
|
||||||
|
int is_current(const THING *obj);
|
||||||
|
int is_magic(const THING *obj);
|
||||||
|
int is_symlink(const char *sp);
|
||||||
|
void kill_daemon(void (*func)());
|
||||||
|
void killed(THING *tp, int pr);
|
||||||
|
const char *killname(int monst, int doart);
|
||||||
|
void land(void);
|
||||||
|
void leave(int);
|
||||||
|
THING *leave_pack(THING *obj, int newobj, int all);
|
||||||
|
int levit_check(void);
|
||||||
|
int lock_sc(void);
|
||||||
|
void miss(const char *er, const char *ee, int noend);
|
||||||
|
void missile(int ydelta, int xdelta);
|
||||||
|
void money(int value);
|
||||||
|
int move_monst(THING *tp);
|
||||||
|
void move_msg(const THING *obj);
|
||||||
|
int msg(const char *fmt, ...);
|
||||||
|
void my_exit(int sig);
|
||||||
|
void nameit(const THING *obj, const char *type, const char *which, const struct obj_info *op, const char *(*prfunc)(const THING *));
|
||||||
|
THING *new_item(void);
|
||||||
|
void new_level(void);
|
||||||
|
void new_monster(THING *tp, int type, const coord *cp);
|
||||||
|
THING *new_thing(void);
|
||||||
|
void nohaste(void);
|
||||||
|
const char *nothing(int type);
|
||||||
|
const char *nullstr(const THING *ignored);
|
||||||
|
const char *num(int n1, int n2, int type);
|
||||||
|
void numpass(int y, int x);
|
||||||
|
void option(void);
|
||||||
|
void open_score(void);
|
||||||
|
int pack_char(void);
|
||||||
|
int pack_room(int from_floor, THING *obj);
|
||||||
|
void parse_opts(char *str);
|
||||||
|
void passnum(void);
|
||||||
|
int passwd(void);
|
||||||
|
const char *pick_color(const char *col);
|
||||||
|
int pick_one(const struct obj_info *info, int nitems);
|
||||||
|
void pick_up(int ch);
|
||||||
|
void picky_inven(void);
|
||||||
|
void playit(void);
|
||||||
|
void playltchars(void);
|
||||||
|
void pr_spec(const struct obj_info *info, int nitems);
|
||||||
|
void pr_list(void);
|
||||||
|
void print_disc(int);
|
||||||
|
void put_bool(void *b);
|
||||||
|
void put_inv_t(void *ip);
|
||||||
|
void put_str(void *str);
|
||||||
|
void put_things(void);
|
||||||
|
void putpass(const coord *cp);
|
||||||
|
void quaff(void);
|
||||||
|
void quit(int);
|
||||||
|
void raise_level(void);
|
||||||
|
int randmonster(int wander);
|
||||||
|
void read_scroll(void);
|
||||||
|
int readchar(void);
|
||||||
|
void relocate(THING *th, const coord *new_loc);
|
||||||
|
void remove_mon(const coord *mp, THING *tp, int waskill);
|
||||||
|
void reset_last(void);
|
||||||
|
void resetltchars(void);
|
||||||
|
int restore(const char *file);
|
||||||
|
int ring_eat(int hand);
|
||||||
|
void ring_on(void);
|
||||||
|
void ring_off(void);
|
||||||
|
const char *ring_num(const THING *obj);
|
||||||
|
int rnd(int range);
|
||||||
|
int rnd_room(void);
|
||||||
|
int rnd_thing(void);
|
||||||
|
coord rndmove(const THING *who);
|
||||||
|
int roll(int number, int sides);
|
||||||
|
int roll_em(const THING *thatt, THING *thdef, const THING *weap, int hurl);
|
||||||
|
void rollwand(void);
|
||||||
|
struct room *roomin(const coord *cp);
|
||||||
|
int rs_save_file(FILE *savef);
|
||||||
|
int rs_restore_file(FILE *inf);
|
||||||
|
void runners(void);
|
||||||
|
void runto(const coord *runner);
|
||||||
|
void rust_armor(THING *arm);
|
||||||
|
int save(int which);
|
||||||
|
void save_file(FILE *savef);
|
||||||
|
void save_game(void);
|
||||||
|
int save_throw(int which, const THING *tp);
|
||||||
|
void score(int amount, int flags, int monst);
|
||||||
|
void search(void);
|
||||||
|
int see_monst(const THING *mp);
|
||||||
|
int seen_stairs(void);
|
||||||
|
void set_know(THING *obj, struct obj_info *info);
|
||||||
|
const char *set_mname(const THING *tp);
|
||||||
|
void set_oldch(THING *tp, const coord *cp);
|
||||||
|
void set_order(int *order, int numthings);
|
||||||
|
void setup(void);
|
||||||
|
void shell(void);
|
||||||
|
int show_floor(void);
|
||||||
|
void show_map(void);
|
||||||
|
void show_win(const char *message);
|
||||||
|
void sight(void);
|
||||||
|
int sign(int nm);
|
||||||
|
int spread(int nm);
|
||||||
|
void start_daemon(void (*func)(), int arg, int type);
|
||||||
|
void start_score(void);
|
||||||
|
void status(void);
|
||||||
|
int step_ok(int ch);
|
||||||
|
void stomach(void);
|
||||||
|
void strucpy(char *s1, const char *s2, size_t len);
|
||||||
|
void swander(void);
|
||||||
|
int swing(int at_lvl, int op_arm, int wplus);
|
||||||
|
void take_off(void);
|
||||||
|
void teleport(void);
|
||||||
|
void total_winner(void);
|
||||||
|
void thunk(const THING *weap, const char *mname, int noend);
|
||||||
|
void treas_room(void);
|
||||||
|
int trip_ch(int y, int x, int ch);
|
||||||
|
void tstp(int ignored);
|
||||||
|
int turn_ok(int y, int x);
|
||||||
|
int turn_see(int turn_off);
|
||||||
|
void turnref(void);
|
||||||
|
const char *type_name(int type);
|
||||||
|
void u_level(void);
|
||||||
|
void unconfuse(void);
|
||||||
|
void uncurse(THING *obj);
|
||||||
|
void unlock_sc(void);
|
||||||
|
void unsee(void);
|
||||||
|
void vert(const struct room *rp, int startx);
|
||||||
|
void visuals(void);
|
||||||
|
char *vowelstr(const char *str);
|
||||||
|
void wait_for(WINDOW *win, int ch);
|
||||||
|
const THING *wake_monster(int y, int x);
|
||||||
|
void wanderer(void);
|
||||||
|
void waste_time(void);
|
||||||
|
void wear(void);
|
||||||
|
void whatis(int insist, int type);
|
||||||
|
void wield(void);
|
||||||
|
int wreadchar(WINDOW *win);
|
||||||
|
|
||||||
1060
rogue5/rogue.html.in
Normal file
1060
rogue5/rogue.html.in
Normal file
File diff suppressed because it is too large
Load diff
892
rogue5/rogue.me.in
Normal file
892
rogue5/rogue.me.in
Normal file
|
|
@ -0,0 +1,892 @@
|
||||||
|
.\"
|
||||||
|
.\" @(#)rogue.me 6.2 (Berkeley) 4/28/86
|
||||||
|
.\"
|
||||||
|
.\" Rogue: Exploring the Dungeons of Doom
|
||||||
|
.\" Copyright (C) 1980-1983, 1985, 1986 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
.\" All rights reserved.
|
||||||
|
.\"
|
||||||
|
.\" See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
.\"
|
||||||
|
.ds E \s-2<ESCAPE>\s0
|
||||||
|
.ds R \s-2<RETURN>\s0
|
||||||
|
.ds U \s-2UNIX\s0
|
||||||
|
.ie t .ds _ \d\(mi\u
|
||||||
|
.el .ds _ _
|
||||||
|
.de Cs
|
||||||
|
\&\\$3\*(lq\\$1\*(rq\\$2
|
||||||
|
..
|
||||||
|
.sp 5
|
||||||
|
.ce 1000
|
||||||
|
.ps +4
|
||||||
|
.vs +4p
|
||||||
|
.b
|
||||||
|
A Guide to the Dungeons of Doom
|
||||||
|
.r
|
||||||
|
.vs
|
||||||
|
.ps
|
||||||
|
.sp 2
|
||||||
|
.i
|
||||||
|
Michael C. Toy
|
||||||
|
Kenneth C. R. C. Arnold
|
||||||
|
.r
|
||||||
|
.sp 2
|
||||||
|
Computer Systems Research Group
|
||||||
|
Department of Electrical Engineering and Computer Science
|
||||||
|
University of California
|
||||||
|
Berkeley, California 94720
|
||||||
|
.sp 4
|
||||||
|
.i ABSTRACT
|
||||||
|
.ce 0
|
||||||
|
.(b I F
|
||||||
|
.bi Rogue
|
||||||
|
is a visual CRT based fantasy game
|
||||||
|
which runs under the \*U\(dg timesharing system.
|
||||||
|
.(f
|
||||||
|
\fR\(dg\*U is a trademark of Bell Laboratories\fP
|
||||||
|
.)f
|
||||||
|
This paper describes how to play rogue,
|
||||||
|
and gives a few hints
|
||||||
|
for those who might otherwise get lost in the Dungeons of Doom.
|
||||||
|
.)b
|
||||||
|
\".he '''\fBA Guide to the Dungeons of Doom\fP'
|
||||||
|
\" .fo ''- % -''
|
||||||
|
.eh 'USD:33-%''A Guide to the Dungeons of Doom'
|
||||||
|
.oh 'A Guide to the Dungeons of Doom''USD:33-%'
|
||||||
|
.sh 1 Introduction
|
||||||
|
.pp
|
||||||
|
You have just finished your years as a student at the local fighter's guild.
|
||||||
|
After much practice and sweat you have finally completed your training
|
||||||
|
and are ready to embark upon a perilous adventure.
|
||||||
|
As a test of your skills,
|
||||||
|
the local guildmasters have sent you into the Dungeons of Doom.
|
||||||
|
Your task is to return with the Amulet of Yendor.
|
||||||
|
Your reward for the completion of this task
|
||||||
|
will be a full membership in the local guild.
|
||||||
|
In addition,
|
||||||
|
you are allowed to keep all the loot you bring back from the dungeons.
|
||||||
|
.pp
|
||||||
|
In preparation for your journey,
|
||||||
|
you are given an enchanted mace,
|
||||||
|
a bow, and a quiver of arrows
|
||||||
|
taken from a dragon's hoard in the far off Dark Mountains.
|
||||||
|
You are also outfitted with elf-crafted armor
|
||||||
|
and given enough food to reach the dungeons.
|
||||||
|
You say goodbye to family and friends for what may be the last time
|
||||||
|
and head up the road.
|
||||||
|
.pp
|
||||||
|
You set out on your way to the dungeons
|
||||||
|
and after several days of uneventful travel,
|
||||||
|
you see the ancient ruins
|
||||||
|
that mark the entrance to the Dungeons of Doom.
|
||||||
|
It is late at night,
|
||||||
|
so you make camp at the entrance
|
||||||
|
and spend the night sleeping under the open skies.
|
||||||
|
In the morning you gather your weapons,
|
||||||
|
put on your armor,
|
||||||
|
eat what is almost your last food,
|
||||||
|
and enter the dungeons.
|
||||||
|
.sh 1 "What is going on here?"
|
||||||
|
.pp
|
||||||
|
You have just begun a game of rogue.
|
||||||
|
Your goal is to grab as much treasure as you can,
|
||||||
|
find the Amulet of Yendor,
|
||||||
|
and get out of the Dungeons of Doom alive.
|
||||||
|
On the screen,
|
||||||
|
a map of where you have been
|
||||||
|
and what you have seen on the current dungeon level is kept.
|
||||||
|
As you explore more of the level,
|
||||||
|
it appears on the screen in front of you.
|
||||||
|
.pp
|
||||||
|
Rogue differs from most computer fantasy games in that it is screen oriented.
|
||||||
|
Commands are all one or two keystrokes\**
|
||||||
|
.(f
|
||||||
|
\** As opposed to pseudo English sentences.
|
||||||
|
.)f
|
||||||
|
and the results of your commands
|
||||||
|
are displayed graphically on the screen rather
|
||||||
|
than being explained in words.\**
|
||||||
|
.(f
|
||||||
|
\** A minimum screen size of 24 lines by 80 columns is required.
|
||||||
|
If the screen is larger, only the 24x80 section will be used
|
||||||
|
for the map.
|
||||||
|
.)f
|
||||||
|
.pp
|
||||||
|
Another major difference between rogue and other computer fantasy games
|
||||||
|
is that once you have solved all the puzzles in a standard fantasy game,
|
||||||
|
it has lost most of its excitement and it ceases to be fun.
|
||||||
|
Rogue,
|
||||||
|
on the other hand,
|
||||||
|
generates a new dungeon every time you play it
|
||||||
|
and even the author finds it an entertaining and exciting game.
|
||||||
|
.sh 1 "What do all those things on the screen mean?"
|
||||||
|
.pp
|
||||||
|
In order to understand what is going on in rogue
|
||||||
|
you have to first get some grasp of what rogue is doing with the screen.
|
||||||
|
The rogue screen is intended
|
||||||
|
to replace the \*(lqYou can see ...\*(rq descriptions
|
||||||
|
of standard fantasy games.
|
||||||
|
Figure 1 is a sample of what a rogue screen might look like.
|
||||||
|
.(z
|
||||||
|
.hl
|
||||||
|
.nf
|
||||||
|
.TS
|
||||||
|
center;
|
||||||
|
ce0 ce0 ce0 ce0 ce0 ce0 ce0 ce0 ce0 ce0 ce0 ce.
|
||||||
|
- - - - - - - - - - - -
|
||||||
|
| . . . . . . . . . . +
|
||||||
|
| . . @ . . . . ] . . |
|
||||||
|
| . . . . B . . . . . |
|
||||||
|
| . . . . . . . . . . |
|
||||||
|
- - - - - + - - - - - -
|
||||||
|
.TE
|
||||||
|
|
||||||
|
|
||||||
|
.ce 1000
|
||||||
|
Level: 1 Gold: 0 Hp: 12(12) Str: 16(16) Arm: 4 Exp: 1/0
|
||||||
|
|
||||||
|
Figure 1
|
||||||
|
.ce
|
||||||
|
.hl
|
||||||
|
.)z
|
||||||
|
.sh 2 "The bottom line"
|
||||||
|
.pp
|
||||||
|
At the bottom line of the screen
|
||||||
|
are a few pieces of cryptic information
|
||||||
|
describing your current status.
|
||||||
|
Here is an explanation of what these things mean:
|
||||||
|
.ip Level \w'Level\ \ 'u
|
||||||
|
This number indicates how deep you have gone in the dungeon.
|
||||||
|
It starts at one and goes up as you go deeper into the dungeon.
|
||||||
|
.ip Gold \w'Level\ \ 'u
|
||||||
|
The number of gold pieces you have managed to find
|
||||||
|
and keep with you so far.
|
||||||
|
.ip Hp \w'Level\ \ 'u
|
||||||
|
Your current and maximum health points.
|
||||||
|
Health points indicate how much damage you can take before you die.
|
||||||
|
The more you get hit in a fight,
|
||||||
|
the lower they get.
|
||||||
|
You can regain health points by resting.
|
||||||
|
The number in parentheses
|
||||||
|
is the maximum number your health points can reach.
|
||||||
|
.ip Str \w'Level\ \ 'u
|
||||||
|
Your current strength and maximum ever strength.
|
||||||
|
This can be any integer less than or equal to 31,
|
||||||
|
or greater than or equal to three.
|
||||||
|
The higher the number,
|
||||||
|
the stronger you are.
|
||||||
|
The number in the parentheses
|
||||||
|
is the maximum strength you have attained so far this game.
|
||||||
|
.ip Arm \w'Level\ \ 'u
|
||||||
|
Your current armor protection.
|
||||||
|
This number indicates how effective your armor is
|
||||||
|
in stopping blows from unfriendly creatures.
|
||||||
|
The higher this number is,
|
||||||
|
the more effective the armor.
|
||||||
|
.ip Exp \w'Level\ \ 'u
|
||||||
|
These two numbers give your current experience level
|
||||||
|
and experience points.
|
||||||
|
As you do things,
|
||||||
|
you gain experience points.
|
||||||
|
At certain experience point totals,
|
||||||
|
you gain an experience level.
|
||||||
|
The more experienced you are,
|
||||||
|
the better you are able to fight and to withstand magical attacks.
|
||||||
|
.sh 2 "The top line"
|
||||||
|
.pp
|
||||||
|
The top line of the screen is reserved
|
||||||
|
for printing messages that describe things
|
||||||
|
that are impossible to represent visually.
|
||||||
|
If you see a \*(lq--More--\*(rq on the top line,
|
||||||
|
this means that rogue wants to print another message on the screen,
|
||||||
|
but it wants to make certain
|
||||||
|
that you have read the one that is there first.
|
||||||
|
To read the next message,
|
||||||
|
just type a space.
|
||||||
|
.sh 2 "The rest of the screen"
|
||||||
|
.pp
|
||||||
|
The rest of the screen is the map of the level
|
||||||
|
as you have explored it so far.
|
||||||
|
Each symbol on the screen represents something.
|
||||||
|
Here is a list of what the various symbols mean:
|
||||||
|
.ip @
|
||||||
|
This symbol represents you, the adventurer.
|
||||||
|
.ip "-\^|"
|
||||||
|
These symbols represent the walls of rooms.
|
||||||
|
.ip +
|
||||||
|
A door to/from a room.
|
||||||
|
.ip .
|
||||||
|
The floor of a room.
|
||||||
|
.ip #
|
||||||
|
The floor of a passage between rooms.
|
||||||
|
.ip *
|
||||||
|
A pile or pot of gold.
|
||||||
|
.ip )
|
||||||
|
A weapon of some sort.
|
||||||
|
.ip ]
|
||||||
|
A piece of armor.
|
||||||
|
.ip !
|
||||||
|
A flask containing a magic potion.
|
||||||
|
.ip ?
|
||||||
|
A piece of paper, usually a magic scroll.
|
||||||
|
.ip =
|
||||||
|
A ring with magic properties
|
||||||
|
.ip /
|
||||||
|
A magical staff or wand
|
||||||
|
.ip ^
|
||||||
|
A trap, watch out for these.
|
||||||
|
.ip %
|
||||||
|
A staircase to other levels
|
||||||
|
.ip :
|
||||||
|
A piece of food.
|
||||||
|
.ip A-Z
|
||||||
|
The uppercase letters
|
||||||
|
represent the various inhabitants of the Dungeons of Doom.
|
||||||
|
Watch out, they can be nasty and vicious.
|
||||||
|
.sh 1 Commands
|
||||||
|
.pp
|
||||||
|
Commands are given to rogue by typing one or two characters.
|
||||||
|
Most commands can be preceded by a count to repeat them
|
||||||
|
(e.g. typing
|
||||||
|
.Cs 10s
|
||||||
|
will do ten searches).
|
||||||
|
Commands for which counts make no sense
|
||||||
|
have the count ignored.
|
||||||
|
To cancel a count or a prefix,
|
||||||
|
type \*E.
|
||||||
|
The list of commands is rather long,
|
||||||
|
but it can be read at any time during the game with the
|
||||||
|
.Cs ?
|
||||||
|
command.
|
||||||
|
Here it is for reference,
|
||||||
|
with a short explanation of each command.
|
||||||
|
.ip ?
|
||||||
|
The help command.
|
||||||
|
Asks for a character to give help on.
|
||||||
|
If you type a
|
||||||
|
.Cs * ,
|
||||||
|
it will list all the commands,
|
||||||
|
otherwise it will explain what the character you typed does.
|
||||||
|
.ip /
|
||||||
|
This is the \*(lqWhat is that on the screen?\*(rq command.
|
||||||
|
A
|
||||||
|
.Cs /
|
||||||
|
followed by any character that you see on the level,
|
||||||
|
will tell you what that character is.
|
||||||
|
For instance,
|
||||||
|
typing
|
||||||
|
.Cs /@
|
||||||
|
will tell you that the
|
||||||
|
.Cs @
|
||||||
|
symbol represents you, the player.
|
||||||
|
.ip "h, H, ^H"
|
||||||
|
Move left.
|
||||||
|
You move one space to the left.
|
||||||
|
If you use upper case
|
||||||
|
.Cs h ,
|
||||||
|
you will continue to move left until you run into something.
|
||||||
|
This works for all movement commands
|
||||||
|
(e.g.
|
||||||
|
.Cs L
|
||||||
|
means run in direction
|
||||||
|
.Cs l )
|
||||||
|
If you use the \*(lqcontrol\*(rq
|
||||||
|
.Cs h ,
|
||||||
|
you will continue moving in the specified direction
|
||||||
|
until you pass something interesting or run into a wall.
|
||||||
|
You should experiment with this,
|
||||||
|
since it is a very useful command,
|
||||||
|
but very difficult to describe.
|
||||||
|
This also works for all movement commands.
|
||||||
|
.ip j
|
||||||
|
Move down.
|
||||||
|
.ip k
|
||||||
|
Move up.
|
||||||
|
.ip l
|
||||||
|
Move right.
|
||||||
|
.ip y
|
||||||
|
Move diagonally up and left.
|
||||||
|
.ip u
|
||||||
|
Move diagonally up and right.
|
||||||
|
.ip b
|
||||||
|
Move diagonally down and left.
|
||||||
|
.ip n
|
||||||
|
Move diagonally down and right.
|
||||||
|
.ip t
|
||||||
|
Throw an object.
|
||||||
|
This is a prefix command.
|
||||||
|
When followed with a direction
|
||||||
|
it throws an object in the specified direction.
|
||||||
|
(e.g. type
|
||||||
|
.Cs th
|
||||||
|
to throw
|
||||||
|
something to the left.)
|
||||||
|
.ip f
|
||||||
|
Fight until someone dies.
|
||||||
|
When followed with a direction
|
||||||
|
this will force you to fight the creature in that direction
|
||||||
|
until either you or it bites the big one.
|
||||||
|
.ip m
|
||||||
|
Move onto something without picking it up.
|
||||||
|
This will move you one space in the direction you specify and,
|
||||||
|
if there is an object there you can pick up,
|
||||||
|
it won't do it.
|
||||||
|
.ip z
|
||||||
|
Zap prefix.
|
||||||
|
Point a staff or wand in a given direction
|
||||||
|
and fire it.
|
||||||
|
Even non-directional staves must be pointed in some direction
|
||||||
|
to be used.
|
||||||
|
.ip ^
|
||||||
|
Identify trap command.
|
||||||
|
If a trap is on your map
|
||||||
|
and you can't remember what type it is,
|
||||||
|
you can get rogue to remind you
|
||||||
|
by getting next to it and typing
|
||||||
|
.Cs ^
|
||||||
|
followed by the direction that would move you on top of it.
|
||||||
|
.ip s
|
||||||
|
Search for traps and secret doors.
|
||||||
|
Examine each space immediately adjacent to you
|
||||||
|
for the existence of a trap or secret door.
|
||||||
|
There is a large chance that even if there is something there,
|
||||||
|
you won't find it,
|
||||||
|
so you might have to search a while before you find something.
|
||||||
|
.ip >
|
||||||
|
Climb down a staircase to the next level.
|
||||||
|
Not surprisingly, this can only be done if you are standing on staircase.
|
||||||
|
.ip <
|
||||||
|
Climb up a staircase to the level above.
|
||||||
|
This can't be done without the Amulet of Yendor in your possession.
|
||||||
|
.ip "."
|
||||||
|
Rest.
|
||||||
|
This is the \*(lqdo nothing\*(rq command.
|
||||||
|
This is good for waiting and healing.
|
||||||
|
.ip ,
|
||||||
|
Pick up something.
|
||||||
|
This picks up whatever you are currently standing on,
|
||||||
|
if you are standing on anything at all.
|
||||||
|
.ip i
|
||||||
|
Inventory.
|
||||||
|
List what you are carrying in your pack.
|
||||||
|
.ip I
|
||||||
|
Selective inventory.
|
||||||
|
Tells you what a single item in your pack is.
|
||||||
|
.ip q
|
||||||
|
Quaff one of the potions you are carrying.
|
||||||
|
.ip r
|
||||||
|
Read one of the scrolls in your pack.
|
||||||
|
.ip e
|
||||||
|
Eat food from your pack.
|
||||||
|
.ip w
|
||||||
|
Wield a weapon.
|
||||||
|
Take a weapon out of your pack and carry it for use in combat,
|
||||||
|
replacing the one you are currently using (if any).
|
||||||
|
.ip W
|
||||||
|
Wear armor.
|
||||||
|
You can only wear one suit of armor at a time.
|
||||||
|
This takes extra time.
|
||||||
|
.ip T
|
||||||
|
Take armor off.
|
||||||
|
You can't remove armor that is cursed.
|
||||||
|
This takes extra time.
|
||||||
|
.ip P
|
||||||
|
Put on a ring.
|
||||||
|
You can wear only two rings at a time
|
||||||
|
(one on each hand).
|
||||||
|
If you aren't wearing any rings,
|
||||||
|
this command will ask you which hand you want to wear it on,
|
||||||
|
otherwise, it will place it on the unused hand.
|
||||||
|
The program assumes that you wield your sword in your right hand.
|
||||||
|
.ip R
|
||||||
|
Remove a ring.
|
||||||
|
If you are only wearing one ring,
|
||||||
|
this command takes it off.
|
||||||
|
If you are wearing two,
|
||||||
|
it will ask you which one you wish to remove,
|
||||||
|
.ip d
|
||||||
|
Drop an object.
|
||||||
|
Take something out of your pack and leave it lying on the floor.
|
||||||
|
Only one object can occupy each space.
|
||||||
|
You cannot drop a cursed object at all
|
||||||
|
if you are wielding or wearing it.
|
||||||
|
.ip c
|
||||||
|
Call an object something.
|
||||||
|
If you have a type of object in your pack
|
||||||
|
which you wish to remember something about,
|
||||||
|
you can use the call command to give a name to that type of object.
|
||||||
|
This is usually used when you figure out what a
|
||||||
|
potion, scroll, ring, or staff is
|
||||||
|
after you pick it up,
|
||||||
|
or when you want to remember
|
||||||
|
which of those swords in your pack you were wielding.
|
||||||
|
.ip D
|
||||||
|
Print out which things you've discovered something about.
|
||||||
|
This command will ask you what type of thing you are interested in.
|
||||||
|
If you type the character for a given type of object
|
||||||
|
(\fIe.g.\fP
|
||||||
|
.Cs !
|
||||||
|
for potion)
|
||||||
|
it will tell you which kinds of that type of object you've discovered
|
||||||
|
(\fIi.e.\fP, figured out what they are).
|
||||||
|
This command works for potions, scrolls, rings, and staves and wands.
|
||||||
|
.ip o
|
||||||
|
Examine and set options.
|
||||||
|
This command is further explained in the section on options.
|
||||||
|
.ip ^R
|
||||||
|
Redraws the screen.
|
||||||
|
Useful if spurious messages or transmission errors
|
||||||
|
have messed up the display.
|
||||||
|
.ip ^P
|
||||||
|
Print last message.
|
||||||
|
Useful when a message disappears before you can read it.
|
||||||
|
This only repeats the last message
|
||||||
|
that was not a mistyped command
|
||||||
|
so that you don't loose anything by accidentally typing
|
||||||
|
the wrong character instead of ^P.
|
||||||
|
.ip \*E
|
||||||
|
Cancel a command, prefix, or count.
|
||||||
|
.ip !
|
||||||
|
Escape to a shell for some commands.
|
||||||
|
.ip Q
|
||||||
|
Quit.
|
||||||
|
Leave the game.
|
||||||
|
.ip S
|
||||||
|
Save the current game in a file.
|
||||||
|
It will ask you whether you wish to use the default save file.
|
||||||
|
.i Caveat :
|
||||||
|
Rogue won't let you start up a copy of a saved game,
|
||||||
|
and it removes the save file as soon as you start up a restored game.
|
||||||
|
This is to prevent people from saving a game just before a dangerous position
|
||||||
|
and then restarting it if they die.
|
||||||
|
To restore a saved game,
|
||||||
|
give the file name as an argument to rogue.
|
||||||
|
As in
|
||||||
|
.ti +1i
|
||||||
|
.nf
|
||||||
|
% rogue \fIsave\*_file\fP
|
||||||
|
.ip
|
||||||
|
To restart from the default save file (see below),
|
||||||
|
run
|
||||||
|
.ti +1i
|
||||||
|
.nf
|
||||||
|
% rogue \-r
|
||||||
|
.ip v
|
||||||
|
Prints the program version number.
|
||||||
|
.ip )
|
||||||
|
Print the weapon you are currently wielding
|
||||||
|
.ip ]
|
||||||
|
Print the armor you are currently wearing
|
||||||
|
.ip =
|
||||||
|
Print the rings you are currently wearing
|
||||||
|
.ip @
|
||||||
|
Reprint the status line on the message line
|
||||||
|
.sh 1 Rooms
|
||||||
|
.pp
|
||||||
|
Rooms in the dungeons are either lit or dark.
|
||||||
|
If you walk into a lit room,
|
||||||
|
the entire room will be drawn on the screen as soon as you enter.
|
||||||
|
If you walk into a dark room,
|
||||||
|
it will only be displayed as you explore it.
|
||||||
|
Upon leaving a room,
|
||||||
|
all monsters inside the room
|
||||||
|
are erased from the screen.
|
||||||
|
In the darkness you can only see one space
|
||||||
|
in all directions around you.
|
||||||
|
A corridor is always dark.
|
||||||
|
.sh 1 Fighting
|
||||||
|
.pp
|
||||||
|
If you see a monster and you wish to fight it,
|
||||||
|
just attempt to run into it.
|
||||||
|
Many times a monster you find will mind its own business
|
||||||
|
unless you attack it.
|
||||||
|
It is often the case that discretion is the better part of valor.
|
||||||
|
.sh 1 "Objects you can find"
|
||||||
|
.pp
|
||||||
|
When you find something in the dungeon,
|
||||||
|
it is common to want to pick the object up.
|
||||||
|
This is accomplished in rogue by walking over the object
|
||||||
|
(unless you use the
|
||||||
|
.Cs m
|
||||||
|
prefix, see above).
|
||||||
|
If you are carrying too many things,
|
||||||
|
the program will tell you and it won't pick up the object,
|
||||||
|
otherwise it will add it to your pack
|
||||||
|
and tell you what you just picked up.
|
||||||
|
.pp
|
||||||
|
Many of the commands that operate on objects must prompt you
|
||||||
|
to find out which object you want to use.
|
||||||
|
If you change your mind and don't want to do that command after all,
|
||||||
|
just type an \*E and the command will be aborted.
|
||||||
|
.pp
|
||||||
|
Some objects, like armor and weapons,
|
||||||
|
are easily differentiated.
|
||||||
|
Others, like scrolls and potions,
|
||||||
|
are given labels which vary according to type.
|
||||||
|
During a game,
|
||||||
|
any two of the same kind of object
|
||||||
|
with the same label
|
||||||
|
are the same type.
|
||||||
|
However,
|
||||||
|
the labels will vary from game to game.
|
||||||
|
.pp
|
||||||
|
When you use one of these labeled objects,
|
||||||
|
if its effect is obvious,
|
||||||
|
rogue will remember what it is for you.
|
||||||
|
If it's effect isn't extremely obvious
|
||||||
|
you will be asked what you want to scribble on it
|
||||||
|
so you will recognize it later,
|
||||||
|
or you can use the
|
||||||
|
.Cs call
|
||||||
|
command
|
||||||
|
(see above).
|
||||||
|
.sh 2 Weapons
|
||||||
|
.pp
|
||||||
|
Some weapons,
|
||||||
|
like arrows,
|
||||||
|
come in bunches,
|
||||||
|
but most come one at a time.
|
||||||
|
In order to use a weapon,
|
||||||
|
you must wield it.
|
||||||
|
To fire an arrow out of a bow,
|
||||||
|
you must first wield the bow,
|
||||||
|
then throw the arrow.
|
||||||
|
You can only wield one weapon at a time,
|
||||||
|
but you can't change weapons if the one
|
||||||
|
you are currently wielding is cursed.
|
||||||
|
The commands to use weapons are
|
||||||
|
.Cs w
|
||||||
|
(wield)
|
||||||
|
and
|
||||||
|
.Cs t
|
||||||
|
(throw).
|
||||||
|
.sh 2 Armor
|
||||||
|
.pp
|
||||||
|
There are various sorts of armor lying around in the dungeon.
|
||||||
|
Some of it is enchanted,
|
||||||
|
some is cursed,
|
||||||
|
and some is just normal.
|
||||||
|
Different armor types have different armor protection.
|
||||||
|
The higher the armor protection,
|
||||||
|
the more protection the armor affords against the blows of monsters.
|
||||||
|
Here is a list of the various armor types and their normal armor protection:
|
||||||
|
.(b
|
||||||
|
.TS
|
||||||
|
box center;
|
||||||
|
l r.
|
||||||
|
\ \ \fIType Protection\fP
|
||||||
|
None 0
|
||||||
|
Leather armor 2
|
||||||
|
Studded leather / Ring mail 3
|
||||||
|
Scale mail 4
|
||||||
|
Chain mail 5
|
||||||
|
Banded mail / Splint mail 6
|
||||||
|
Plate mail 7
|
||||||
|
.TE
|
||||||
|
.)b
|
||||||
|
.lp
|
||||||
|
If a piece of armor is enchanted,
|
||||||
|
its armor protection will be higher than normal.
|
||||||
|
If a suit of armor is cursed,
|
||||||
|
its armor protection will be lower,
|
||||||
|
and you will not be able to remove it.
|
||||||
|
However, not all armor with a protection that is lower than normal is cursed.
|
||||||
|
.pp
|
||||||
|
The commands to use weapons are
|
||||||
|
.Cs W
|
||||||
|
(wear)
|
||||||
|
and
|
||||||
|
.Cs T
|
||||||
|
(take off).
|
||||||
|
.sh 2 Scrolls
|
||||||
|
.pp
|
||||||
|
Scrolls come with titles in an unknown tongue\**.
|
||||||
|
.(f
|
||||||
|
\** Actually, it's a dialect spoken only by the twenty-seven members
|
||||||
|
of a tribe in Outer Mongolia,
|
||||||
|
but you're not supposed to
|
||||||
|
.i know
|
||||||
|
that.
|
||||||
|
.)f
|
||||||
|
After you read a scroll,
|
||||||
|
it disappears from your pack.
|
||||||
|
The command to use a scroll is
|
||||||
|
.Cs r
|
||||||
|
(read).
|
||||||
|
.sh 2 Potions
|
||||||
|
.pp
|
||||||
|
Potions are labeled by the color of the liquid inside the flask.
|
||||||
|
They disappear after being quaffed.
|
||||||
|
The command to use a scroll is
|
||||||
|
.Cs q
|
||||||
|
(quaff).
|
||||||
|
.sh 2 "Staves and Wands"
|
||||||
|
.pp
|
||||||
|
Staves and wands do the same kinds of things.
|
||||||
|
Staves are identified by a type of wood;
|
||||||
|
wands by a type of metal or bone.
|
||||||
|
They are generally things you want to do to something
|
||||||
|
over a long distance,
|
||||||
|
so you must point them at what you wish to affect
|
||||||
|
to use them.
|
||||||
|
Some staves are not affected by the direction they are pointed, though.
|
||||||
|
Staves come with multiple magic charges,
|
||||||
|
the number being random,
|
||||||
|
and when they are used up,
|
||||||
|
the staff is just a piece of wood or metal.
|
||||||
|
.pp
|
||||||
|
The command to use a wand or staff is
|
||||||
|
.Cs z
|
||||||
|
(zap)
|
||||||
|
.sh 2 Rings
|
||||||
|
.pp
|
||||||
|
Rings are very useful items,
|
||||||
|
since they are relatively permanent magic,
|
||||||
|
unlike the usually fleeting effects of potions, scrolls, and staves.
|
||||||
|
Of course,
|
||||||
|
the bad rings are also more powerful.
|
||||||
|
Most rings also cause you to use up food more rapidly,
|
||||||
|
the rate varying with the type of ring.
|
||||||
|
Rings are differentiated by their stone settings.
|
||||||
|
The commands to use rings are
|
||||||
|
.Cs P
|
||||||
|
(put on)
|
||||||
|
and
|
||||||
|
.Cs R
|
||||||
|
(remove).
|
||||||
|
.sh 2 Food
|
||||||
|
.pp
|
||||||
|
Food is necessary to keep you going.
|
||||||
|
If you go too long without eating you will faint,
|
||||||
|
and eventually die of starvation.
|
||||||
|
The command to use food is
|
||||||
|
.Cs e
|
||||||
|
(eat).
|
||||||
|
.sh 1 Options
|
||||||
|
.pp
|
||||||
|
Due to variations in personal tastes
|
||||||
|
and conceptions of the way rogue should do things,
|
||||||
|
there are a set of options you can set
|
||||||
|
that cause rogue to behave in various different ways.
|
||||||
|
.sh 2 "Setting the options"
|
||||||
|
.pp
|
||||||
|
There are two ways to set the options.
|
||||||
|
The first is with the
|
||||||
|
.Cs o
|
||||||
|
command of rogue;
|
||||||
|
the second is with the
|
||||||
|
.Cs ROGUEOPTS
|
||||||
|
environment variable\**.
|
||||||
|
.(f
|
||||||
|
\** On Version 6 systems,
|
||||||
|
there is no equivalent of the ROGUEOPTS feature.
|
||||||
|
.br
|
||||||
|
.)f
|
||||||
|
.br
|
||||||
|
.sh 3 "Using the `o' command"
|
||||||
|
.pp
|
||||||
|
When you type
|
||||||
|
.Cs o
|
||||||
|
in rogue,
|
||||||
|
it clears the screen
|
||||||
|
and displays the current settings for all the options.
|
||||||
|
It then places the cursor by the value of the first option
|
||||||
|
and waits for you to type.
|
||||||
|
You can type a \*R
|
||||||
|
which means to go to the next option,
|
||||||
|
a
|
||||||
|
.Cs \-
|
||||||
|
which means to go to the previous option,
|
||||||
|
an \*E
|
||||||
|
which means to return to the game,
|
||||||
|
or you can give the option a value.
|
||||||
|
For boolean options this merely involves typing
|
||||||
|
.Cs t
|
||||||
|
for true or
|
||||||
|
.Cs f
|
||||||
|
for false.
|
||||||
|
For string options,
|
||||||
|
type the new value followed by a \*R.
|
||||||
|
.sh 3 "Using the ROGUEOPTS variable"
|
||||||
|
.pp
|
||||||
|
The ROGUEOPTS variable is a string
|
||||||
|
containing a comma separated list of initial values
|
||||||
|
for the various options.
|
||||||
|
Boolean variables can be turned on by listing their name
|
||||||
|
or turned off by putting a
|
||||||
|
.Cs no
|
||||||
|
in front of the name.
|
||||||
|
Thus to set up an environment variable so that
|
||||||
|
.b jump
|
||||||
|
is on,
|
||||||
|
.b terse
|
||||||
|
is off,
|
||||||
|
and the
|
||||||
|
.b name
|
||||||
|
is set to \*(lqBlue Meanie\*(rq,
|
||||||
|
use the command
|
||||||
|
.nf
|
||||||
|
.ti +3n
|
||||||
|
% setenv ROGUEOPTS "jump,noterse,name=Blue Meanie"\**
|
||||||
|
.fi
|
||||||
|
.(f
|
||||||
|
\**
|
||||||
|
For those of you who use the Bourne shell sh (1), the commands would be
|
||||||
|
.in +3
|
||||||
|
.nf
|
||||||
|
$ ROGUEOPTS="jump,noterse,name=Blue Meanie"
|
||||||
|
$ export ROGUEOPTS
|
||||||
|
.fi
|
||||||
|
.in +0
|
||||||
|
.)f
|
||||||
|
.sh 2 "Option list"
|
||||||
|
.pp
|
||||||
|
Here is a list of the options
|
||||||
|
and an explanation of what each one is for.
|
||||||
|
The default value for each is enclosed in square brackets.
|
||||||
|
For character string options,
|
||||||
|
input over fifty characters will be ignored.
|
||||||
|
.ip "\fBterse\fP [\fI\^noterse\^\fP]"
|
||||||
|
Useful for those who are tired of the sometimes lengthy messages of rogue.
|
||||||
|
This is a useful option for playing on slow terminals,
|
||||||
|
so this option defaults to
|
||||||
|
.i terse
|
||||||
|
if you
|
||||||
|
are on a slow (1200 baud or under) terminal.
|
||||||
|
.ip "\fBjump\fP [\fI\^nojump\^\fP]"
|
||||||
|
If this option is set,
|
||||||
|
running moves will not be displayed
|
||||||
|
until you reach the end of the move.
|
||||||
|
This saves considerable cpu and display time.
|
||||||
|
This option defaults to
|
||||||
|
.i jump
|
||||||
|
if you are using a slow terminal.
|
||||||
|
.ip "\fBflush\fP [\fI\^noflush\^\fP]"
|
||||||
|
All typeahead is thrown away after each round of battle.
|
||||||
|
This is useful for those who type far ahead
|
||||||
|
and then watch in dismay as a Bat kills them.
|
||||||
|
.ip "\fBseefloor\fP [\fI\^seefloor\^\fP]"
|
||||||
|
Display the floor around you on the screen
|
||||||
|
as you move through dark rooms.
|
||||||
|
Due to the amount of characters generated,
|
||||||
|
this option defaults to
|
||||||
|
.i noseefloor
|
||||||
|
if you are using a slow terminal.
|
||||||
|
.ip "\fBpassgo\fP [\fI\^nopassgo\^\fP]"
|
||||||
|
Follow turnings in passageways.
|
||||||
|
If you run in a passage
|
||||||
|
and you run into stone or a wall,
|
||||||
|
rogue will see if it can turn to the right or left.
|
||||||
|
If it can only turn one way,
|
||||||
|
it will turn that way.
|
||||||
|
If it can turn either or neither,
|
||||||
|
it will stop.
|
||||||
|
This algorithm can sometimes lead to slightly confusing occurrences
|
||||||
|
which is why it defaults to \fInopassgo\fP.
|
||||||
|
.ip "\fBtombstone\fP [\fI\^tombstone\^\fP]"
|
||||||
|
Print out the tombstone at the end if you get killed.
|
||||||
|
This is nice but slow, so you can turn it off if you like.
|
||||||
|
.ip "\fBinven\fP [\fI\^overwrite\^\fP]"
|
||||||
|
Inventory type.
|
||||||
|
This can have one of three values:
|
||||||
|
.i overwrite ,
|
||||||
|
.i slow ,
|
||||||
|
or
|
||||||
|
.i clear .
|
||||||
|
With
|
||||||
|
.i overwrite
|
||||||
|
the top lines of the map are overwritten
|
||||||
|
with the list
|
||||||
|
when inventory is requested
|
||||||
|
or when
|
||||||
|
\*(lqWhich item do you wish to \fB. . .\fP? \*(rq questions
|
||||||
|
are answered with a
|
||||||
|
.Cs * .
|
||||||
|
However, if the list is longer than a screenful,
|
||||||
|
the screen is cleared.
|
||||||
|
With
|
||||||
|
.i slow ,
|
||||||
|
lists are displayed one item at a time on the top of the screen,
|
||||||
|
and with
|
||||||
|
.i clear ,
|
||||||
|
the screen is cleared,
|
||||||
|
the list is displayed,
|
||||||
|
and then the dungeon level is re-displayed.
|
||||||
|
Due to speed considerations,
|
||||||
|
.i clear
|
||||||
|
is the default for terminals without
|
||||||
|
clear-to-end-of-line capabilities.
|
||||||
|
.ip "\fBname\fP [account name]"
|
||||||
|
This is the name of your character.
|
||||||
|
It is used if you get on the top ten scorer's list.
|
||||||
|
.ip "\fBfruit\fP [\fI\^slime-mold\^\fP]"
|
||||||
|
This should hold the name of a fruit that you enjoy eating.
|
||||||
|
It is basically a whimsey that rogue uses in a couple of places.
|
||||||
|
.ip "\fBfile\fP [\fI\^~/rogue.save\^\fP]"
|
||||||
|
The default file name for saving the game.
|
||||||
|
If your phone is hung up by accident,
|
||||||
|
rogue will automatically save the game in this file.
|
||||||
|
The file name may start with the special character
|
||||||
|
.Cs ~
|
||||||
|
which expands to be your home directory.
|
||||||
|
.sh 1 Scoring
|
||||||
|
.pp
|
||||||
|
Rogue usually maintains a list
|
||||||
|
of the top scoring people or scores on your machine.
|
||||||
|
Depending on how it is set up,
|
||||||
|
it can post either the top scores
|
||||||
|
or the top players.
|
||||||
|
In the latter case,
|
||||||
|
each account on the machine
|
||||||
|
can post only one non-winning score on this list.
|
||||||
|
If you score higher than someone else on this list,
|
||||||
|
or better your previous score on the list,
|
||||||
|
you will be inserted in the proper place
|
||||||
|
under your current name.
|
||||||
|
How many scores are kept
|
||||||
|
can also be set up by whoever installs it on your machine.
|
||||||
|
.pp
|
||||||
|
If you quit the game, you get out with all of your gold intact.
|
||||||
|
If, however, you get killed in the Dungeons of Doom,
|
||||||
|
your body is forwarded to your next-of-kin,
|
||||||
|
along with 90% of your gold;
|
||||||
|
ten percent of your gold is kept by the Dungeons' wizard as a fee\**.
|
||||||
|
.(f
|
||||||
|
\** The Dungeon's wizard is named Wally the Wonder Badger.
|
||||||
|
Invocations should be accompanied by a sizable donation.
|
||||||
|
.)f
|
||||||
|
This should make you consider whether you want to take one last hit
|
||||||
|
at that monster and possibly live,
|
||||||
|
or quit and thus stop with whatever you have.
|
||||||
|
If you quit, you do get all your gold,
|
||||||
|
but if you swing and live, you might find more.
|
||||||
|
.pp
|
||||||
|
If you just want to see what the current top players/games list is,
|
||||||
|
you can type
|
||||||
|
.ti +1i
|
||||||
|
.nf
|
||||||
|
% @PROGRAM@ \-s
|
||||||
|
.br
|
||||||
|
.sh 1 Acknowledgements
|
||||||
|
.pp
|
||||||
|
Rogue was originally conceived of by Glenn Wichman and Michael Toy.
|
||||||
|
Ken Arnold and Michael Toy then smoothed out the user interface,
|
||||||
|
and added jillions of new features.
|
||||||
|
We would like to thank
|
||||||
|
Bob Arnold,
|
||||||
|
Michelle Busch,
|
||||||
|
Andy Hatcher,
|
||||||
|
Kipp Hickman,
|
||||||
|
Mark Horton,
|
||||||
|
Daniel Jensen,
|
||||||
|
Bill Joy,
|
||||||
|
Joe Kalash,
|
||||||
|
Steve Maurer,
|
||||||
|
Marty McNary,
|
||||||
|
Jan Miller,
|
||||||
|
and
|
||||||
|
Scott Nelson
|
||||||
|
for their ideas and assistance;
|
||||||
|
and also the teeming multitudes
|
||||||
|
who graciously ignored work, school, and social life to play rogue
|
||||||
|
and send us bugs, complaints, suggestions, and just plain flames.
|
||||||
|
And also Mom.
|
||||||
BIN
rogue5/rogue.png
Normal file
BIN
rogue5/rogue.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1,005 B |
109
rogue5/rogue.spec
Normal file
109
rogue5/rogue.spec
Normal file
|
|
@ -0,0 +1,109 @@
|
||||||
|
Name: rogue
|
||||||
|
Version: 5.4.5
|
||||||
|
Release: 1%{?dist}
|
||||||
|
Summary: The original graphical adventure game
|
||||||
|
|
||||||
|
Group: Amusements/Games
|
||||||
|
License: BSD
|
||||||
|
URL: http://rogue.rogueforge.net/
|
||||||
|
Source0: http://rogue.rogueforge.net/files/rogue5.4/rogue5.4.5-src.tar.gz
|
||||||
|
Source1: rogue.desktop
|
||||||
|
Source2: rogue.png
|
||||||
|
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||||
|
|
||||||
|
BuildRequires: desktop-file-utils
|
||||||
|
BuildRequires: ncurses-devel
|
||||||
|
|
||||||
|
%description
|
||||||
|
The one, the only, the original graphical adventure game that spawned
|
||||||
|
an entire genre.
|
||||||
|
|
||||||
|
%prep
|
||||||
|
%setup -q -n %{name}%{version}
|
||||||
|
|
||||||
|
|
||||||
|
%build
|
||||||
|
%configure --enable-setgid=games --enable-scorefile=%{_var}/games/roguelike/rogue54.scr --enable-lockfile=%{_var}/games/roguelike/rogue54.lck
|
||||||
|
make %{_smp_mflags}
|
||||||
|
|
||||||
|
|
||||||
|
%install
|
||||||
|
rm -rf $RPM_BUILD_ROOT
|
||||||
|
|
||||||
|
make install DESTDIR=$RPM_BUILD_ROOT
|
||||||
|
|
||||||
|
desktop-file-install --vendor fedora \
|
||||||
|
--dir ${RPM_BUILD_ROOT}%{_datadir}/applications \
|
||||||
|
%{SOURCE1}
|
||||||
|
mkdir -p $RPM_BUILD_ROOT/%{_datadir}/icons/hicolor/32x32/apps/
|
||||||
|
install -p -m 644 %{SOURCE2} $RPM_BUILD_ROOT/%{_datadir}/icons/hicolor/32x32/apps/
|
||||||
|
|
||||||
|
|
||||||
|
%clean
|
||||||
|
rm -rf $RPM_BUILD_ROOT
|
||||||
|
|
||||||
|
%post
|
||||||
|
touch --no-create %{_datadir}/icons/hicolor || :
|
||||||
|
if [ -x %{_bindir}/gtk-update-icon-cache ]; then
|
||||||
|
%{_bindir}/gtk-update-icon-cache --quiet %{_datadir}/icons/hicolor || :
|
||||||
|
fi
|
||||||
|
|
||||||
|
%postun
|
||||||
|
touch --no-create %{_datadir}/icons/hicolor || :
|
||||||
|
if [ -x %{_bindir}/gtk-update-icon-cache ]; then
|
||||||
|
%{_bindir}/gtk-update-icon-cache --quiet %{_datadir}/icons/hicolor || :
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
%files
|
||||||
|
%defattr(-,root,root,-)
|
||||||
|
%attr(2755,games,games) %{_bindir}/rogue
|
||||||
|
%{_mandir}/man6/rogue.6.gz
|
||||||
|
%{_datadir}/applications/fedora-%{name}.desktop
|
||||||
|
%{_datadir}/icons/hicolor/32x32/apps/rogue.png
|
||||||
|
%dir %attr(0775,games,games) %{_var}/games/roguelike
|
||||||
|
%config(noreplace) %attr(0664,games,games) %{_var}/games/roguelike/rogue54.scr
|
||||||
|
%doc %{_docdir}/%{name}-%{version}
|
||||||
|
|
||||||
|
|
||||||
|
%changelog
|
||||||
|
* Sun Aug 24 2008 yendor <yendor at roguefogre.net> 5.4.5-1
|
||||||
|
- Update to 5.4.5
|
||||||
|
* Sun Sep 2 2007 Wart <wart at kobold.org> 5.4.4-1
|
||||||
|
- Update to 5.4.4
|
||||||
|
|
||||||
|
* Mon Aug 20 2007 Wart <wart at kobold.org> 5.4.3-1
|
||||||
|
- Update to 5.4.3
|
||||||
|
|
||||||
|
* Sun Jul 15 2007 Wart <wart at kobold.org> 5.4.2-9
|
||||||
|
- New upstream home page and download URL
|
||||||
|
- Add patch when reading long values from the save file on 64-bit arch
|
||||||
|
(BZ #248283)
|
||||||
|
- Add patch removing many compiler warnings
|
||||||
|
- Use proper version in the .desktop file
|
||||||
|
|
||||||
|
* Sat Mar 3 2007 Wart <wart at kobold.org> 5.4.2-8
|
||||||
|
- Use better sourceforge download url
|
||||||
|
- Use more precise desktop file categories
|
||||||
|
|
||||||
|
* Mon Aug 28 2006 Wart <wart at kobold.org> 5.4.2-7
|
||||||
|
- Rebuild for Fedora Extras
|
||||||
|
|
||||||
|
* Tue May 16 2006 Wart <wart at kobold.org> 5.4.2-6
|
||||||
|
- Added empty initial scoreboard file.
|
||||||
|
|
||||||
|
* Mon May 15 2006 Wart <wart at kobold.org> 5.4.2-5
|
||||||
|
- Better setuid/setgid handling (again) (BZ #187392)
|
||||||
|
|
||||||
|
* Thu Mar 30 2006 Wart <wart at kobold.org> 5.4.2-4
|
||||||
|
- Better setuid/setgid handling (BZ #187392)
|
||||||
|
- Resize desktop icon to match directory name
|
||||||
|
|
||||||
|
* Mon Mar 13 2006 Wart <wart at kobold.org> 5.4.2-3
|
||||||
|
- Added icon for .desktop file.
|
||||||
|
|
||||||
|
* Sun Mar 12 2006 Wart <wart at kobold.org> 5.4.2-2
|
||||||
|
- Added missing BR: ncurses-devel, desktop-file-utils
|
||||||
|
|
||||||
|
* Sat Feb 25 2006 Wart <wart at kobold.org> 5.4.2-1
|
||||||
|
- Initial spec file.
|
||||||
21
rogue5/rogue54.sln
Normal file
21
rogue5/rogue54.sln
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||||
|
# Visual Studio 2005
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rogue54", "rogue54.vcproj", "{9EA0D326-8097-4ADA-82EA-4DB1F5CAA8F6}"
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{1C23D043-B375-4844-ACA0-32848BFCC987}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Win32 = Debug|Win32
|
||||||
|
Release|Win32 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{9EA0D326-8097-4ADA-82EA-4DB1F5CAA8F6}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{9EA0D326-8097-4ADA-82EA-4DB1F5CAA8F6}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{9EA0D326-8097-4ADA-82EA-4DB1F5CAA8F6}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{9EA0D326-8097-4ADA-82EA-4DB1F5CAA8F6}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
362
rogue5/rogue54.vcproj
Normal file
362
rogue5/rogue54.vcproj
Normal file
|
|
@ -0,0 +1,362 @@
|
||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="8.00"
|
||||||
|
Name="rogue54"
|
||||||
|
ProjectGUID="{9EA0D326-8097-4ADA-82EA-4DB1F5CAA8F6}"
|
||||||
|
Keyword="Win32Proj"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="Debug"
|
||||||
|
IntermediateDirectory="Debug"
|
||||||
|
ConfigurationType="1"
|
||||||
|
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC70.vsprops"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
InlineFunctionExpansion="0"
|
||||||
|
AdditionalIncludeDirectories="../pdcurses"
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;ALLSCORES;MASTER;SCOREFILE=\"rogue54.scr\";LOCKFILE=\"rogue54.lck\""
|
||||||
|
StringPooling="true"
|
||||||
|
MinimalRebuild="false"
|
||||||
|
ExceptionHandling="0"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
BufferSecurityCheck="true"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
DisableLanguageExtensions="false"
|
||||||
|
ForceConformanceInForLoopScope="true"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
BrowseInformation="0"
|
||||||
|
WarningLevel="4"
|
||||||
|
Detect64BitPortabilityProblems="true"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
CompileAs="1"
|
||||||
|
EnablePREfast="true"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="../pdcurses/pdcurses.lib"
|
||||||
|
OutputFile="$(OutDir)/rogue54.exe"
|
||||||
|
LinkIncremental="1"
|
||||||
|
AdditionalLibraryDirectories="..\pdcurses"
|
||||||
|
IgnoreAllDefaultLibraries="false"
|
||||||
|
IgnoreDefaultLibraryNames=""
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
ProgramDatabaseFile="$(OutDir)/rogue54.pdb"
|
||||||
|
SubSystem="1"
|
||||||
|
TargetMachine="1"
|
||||||
|
Profile="true"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebDeploymentTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="Release"
|
||||||
|
IntermediateDirectory="Release"
|
||||||
|
ConfigurationType="1"
|
||||||
|
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC70.vsprops"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
InlineFunctionExpansion="1"
|
||||||
|
OmitFramePointers="true"
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
|
||||||
|
StringPooling="true"
|
||||||
|
RuntimeLibrary="0"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
UsePrecompiledHeader="2"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="true"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
OutputFile="$(OutDir)/rogue54.exe"
|
||||||
|
LinkIncremental="1"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="2"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebDeploymentTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="Source Files"
|
||||||
|
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="armor.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="chase.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="command.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="daemon.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="daemons.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="extern.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="fight.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="init.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="io.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="list.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="mach_dep.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="main.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="mdport.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="misc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="monsters.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="move.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="new_level.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="options.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="pack.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="passages.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="potions.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="rings.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="rip.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="rooms.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="save.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="scrolls.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="state.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="sticks.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="things.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="vers.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="weapons.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="wizard.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="xcrypt.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Header Files"
|
||||||
|
Filter="h;hpp;hxx;hm;inl;inc"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="extern.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="rogue.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="score.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Resource Files"
|
||||||
|
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||||
|
>
|
||||||
|
</Filter>
|
||||||
|
<File
|
||||||
|
RelativePath="LICENSE.TXT"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
||||||
472
rogue5/rooms.c
Normal file
472
rogue5/rooms.c
Normal file
|
|
@ -0,0 +1,472 @@
|
||||||
|
/*
|
||||||
|
* Create the layout for the new level
|
||||||
|
*
|
||||||
|
* @(#)rooms.c 4.45 (Berkeley) 02/05/99
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <curses.h>
|
||||||
|
#include "rogue.h"
|
||||||
|
|
||||||
|
typedef struct spot { /* position matrix for maze positions */
|
||||||
|
int nexits;
|
||||||
|
coord exits[4];
|
||||||
|
int used;
|
||||||
|
} SPOT;
|
||||||
|
|
||||||
|
#define GOLDGRP 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* do_rooms:
|
||||||
|
* Create rooms and corridors with a connectivity graph
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
do_rooms(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct room *rp;
|
||||||
|
THING *tp;
|
||||||
|
int left_out;
|
||||||
|
coord top;
|
||||||
|
coord bsze; /* maximum room size */
|
||||||
|
coord mp;
|
||||||
|
|
||||||
|
bsze.x = NUMCOLS / 3;
|
||||||
|
bsze.y = NUMLINES / 3;
|
||||||
|
/*
|
||||||
|
* Clear things for a new level
|
||||||
|
*/
|
||||||
|
for (rp = rooms; rp < &rooms[MAXROOMS]; rp++)
|
||||||
|
{
|
||||||
|
rp->r_goldval = 0;
|
||||||
|
rp->r_nexits = 0;
|
||||||
|
rp->r_flags = 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Put the gone rooms, if any, on the level
|
||||||
|
*/
|
||||||
|
left_out = rnd(4);
|
||||||
|
for (i = 0; i < left_out; i++)
|
||||||
|
rooms[rnd_room()].r_flags |= ISGONE;
|
||||||
|
/*
|
||||||
|
* dig and populate all the rooms on the level
|
||||||
|
*/
|
||||||
|
for (i = 0, rp = rooms; i < MAXROOMS; rp++, i++)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Find upper left corner of box that this room goes in
|
||||||
|
*/
|
||||||
|
top.x = (i % 3) * bsze.x + 1;
|
||||||
|
top.y = (i / 3) * bsze.y;
|
||||||
|
if (rp->r_flags & ISGONE)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Place a gone room. Make certain that there is a blank line
|
||||||
|
* for passage drawing.
|
||||||
|
*/
|
||||||
|
do
|
||||||
|
{
|
||||||
|
rp->r_pos.x = top.x + rnd(bsze.x - 2) + 1;
|
||||||
|
rp->r_pos.y = top.y + rnd(bsze.y - 2) + 1;
|
||||||
|
rp->r_max.x = -NUMCOLS;
|
||||||
|
rp->r_max.y = -NUMLINES;
|
||||||
|
} until (rp->r_pos.y > 0 && rp->r_pos.y < NUMLINES-1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* set room type
|
||||||
|
*/
|
||||||
|
if (rnd(10) < level - 1)
|
||||||
|
{
|
||||||
|
rp->r_flags |= ISDARK; /* dark room */
|
||||||
|
if (rnd(15) == 0)
|
||||||
|
rp->r_flags = ISMAZE; /* maze room */
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Find a place and size for a random room
|
||||||
|
*/
|
||||||
|
if (rp->r_flags & ISMAZE)
|
||||||
|
{
|
||||||
|
rp->r_max.x = bsze.x - 1;
|
||||||
|
rp->r_max.y = bsze.y - 1;
|
||||||
|
if ((rp->r_pos.x = top.x) == 1)
|
||||||
|
rp->r_pos.x = 0;
|
||||||
|
if ((rp->r_pos.y = top.y) == 0)
|
||||||
|
{
|
||||||
|
rp->r_pos.y++;
|
||||||
|
rp->r_max.y--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
do
|
||||||
|
{
|
||||||
|
rp->r_max.x = rnd(bsze.x - 4) + 4;
|
||||||
|
rp->r_max.y = rnd(bsze.y - 4) + 4;
|
||||||
|
rp->r_pos.x = top.x + rnd(bsze.x - rp->r_max.x);
|
||||||
|
rp->r_pos.y = top.y + rnd(bsze.y - rp->r_max.y);
|
||||||
|
} until (rp->r_pos.y != 0);
|
||||||
|
draw_room(rp);
|
||||||
|
/*
|
||||||
|
* Put the gold in
|
||||||
|
*/
|
||||||
|
if (rnd(2) == 0 && (!amulet || level >= max_level))
|
||||||
|
{
|
||||||
|
THING *gold;
|
||||||
|
|
||||||
|
gold = new_item();
|
||||||
|
gold->o_goldval = rp->r_goldval = GOLDCALC;
|
||||||
|
find_floor(rp, &rp->r_gold, FALSE, FALSE);
|
||||||
|
gold->o_pos = rp->r_gold;
|
||||||
|
chat(rp->r_gold.y, rp->r_gold.x) = GOLD;
|
||||||
|
gold->o_flags = ISMANY;
|
||||||
|
gold->o_group = GOLDGRP;
|
||||||
|
gold->o_type = GOLD;
|
||||||
|
attach(lvl_obj, gold);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Put the monster in
|
||||||
|
*/
|
||||||
|
if (rnd(100) < (rp->r_goldval > 0 ? 80 : 25))
|
||||||
|
{
|
||||||
|
tp = new_item();
|
||||||
|
find_floor(rp, &mp, FALSE, TRUE);
|
||||||
|
new_monster(tp, randmonster(FALSE), &mp);
|
||||||
|
give_pack(tp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* draw_room:
|
||||||
|
* Draw a box around a room and lay down the floor for normal
|
||||||
|
* rooms; for maze rooms, draw maze.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
draw_room(const struct room *rp)
|
||||||
|
{
|
||||||
|
int y, x;
|
||||||
|
|
||||||
|
if (rp->r_flags & ISMAZE)
|
||||||
|
do_maze(rp);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vert(rp, rp->r_pos.x); /* Draw left side */
|
||||||
|
vert(rp, rp->r_pos.x + rp->r_max.x - 1); /* Draw right side */
|
||||||
|
horiz(rp, rp->r_pos.y); /* Draw top */
|
||||||
|
horiz(rp, rp->r_pos.y + rp->r_max.y - 1); /* Draw bottom */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Put the floor down
|
||||||
|
*/
|
||||||
|
for (y = rp->r_pos.y + 1; y < rp->r_pos.y + rp->r_max.y - 1; y++)
|
||||||
|
for (x = rp->r_pos.x + 1; x < rp->r_pos.x + rp->r_max.x - 1; x++)
|
||||||
|
chat(y, x) = FLOOR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* vert:
|
||||||
|
* Draw a vertical line
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
vert(const struct room *rp, int startx)
|
||||||
|
{
|
||||||
|
int y;
|
||||||
|
|
||||||
|
for (y = rp->r_pos.y + 1; y <= rp->r_max.y + rp->r_pos.y - 1; y++)
|
||||||
|
chat(y, startx) = '|';
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* horiz:
|
||||||
|
* Draw a horizontal line
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
horiz(const struct room *rp, int starty)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
|
||||||
|
for (x = rp->r_pos.x; x <= rp->r_pos.x + rp->r_max.x - 1; x++)
|
||||||
|
chat(starty, x) = '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* do_maze:
|
||||||
|
* Dig a maze
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int Maxy, Maxx, Starty, Startx;
|
||||||
|
|
||||||
|
static SPOT maze[NUMLINES/3+1][NUMCOLS/3+1];
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
do_maze(const struct room *rp)
|
||||||
|
{
|
||||||
|
SPOT *sp;
|
||||||
|
int starty, startx;
|
||||||
|
coord pos;
|
||||||
|
|
||||||
|
for (sp = &maze[0][0]; sp <= &maze[NUMLINES / 3][NUMCOLS / 3]; sp++)
|
||||||
|
{
|
||||||
|
sp->used = FALSE;
|
||||||
|
sp->nexits = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Maxy = rp->r_max.y;
|
||||||
|
Maxx = rp->r_max.x;
|
||||||
|
Starty = rp->r_pos.y;
|
||||||
|
Startx = rp->r_pos.x;
|
||||||
|
starty = (rnd(rp->r_max.y) / 2) * 2;
|
||||||
|
startx = (rnd(rp->r_max.x) / 2) * 2;
|
||||||
|
pos.y = starty + Starty;
|
||||||
|
pos.x = startx + Startx;
|
||||||
|
putpass(&pos);
|
||||||
|
dig(starty, startx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dig:
|
||||||
|
* Dig out from around where we are now, if possible
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dig(int y, int x)
|
||||||
|
{
|
||||||
|
coord *cp;
|
||||||
|
int cnt, newy, newx, nexty = 0, nextx = 0;
|
||||||
|
coord pos;
|
||||||
|
coord del[4] = {
|
||||||
|
{2, 0}, {-2, 0}, {0, 2}, {0, -2}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
cnt = 0;
|
||||||
|
for (cp = del; cp <= &del[3]; cp++)
|
||||||
|
{
|
||||||
|
newy = y + cp->y;
|
||||||
|
newx = x + cp->x;
|
||||||
|
if (newy < 0 || newy > Maxy || newx < 0 || newx > Maxx)
|
||||||
|
continue;
|
||||||
|
if (flat(newy + Starty, newx + Startx) & F_PASS)
|
||||||
|
continue;
|
||||||
|
if (rnd(++cnt) == 0)
|
||||||
|
{
|
||||||
|
nexty = newy;
|
||||||
|
nextx = newx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cnt == 0)
|
||||||
|
return;
|
||||||
|
accnt_maze(y, x, nexty, nextx);
|
||||||
|
accnt_maze(nexty, nextx, y, x);
|
||||||
|
if (nexty == y)
|
||||||
|
{
|
||||||
|
pos.y = y + Starty;
|
||||||
|
if (nextx - x < 0)
|
||||||
|
pos.x = nextx + Startx + 1;
|
||||||
|
else
|
||||||
|
pos.x = nextx + Startx - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pos.x = x + Startx;
|
||||||
|
if (nexty - y < 0)
|
||||||
|
pos.y = nexty + Starty + 1;
|
||||||
|
else
|
||||||
|
pos.y = nexty + Starty - 1;
|
||||||
|
}
|
||||||
|
putpass(&pos);
|
||||||
|
pos.y = nexty + Starty;
|
||||||
|
pos.x = nextx + Startx;
|
||||||
|
putpass(&pos);
|
||||||
|
dig(nexty, nextx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* accnt_maze:
|
||||||
|
* Account for maze exits
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
accnt_maze(int y, int x, int ny, int nx)
|
||||||
|
{
|
||||||
|
SPOT *sp;
|
||||||
|
coord *cp;
|
||||||
|
|
||||||
|
sp = &maze[y][x];
|
||||||
|
for (cp = sp->exits; cp < &sp->exits[sp->nexits]; cp++)
|
||||||
|
if (cp->y == ny && cp->x == nx)
|
||||||
|
return;
|
||||||
|
cp->y = ny;
|
||||||
|
cp->x = nx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rnd_pos:
|
||||||
|
* Pick a random spot in a room
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
rnd_pos(const struct room *rp, coord *cp)
|
||||||
|
{
|
||||||
|
cp->x = rp->r_pos.x + rnd(rp->r_max.x - 2) + 1;
|
||||||
|
cp->y = rp->r_pos.y + rnd(rp->r_max.y - 2) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* find_floor:
|
||||||
|
* Find a valid floor spot in this room. If rp is NULL, then
|
||||||
|
* pick a new room each time around the loop.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
find_floor(const struct room *rp, coord *cp, int limit, int monst)
|
||||||
|
{
|
||||||
|
PLACE *pp;
|
||||||
|
int cnt;
|
||||||
|
int compchar = 0;
|
||||||
|
int pickroom;
|
||||||
|
|
||||||
|
pickroom = (rp == NULL);
|
||||||
|
|
||||||
|
if (!pickroom)
|
||||||
|
compchar = ((rp->r_flags & ISMAZE) ? PASSAGE : FLOOR);
|
||||||
|
cnt = limit;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (limit && cnt-- == 0)
|
||||||
|
return FALSE;
|
||||||
|
if (pickroom)
|
||||||
|
{
|
||||||
|
rp = &rooms[rnd_room()];
|
||||||
|
compchar = ((rp->r_flags & ISMAZE) ? PASSAGE : FLOOR);
|
||||||
|
}
|
||||||
|
rnd_pos(rp, cp);
|
||||||
|
pp = INDEX(cp->y, cp->x);
|
||||||
|
if (monst)
|
||||||
|
{
|
||||||
|
if (pp->p_monst == NULL && step_ok(pp->p_ch))
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else if (pp->p_ch == compchar)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* enter_room:
|
||||||
|
* Code that is executed whenver you appear in a room
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
enter_room(const coord *cp)
|
||||||
|
{
|
||||||
|
struct room *rp;
|
||||||
|
THING *tp;
|
||||||
|
int y, x;
|
||||||
|
chtype ch;
|
||||||
|
|
||||||
|
rp = proom = roomin(cp);
|
||||||
|
door_open(rp);
|
||||||
|
if (!(rp->r_flags & ISDARK) && !on(player, ISBLIND))
|
||||||
|
for (y = rp->r_pos.y; y < rp->r_max.y + rp->r_pos.y; y++)
|
||||||
|
{
|
||||||
|
move(y, rp->r_pos.x);
|
||||||
|
for (x = rp->r_pos.x; x < rp->r_max.x + rp->r_pos.x; x++)
|
||||||
|
{
|
||||||
|
tp = moat(y, x);
|
||||||
|
ch = chat(y, x);
|
||||||
|
if (tp == NULL)
|
||||||
|
if (CCHAR(inch()) != ch)
|
||||||
|
addch(ch);
|
||||||
|
else
|
||||||
|
move(y, x + 1);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tp->t_oldch = ch;
|
||||||
|
if (!see_monst(tp))
|
||||||
|
if (on(player, SEEMONST))
|
||||||
|
{
|
||||||
|
standout();
|
||||||
|
addch(tp->t_disguise);
|
||||||
|
standend();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
addch(ch);
|
||||||
|
else
|
||||||
|
addch(tp->t_disguise);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* leave_room:
|
||||||
|
* Code for when we exit a room
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
leave_room(const coord *cp)
|
||||||
|
{
|
||||||
|
PLACE *pp;
|
||||||
|
struct room *rp;
|
||||||
|
int y, x;
|
||||||
|
int floor;
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
rp = proom;
|
||||||
|
|
||||||
|
if (rp->r_flags & ISMAZE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (rp->r_flags & ISGONE)
|
||||||
|
floor = PASSAGE;
|
||||||
|
else if (!(rp->r_flags & ISDARK) || on(player, ISBLIND))
|
||||||
|
floor = FLOOR;
|
||||||
|
else
|
||||||
|
floor = ' ';
|
||||||
|
|
||||||
|
proom = &passages[flat(cp->y, cp->x) & F_PNUM];
|
||||||
|
for (y = rp->r_pos.y; y < rp->r_max.y + rp->r_pos.y; y++)
|
||||||
|
for (x = rp->r_pos.x; x < rp->r_max.x + rp->r_pos.x; x++)
|
||||||
|
{
|
||||||
|
move(y, x);
|
||||||
|
switch ( ch = CCHAR(inch()) )
|
||||||
|
{
|
||||||
|
case FLOOR:
|
||||||
|
if (floor == ' ' && ch != ' ')
|
||||||
|
addch(' ');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/*
|
||||||
|
* to check for monster, we have to strip out
|
||||||
|
* standout bit
|
||||||
|
*/
|
||||||
|
if (isupper(toascii(ch)))
|
||||||
|
{
|
||||||
|
if (on(player, SEEMONST))
|
||||||
|
{
|
||||||
|
standout();
|
||||||
|
addch(ch);
|
||||||
|
standend();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pp = INDEX(y,x);
|
||||||
|
addch(pp->p_ch == DOOR ? DOOR : floor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
door_open(rp);
|
||||||
|
}
|
||||||
423
rogue5/save.c
Normal file
423
rogue5/save.c
Normal file
|
|
@ -0,0 +1,423 @@
|
||||||
|
/*
|
||||||
|
* save and restore routines
|
||||||
|
*
|
||||||
|
* @(#)save.c 4.33 (Berkeley) 06/01/83
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <curses.h>
|
||||||
|
#include "rogue.h"
|
||||||
|
#include "score.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* save_game:
|
||||||
|
* Implement the "save game" command
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
save_game(void)
|
||||||
|
{
|
||||||
|
FILE *savef;
|
||||||
|
int c;
|
||||||
|
char buf[MAXSTR];
|
||||||
|
struct stat sbuf;
|
||||||
|
/*
|
||||||
|
* get file name
|
||||||
|
*/
|
||||||
|
mpos = 0;
|
||||||
|
over:
|
||||||
|
if (file_name[0] != '\0')
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
msg("save file (%s)? ", file_name);
|
||||||
|
c = readchar();
|
||||||
|
mpos = 0;
|
||||||
|
if (c == ESCAPE)
|
||||||
|
{
|
||||||
|
msg("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (c == 'n' || c == 'N' || c == 'y' || c == 'Y')
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
msg("please answer Y or N");
|
||||||
|
}
|
||||||
|
if (c == 'y' || c == 'Y')
|
||||||
|
{
|
||||||
|
addstr("Yes\n");
|
||||||
|
refresh();
|
||||||
|
strcpy(buf, file_name);
|
||||||
|
goto gotfile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
mpos = 0;
|
||||||
|
msg("file name: ");
|
||||||
|
buf[0] = '\0';
|
||||||
|
if (get_str(buf, stdscr) == QUIT)
|
||||||
|
{
|
||||||
|
quit_it:
|
||||||
|
msg("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mpos = 0;
|
||||||
|
gotfile:
|
||||||
|
/*
|
||||||
|
* test to see if the file exists
|
||||||
|
*/
|
||||||
|
if (stat(buf, &sbuf) >= 0)
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
msg("File exists. Do you wish to overwrite it?");
|
||||||
|
mpos = 0;
|
||||||
|
if ((c = readchar()) == ESCAPE)
|
||||||
|
goto quit_it;
|
||||||
|
if (c == 'y' || c == 'Y')
|
||||||
|
break;
|
||||||
|
else if (c == 'n' || c == 'N')
|
||||||
|
goto over;
|
||||||
|
else
|
||||||
|
msg("Please answer Y or N");
|
||||||
|
}
|
||||||
|
msg("file name: %s", buf);
|
||||||
|
md_unlink(file_name);
|
||||||
|
}
|
||||||
|
strcpy(file_name, buf);
|
||||||
|
if ((savef = fopen(file_name, "w")) == NULL)
|
||||||
|
msg(strerror(errno));
|
||||||
|
} while (savef == NULL);
|
||||||
|
msg("");
|
||||||
|
save_file(savef);
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* auto_save:
|
||||||
|
* Automatically save a file. This is used if a HUP signal is
|
||||||
|
* recieved
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
auto_save(int sig)
|
||||||
|
{
|
||||||
|
FILE *savef;
|
||||||
|
NOOP(sig);
|
||||||
|
|
||||||
|
md_ignoreallsignals();
|
||||||
|
if (file_name[0] != '\0' && ((savef = fopen(file_name, "w")) != NULL ||
|
||||||
|
(md_unlink_open_file(file_name, savef) >= 0 && (savef = fopen(file_name, "w")) != NULL)))
|
||||||
|
save_file(savef);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* save_file:
|
||||||
|
* Write the saved game on the file
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
save_file(FILE *savef)
|
||||||
|
{
|
||||||
|
char buf[80];
|
||||||
|
mvcur(0, COLS - 1, LINES - 1, 0);
|
||||||
|
putchar('\n');
|
||||||
|
endwin();
|
||||||
|
resetltchars();
|
||||||
|
md_chmod(file_name, 0400);
|
||||||
|
encwrite(version, strlen(version)+1, savef);
|
||||||
|
sprintf(buf,"%d x %d\n", LINES, COLS);
|
||||||
|
encwrite(buf,80,savef);
|
||||||
|
rs_save_file(savef);
|
||||||
|
fflush(savef);
|
||||||
|
fclose(savef);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* restore:
|
||||||
|
* Restore a saved game from a file with elaborate checks for file
|
||||||
|
* integrity from cheaters
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
restore(const char *file)
|
||||||
|
{
|
||||||
|
FILE *inf;
|
||||||
|
int syml;
|
||||||
|
char buf[MAXSTR];
|
||||||
|
struct stat sbuf2;
|
||||||
|
int lines, cols;
|
||||||
|
|
||||||
|
if (strcmp(file, "-r") == 0)
|
||||||
|
file = file_name;
|
||||||
|
|
||||||
|
md_tstphold();
|
||||||
|
|
||||||
|
if ((inf = fopen(file,"r")) == NULL)
|
||||||
|
{
|
||||||
|
perror(file);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
stat(file, &sbuf2);
|
||||||
|
syml = is_symlink(file);
|
||||||
|
|
||||||
|
fflush(stdout);
|
||||||
|
encread(buf, strlen(version) + 1, inf);
|
||||||
|
if (strcmp(buf, version) != 0)
|
||||||
|
{
|
||||||
|
printf("Sorry, saved game is out of date.\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
encread(buf,80,inf);
|
||||||
|
(void) sscanf(buf,"%d x %d\n", &lines, &cols);
|
||||||
|
|
||||||
|
initscr(); /* Start up cursor package */
|
||||||
|
keypad(stdscr, 1);
|
||||||
|
|
||||||
|
if (lines > LINES)
|
||||||
|
{
|
||||||
|
endwin();
|
||||||
|
printf("Sorry, original game was played on a screen with %d lines.\n",lines);
|
||||||
|
printf("Current screen only has %d lines. Unable to restore game\n",LINES);
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
|
if (cols > COLS)
|
||||||
|
{
|
||||||
|
endwin();
|
||||||
|
printf("Sorry, original game was played on a screen with %d columns.\n",cols);
|
||||||
|
printf("Current screen only has %d columns. Unable to restore game\n",COLS);
|
||||||
|
return(FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
hw = newwin(LINES, COLS, 0, 0);
|
||||||
|
setup();
|
||||||
|
|
||||||
|
rs_restore_file(inf);
|
||||||
|
/*
|
||||||
|
* we do not close the file so that we will have a hold of the
|
||||||
|
* inode for as long as possible
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (
|
||||||
|
#ifdef MASTER
|
||||||
|
!wizard &&
|
||||||
|
#endif
|
||||||
|
md_unlink_open_file(file, inf) < 0)
|
||||||
|
{
|
||||||
|
printf("Cannot unlink file\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
mpos = 0;
|
||||||
|
/* printw(0, 0, "%s: %s", file, ctime(&sbuf2.st_mtime)); */
|
||||||
|
/*
|
||||||
|
printw("%s: %s", file, ctime(&sbuf2.st_mtime));
|
||||||
|
*/
|
||||||
|
clearok(stdscr,TRUE);
|
||||||
|
/*
|
||||||
|
* defeat multiple restarting from the same place
|
||||||
|
*/
|
||||||
|
#ifdef MASTER
|
||||||
|
if (!wizard)
|
||||||
|
#endif
|
||||||
|
if (sbuf2.st_nlink != 1 || syml)
|
||||||
|
{
|
||||||
|
endwin();
|
||||||
|
printf("\nCannot restore from a linked file\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pstats.s_hpt <= 0)
|
||||||
|
{
|
||||||
|
endwin();
|
||||||
|
printf("\n\"He's dead, Jim\"\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
md_tstpresume();
|
||||||
|
|
||||||
|
strcpy(file_name, file);
|
||||||
|
clearok(curscr, TRUE);
|
||||||
|
srand(md_getpid());
|
||||||
|
msg("file name: %s", file);
|
||||||
|
playit();
|
||||||
|
/*NOTREACHED*/
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int encerrno = 0;
|
||||||
|
|
||||||
|
int
|
||||||
|
encerror()
|
||||||
|
{
|
||||||
|
return encerrno;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
encseterr(int err)
|
||||||
|
{
|
||||||
|
encerrno = err;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
encclearerr()
|
||||||
|
{
|
||||||
|
int n = encerrno;
|
||||||
|
|
||||||
|
encerrno = 0;
|
||||||
|
|
||||||
|
return(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* encwrite:
|
||||||
|
* Perform an encrypted write
|
||||||
|
*/
|
||||||
|
|
||||||
|
size_t
|
||||||
|
encwrite(const char *start, size_t size, FILE *outf)
|
||||||
|
{
|
||||||
|
const char *e1, *e2;
|
||||||
|
char fb;
|
||||||
|
int temp;
|
||||||
|
size_t o_size = size;
|
||||||
|
e1 = encstr;
|
||||||
|
e2 = statlist;
|
||||||
|
fb = 0;
|
||||||
|
|
||||||
|
if (encerrno) {
|
||||||
|
errno = encerrno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(size)
|
||||||
|
{
|
||||||
|
if (putc(*start++ ^ *e1 ^ *e2 ^ fb, outf) == EOF)
|
||||||
|
{
|
||||||
|
encerrno = errno;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
temp = *e1++;
|
||||||
|
fb = fb + ((char) (temp * *e2++));
|
||||||
|
if (*e1 == '\0')
|
||||||
|
e1 = encstr;
|
||||||
|
if (*e2 == '\0')
|
||||||
|
e2 = statlist;
|
||||||
|
size--;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(o_size - size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* encread:
|
||||||
|
* Perform an encrypted read
|
||||||
|
*/
|
||||||
|
size_t
|
||||||
|
encread(char *start, size_t size, FILE *inf)
|
||||||
|
{
|
||||||
|
const char *e1, *e2;
|
||||||
|
char fb;
|
||||||
|
int temp;
|
||||||
|
size_t read_size;
|
||||||
|
size_t items;
|
||||||
|
fb = 0;
|
||||||
|
|
||||||
|
if (encerrno) {
|
||||||
|
errno = encerrno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
items = read_size = fread(start,1,size,inf);
|
||||||
|
|
||||||
|
e1 = encstr;
|
||||||
|
e2 = statlist;
|
||||||
|
|
||||||
|
while (read_size--)
|
||||||
|
{
|
||||||
|
*start++ ^= *e1 ^ *e2 ^ fb;
|
||||||
|
temp = *e1++;
|
||||||
|
fb = fb + (char)(temp * *e2++);
|
||||||
|
if (*e1 == '\0')
|
||||||
|
e1 = encstr;
|
||||||
|
if (*e2 == '\0')
|
||||||
|
e2 = statlist;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (items != size)
|
||||||
|
encerrno = errno;
|
||||||
|
|
||||||
|
return(items);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read_scrore
|
||||||
|
* Read in the score file
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
rd_score(SCORE *top_ten)
|
||||||
|
{
|
||||||
|
char scoreline[100];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (scoreboard == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
rewind(scoreboard);
|
||||||
|
|
||||||
|
for(i = 0; i < numscores; i++)
|
||||||
|
{
|
||||||
|
encread(top_ten[i].sc_name, MAXSTR, scoreboard);
|
||||||
|
scoreline[0] = '\0';
|
||||||
|
encread(scoreline, 100, scoreboard);
|
||||||
|
(void) sscanf(scoreline, " %u %d %u %d %d %x \n",
|
||||||
|
&top_ten[i].sc_uid, &top_ten[i].sc_score,
|
||||||
|
&top_ten[i].sc_flags, &top_ten[i].sc_monster,
|
||||||
|
&top_ten[i].sc_level, &top_ten[i].sc_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
rewind(scoreboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* write_scrore
|
||||||
|
* Read in the score file
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
wr_score(SCORE *top_ten)
|
||||||
|
{
|
||||||
|
char scoreline[100];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (scoreboard == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
rewind(scoreboard);
|
||||||
|
|
||||||
|
for(i = 0; i < numscores; i++)
|
||||||
|
{
|
||||||
|
memset(scoreline,0,100);
|
||||||
|
encwrite(top_ten[i].sc_name, MAXSTR, scoreboard);
|
||||||
|
sprintf(scoreline, " %u %d %u %u %d %x \n",
|
||||||
|
top_ten[i].sc_uid, top_ten[i].sc_score,
|
||||||
|
top_ten[i].sc_flags, top_ten[i].sc_monster,
|
||||||
|
top_ten[i].sc_level, top_ten[i].sc_time);
|
||||||
|
encwrite(scoreline,100,scoreboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
rewind(scoreboard);
|
||||||
|
}
|
||||||
298
rogue5/scedit.c
Normal file
298
rogue5/scedit.c
Normal file
|
|
@ -0,0 +1,298 @@
|
||||||
|
/*
|
||||||
|
* score editor
|
||||||
|
*
|
||||||
|
* @(#)score.c 4.6 (Berkeley) 02/05/99
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
# include <curses.h>
|
||||||
|
# include <stdio.h>
|
||||||
|
# include <signal.h>
|
||||||
|
# include <ctype.h>
|
||||||
|
|
||||||
|
#ifndef TRUE
|
||||||
|
# define TRUE 1
|
||||||
|
#endif
|
||||||
|
# define FALSE 0
|
||||||
|
# define RN (((seed = seed*11109+13849) >> 16) & 0xffff)
|
||||||
|
|
||||||
|
# define MAXSTR 80
|
||||||
|
|
||||||
|
# include "score.h"
|
||||||
|
|
||||||
|
SCORE top_ten[10];
|
||||||
|
|
||||||
|
char buf[BUFSIZ],
|
||||||
|
*reason[] = {
|
||||||
|
"killed",
|
||||||
|
"quit",
|
||||||
|
"A total winner",
|
||||||
|
"killed with amulet",
|
||||||
|
};
|
||||||
|
|
||||||
|
int seed;
|
||||||
|
FILE *inf;
|
||||||
|
|
||||||
|
struct passwd *getpwnam();
|
||||||
|
int do_comm();
|
||||||
|
int pr_score(SCORE *, int);
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int ac, char *av[])
|
||||||
|
{
|
||||||
|
char *scorefile;
|
||||||
|
FILE *outf;
|
||||||
|
|
||||||
|
if (ac == 1)
|
||||||
|
scorefile = "rogue54.scr";
|
||||||
|
else
|
||||||
|
scorefile = av[1];
|
||||||
|
seed = md_getpid();
|
||||||
|
|
||||||
|
if ((inf = fopen(scorefile, "r+")) < 0) {
|
||||||
|
perror(scorefile);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
s_encread((char *) top_ten, sizeof top_ten, inf);
|
||||||
|
|
||||||
|
while (do_comm())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* do_comm:
|
||||||
|
* Get and execute a command
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
do_comm(void)
|
||||||
|
{
|
||||||
|
char *sp;
|
||||||
|
SCORE *scp;
|
||||||
|
struct passwd *pp;
|
||||||
|
static FILE *outf = NULL;
|
||||||
|
static int written = TRUE;
|
||||||
|
|
||||||
|
printf("\nCommand: ");
|
||||||
|
while (isspace(buf[0] = getchar()) || buf[0] == '\n')
|
||||||
|
continue;
|
||||||
|
(void) fget(s&buf[1], BUFSIZ, stdin);
|
||||||
|
buf[strlen(buf) - 1] = '\0';
|
||||||
|
switch (buf[0]) {
|
||||||
|
case 'w':
|
||||||
|
if (strncmp(buf, "write", strlen(buf)))
|
||||||
|
goto def;
|
||||||
|
lseek(inf, 0L, 0);
|
||||||
|
if (outf == NULL && (outf = fdopen(inf, "w")) == NULL) {
|
||||||
|
perror("fdopen");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
fseek(outf, 0L, 0);
|
||||||
|
if (s_lock_sc())
|
||||||
|
{
|
||||||
|
void (*fp)(int);
|
||||||
|
|
||||||
|
fp = signal(SIGINT, SIG_IGN);
|
||||||
|
s_encwrite((char *) top_ten, sizeof top_ten, outf);
|
||||||
|
s_unlock_sc();
|
||||||
|
signal(SIGINT, fp);
|
||||||
|
written = TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'a':
|
||||||
|
if (strncmp(buf, "add", strlen(buf)))
|
||||||
|
goto def;
|
||||||
|
add_score();
|
||||||
|
written = FALSE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'd':
|
||||||
|
if (strncmp(buf, "delete", strlen(buf)))
|
||||||
|
goto def;
|
||||||
|
del_score();
|
||||||
|
written = FALSE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'p':
|
||||||
|
if (strncmp(buf, "print", strlen(buf)))
|
||||||
|
goto def;
|
||||||
|
printf("\nTop Ten Rogueists:\nRank\tScore\tName\n");
|
||||||
|
for (scp = top_ten; scp < &top_ten[10]; scp++)
|
||||||
|
if (!pr_score(scp, TRUE))
|
||||||
|
break;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'q':
|
||||||
|
if (strncmp(buf, "quit", strlen(buf)))
|
||||||
|
goto def;
|
||||||
|
if (!written) {
|
||||||
|
printf("No write\n");
|
||||||
|
written = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
def:
|
||||||
|
printf("Unkown command: \"%s\"\n", buf);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* add_score:
|
||||||
|
* Add a score to the score file
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
add_score(void)
|
||||||
|
{
|
||||||
|
SCORE *scp;
|
||||||
|
uid_t id = 0;
|
||||||
|
int i;
|
||||||
|
SCORE new;
|
||||||
|
|
||||||
|
printf("Name: ");
|
||||||
|
(void) fgets(new.sc_name, MAXSTR, stdin);
|
||||||
|
new.sc_name[strlen(new.sc_name) - 1] = '\0';
|
||||||
|
do {
|
||||||
|
printf("reason: ");
|
||||||
|
if ((new.sc_flags = getchar()) < '0' || new.sc_flags > '2') {
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
printf("%d: %s\n", i, reason[i]);
|
||||||
|
ungetc(new.sc_flags, stdin);
|
||||||
|
}
|
||||||
|
while (getchar() != '\n')
|
||||||
|
continue;
|
||||||
|
} while (new.sc_flags < '0' || new.sc_flags > '2');
|
||||||
|
new.sc_flags -= '0';
|
||||||
|
do {
|
||||||
|
printf("User Id: ");
|
||||||
|
(void) fgets(buf, BUFSIZ, stdin);
|
||||||
|
buf[strlen(buf) - 1] = '\0';
|
||||||
|
id = atoi(buf);
|
||||||
|
} while (id == -1);
|
||||||
|
new.sc_uid = id;
|
||||||
|
do {
|
||||||
|
printf("Monster: ");
|
||||||
|
if (!isalpha(new.sc_monster = getchar())) {
|
||||||
|
printf("type A-Za-z [%s]\n", unctrl(new.sc_monster));
|
||||||
|
ungetc(new.sc_monster, stdin);
|
||||||
|
}
|
||||||
|
while (getchar() != '\n')
|
||||||
|
continue;
|
||||||
|
} while (!isalpha(new.sc_monster));
|
||||||
|
printf("Score: ");
|
||||||
|
scanf("%d", &new.sc_score);
|
||||||
|
printf("level: ");
|
||||||
|
scanf("%d", &new.sc_level);
|
||||||
|
while (getchar() != '\n')
|
||||||
|
continue;
|
||||||
|
pr_score(&new, FALSE);
|
||||||
|
printf("Really add it? ");
|
||||||
|
if (getchar() != 'y')
|
||||||
|
return;
|
||||||
|
while (getchar() != '\n')
|
||||||
|
continue;
|
||||||
|
insert_score(&new);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pr_score:
|
||||||
|
* Print out a score entry. Return FALSE if last entry.
|
||||||
|
*/
|
||||||
|
|
||||||
|
pr_score(SCORE *scp, int num)
|
||||||
|
{
|
||||||
|
if (scp->sc_score) {
|
||||||
|
if (num)
|
||||||
|
printf("%d", scp - top_ten + 1);
|
||||||
|
printf("\t%d\t%s: %s on level %d", scp->sc_score, scp->sc_name,
|
||||||
|
reason[scp->sc_flags], scp->sc_level);
|
||||||
|
if (scp->sc_flags == 0)
|
||||||
|
printf(" by %s", s_killname(scp->sc_monster, TRUE));
|
||||||
|
|
||||||
|
printf(" (%s)", md_getrealname(scp->sc_uid));
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
|
return scp->sc_score;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* insert_score:
|
||||||
|
* Insert a score into the top ten list
|
||||||
|
*/
|
||||||
|
|
||||||
|
insert_score(SCORE *new)
|
||||||
|
{
|
||||||
|
SCORE *scp, *sc2;
|
||||||
|
int flags, amount;
|
||||||
|
uid_t uid;
|
||||||
|
|
||||||
|
flags = new->sc_flags;
|
||||||
|
uid = new->sc_uid;
|
||||||
|
amount = new->sc_score;
|
||||||
|
|
||||||
|
for (scp = top_ten; scp < &top_ten[10]; scp++)
|
||||||
|
if (amount > scp->sc_score)
|
||||||
|
break;
|
||||||
|
else if (flags != 2 && scp->sc_uid == uid && scp->sc_flags != 2)
|
||||||
|
scp = &top_ten[10];
|
||||||
|
if (scp < &top_ten[10]) {
|
||||||
|
if (flags != 2)
|
||||||
|
for (sc2 = scp; sc2 < &top_ten[10]; sc2++) {
|
||||||
|
if (sc2->sc_uid == uid && sc2->sc_flags != 2)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sc2 = &top_ten[9];
|
||||||
|
while (sc2 > scp) {
|
||||||
|
*sc2 = sc2[-1];
|
||||||
|
sc2--;
|
||||||
|
}
|
||||||
|
*scp = *new;
|
||||||
|
sc2 = scp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* del_score:
|
||||||
|
* Delete a score from the score list.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
del_score(void)
|
||||||
|
{
|
||||||
|
SCORE *scp;
|
||||||
|
int i;
|
||||||
|
int num;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
printf("Which score? ");
|
||||||
|
(void) fgets(buf, BUFSIZ, stdin);
|
||||||
|
if (buf[0] == '\n')
|
||||||
|
return;
|
||||||
|
sscanf(buf, "%d", &num);
|
||||||
|
if (num < 1 || num > 10)
|
||||||
|
printf("range is 1-10\n");
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
num--;
|
||||||
|
for (scp = &top_ten[num]; scp < &top_ten[9]; scp++)
|
||||||
|
*scp = scp[1];
|
||||||
|
top_ten[9].sc_score = 0;
|
||||||
|
for (i = 0; i < MAXSTR; i++)
|
||||||
|
top_ten[9].sc_name[i] = RN;
|
||||||
|
top_ten[9].sc_flags = RN;
|
||||||
|
top_ten[9].sc_level = RN;
|
||||||
|
top_ten[9].sc_monster = RN;
|
||||||
|
top_ten[9].sc_uid = RN;
|
||||||
|
}
|
||||||
231
rogue5/scmisc.c
Normal file
231
rogue5/scmisc.c
Normal file
|
|
@ -0,0 +1,231 @@
|
||||||
|
/*
|
||||||
|
* copies of several routines needed for score
|
||||||
|
*
|
||||||
|
* @(#)smisc.c 4.7 (Berkeley) 02/05/99
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
# include <stdio.h>
|
||||||
|
# include <sys/types.h>
|
||||||
|
# include <sys/stat.h>
|
||||||
|
# include <ctype.h>
|
||||||
|
|
||||||
|
# define TRUE 1
|
||||||
|
# define FALSE 0
|
||||||
|
# define MAXSTR 80
|
||||||
|
# define when break;case
|
||||||
|
# define otherwise break;default
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *m_name;
|
||||||
|
} MONST;
|
||||||
|
|
||||||
|
char *s_vowelstr();
|
||||||
|
|
||||||
|
char *lockfile = "/tmp/.fredlock";
|
||||||
|
|
||||||
|
char prbuf[MAXSTR]; /* buffer for sprintfs */
|
||||||
|
|
||||||
|
MONST monsters[] = {
|
||||||
|
{ "aquator" }, { "bat" }, { "centaur" }, { "dragon" }, { "emu" },
|
||||||
|
{ "venus flytrap" }, { "griffin" }, { "hobgoblin" }, { "ice monster" },
|
||||||
|
{ "jabberwock" }, { "kobold" }, { "leprechaun" }, { "medusa" },
|
||||||
|
{ "nymph" }, { "orc" }, { "phantom" }, { "quasit" }, { "rattlesnake" },
|
||||||
|
{ "snake" }, { "troll" }, { "ur-vile" }, { "vampire" }, { "wraith" },
|
||||||
|
{ "xeroc" }, { "yeti" }, { "zombie" }
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* s_lock_sc:
|
||||||
|
* lock the score file. If it takes too long, ask the user if
|
||||||
|
* they care to wait. Return TRUE if the lock is successful.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
s_lock_sc(void)
|
||||||
|
{
|
||||||
|
int cnt;
|
||||||
|
struct stat sbuf;
|
||||||
|
|
||||||
|
over:
|
||||||
|
close(8); /* just in case there are no files left */
|
||||||
|
if (creat(lockfile, 0000) >= 0)
|
||||||
|
return TRUE;
|
||||||
|
for (cnt = 0; cnt < 5; cnt++)
|
||||||
|
{
|
||||||
|
md_sleep(1);
|
||||||
|
if (creat(lockfile, 0000) >= 0)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
if (stat(lockfile, &sbuf) < 0)
|
||||||
|
{
|
||||||
|
creat(lockfile, 0000);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
if (time(NULL) - sbuf.st_mtime > 10)
|
||||||
|
{
|
||||||
|
if (md_unlink(lockfile) < 0)
|
||||||
|
return FALSE;
|
||||||
|
goto over;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("The score file is very busy. Do you want to wait longer\n");
|
||||||
|
printf("for it to become free so your score can get posted?\n");
|
||||||
|
printf("If so, type \"y\"\n");
|
||||||
|
(void) fgets(prbuf, MAXSTR, stdin);
|
||||||
|
if (prbuf[0] == 'y')
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (creat(lockfile, 0000) >= 0)
|
||||||
|
return TRUE;
|
||||||
|
if (stat(lockfile, &sbuf) < 0)
|
||||||
|
{
|
||||||
|
creat(lockfile, 0000);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
if (time(NULL) - sbuf.st_mtime > 10)
|
||||||
|
{
|
||||||
|
if (md_unlink(lockfile) < 0)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
md_sleep(1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* s_unlock_sc:
|
||||||
|
* Unlock the score file
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
s_unlock_sc(void)
|
||||||
|
{
|
||||||
|
md_unlink(lockfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* s_encwrite:
|
||||||
|
* Perform an encrypted write
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
s_encwrite(char *start, size_t size, FILE *outf)
|
||||||
|
{
|
||||||
|
char *e1, *e2, fb;
|
||||||
|
int temp;
|
||||||
|
|
||||||
|
e1 = encstr;
|
||||||
|
e2 = statlist;
|
||||||
|
fb = 0;
|
||||||
|
|
||||||
|
while (size--)
|
||||||
|
{
|
||||||
|
putc(*start++ ^ *e1 ^ *e2 ^ fb, outf);
|
||||||
|
temp = *e1++;
|
||||||
|
fb += temp * *e2++;
|
||||||
|
if (*e1 == '\0')
|
||||||
|
e1 = encstr;
|
||||||
|
if (*e2 == '\0')
|
||||||
|
e2 = statlist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* s_encread:
|
||||||
|
* Perform an encrypted read
|
||||||
|
*/
|
||||||
|
|
||||||
|
s_encread(char *start, size_t size, int inf)
|
||||||
|
{
|
||||||
|
char *e1, *e2, fb;
|
||||||
|
int temp;
|
||||||
|
int read_size;
|
||||||
|
|
||||||
|
fb = 0;
|
||||||
|
|
||||||
|
if ((read_size = read(inf, start, size)) == 0 || read_size == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
e1 = encstr;
|
||||||
|
e2 = statlist;
|
||||||
|
|
||||||
|
while (size--)
|
||||||
|
{
|
||||||
|
*start++ ^= *e1 ^ *e2 ^ fb;
|
||||||
|
temp = *e1++;
|
||||||
|
fb += temp * *e2++;
|
||||||
|
if (*e1 == '\0')
|
||||||
|
e1 = encstr;
|
||||||
|
if (*e2 == '\0')
|
||||||
|
e2 = statlist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* s_killname:
|
||||||
|
* Convert a code to a monster name
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
s_killname(int monst, int doart)
|
||||||
|
{
|
||||||
|
char *sp;
|
||||||
|
int article;
|
||||||
|
|
||||||
|
article = TRUE;
|
||||||
|
switch (monst)
|
||||||
|
{
|
||||||
|
case 'a':
|
||||||
|
sp = "arrow";
|
||||||
|
when 'b':
|
||||||
|
sp = "bolt";
|
||||||
|
when 'd':
|
||||||
|
sp = "dart";
|
||||||
|
when 's':
|
||||||
|
sp = "starvation";
|
||||||
|
article = FALSE;
|
||||||
|
when 'h':
|
||||||
|
sp = "hypothermia";
|
||||||
|
article = FALSE;
|
||||||
|
otherwise:
|
||||||
|
if (isupper(monst))
|
||||||
|
sp = monsters[monst-'A'].m_name;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sp = "God";
|
||||||
|
article = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (doart && article)
|
||||||
|
sprintf(prbuf, "a%s ", s_vowelstr(sp));
|
||||||
|
else
|
||||||
|
prbuf[0] = '\0';
|
||||||
|
strcat(prbuf, sp);
|
||||||
|
return prbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* s_vowelstr:
|
||||||
|
* For printfs: if string starts with a vowel, return "n" for an
|
||||||
|
* "an".
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
s_vowelstr(char *str)
|
||||||
|
{
|
||||||
|
switch (*str)
|
||||||
|
{
|
||||||
|
case 'a': case 'A':
|
||||||
|
case 'e': case 'E':
|
||||||
|
case 'i': case 'I':
|
||||||
|
case 'o': case 'O':
|
||||||
|
case 'u': case 'U':
|
||||||
|
return "n";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
26
rogue5/score.h
Normal file
26
rogue5/score.h
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* Score file structure
|
||||||
|
*
|
||||||
|
* @(#)score.h 4.6 (Berkeley) 02/05/99
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct sc_ent {
|
||||||
|
uid_t sc_uid;
|
||||||
|
int sc_score;
|
||||||
|
unsigned int sc_flags;
|
||||||
|
int sc_monster;
|
||||||
|
char sc_name[MAXSTR];
|
||||||
|
int sc_level;
|
||||||
|
unsigned int sc_time;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct sc_ent SCORE;
|
||||||
|
|
||||||
|
void rd_score(SCORE *top_ten);
|
||||||
|
void wr_score(SCORE *top_ten);
|
||||||
330
rogue5/scrolls.c
Normal file
330
rogue5/scrolls.c
Normal file
|
|
@ -0,0 +1,330 @@
|
||||||
|
/*
|
||||||
|
* Read a scroll and let it happen
|
||||||
|
*
|
||||||
|
* @(#)scrolls.c 4.44 (Berkeley) 02/05/99
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <curses.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "rogue.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read_scroll:
|
||||||
|
* Read a scroll from the pack and do the appropriate thing
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
read_scroll(void)
|
||||||
|
{
|
||||||
|
THING *obj;
|
||||||
|
PLACE *pp;
|
||||||
|
int y, x;
|
||||||
|
int ch;
|
||||||
|
int i;
|
||||||
|
int discardit = FALSE;
|
||||||
|
struct room *cur_room;
|
||||||
|
THING *orig_obj;
|
||||||
|
coord mp;
|
||||||
|
|
||||||
|
obj = get_item("read", SCROLL);
|
||||||
|
if (obj == NULL)
|
||||||
|
return;
|
||||||
|
if (obj->o_type != SCROLL)
|
||||||
|
{
|
||||||
|
if (!terse)
|
||||||
|
msg("there is nothing on it to read");
|
||||||
|
else
|
||||||
|
msg("nothing to read");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Calculate the effect it has on the poor guy.
|
||||||
|
*/
|
||||||
|
if (obj == cur_weapon)
|
||||||
|
cur_weapon = NULL;
|
||||||
|
/*
|
||||||
|
* Get rid of the thing
|
||||||
|
*/
|
||||||
|
discardit = (obj->o_count == 1);
|
||||||
|
leave_pack(obj, FALSE, FALSE);
|
||||||
|
orig_obj = obj;
|
||||||
|
|
||||||
|
switch (obj->o_which)
|
||||||
|
{
|
||||||
|
case S_CONFUSE:
|
||||||
|
/*
|
||||||
|
* Scroll of monster confusion. Give him that power.
|
||||||
|
*/
|
||||||
|
player.t_flags |= CANHUH;
|
||||||
|
msg("your hands begin to glow %s", pick_color("red"));
|
||||||
|
when S_ARMOR:
|
||||||
|
if (cur_armor != NULL)
|
||||||
|
{
|
||||||
|
cur_armor->o_arm--;
|
||||||
|
cur_armor->o_flags &= ~ISCURSED;
|
||||||
|
msg("your armor glows %s for a moment", pick_color("silver"));
|
||||||
|
}
|
||||||
|
when S_HOLD:
|
||||||
|
/*
|
||||||
|
* Hold monster scroll. Stop all monsters within two spaces
|
||||||
|
* from chasing after the hero.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ch = 0;
|
||||||
|
for (x = hero.x - 2; x <= hero.x + 2; x++)
|
||||||
|
if (x >= 0 && x < NUMCOLS)
|
||||||
|
for (y = hero.y - 2; y <= hero.y + 2; y++)
|
||||||
|
if (y >= 0 && y <= NUMLINES - 1)
|
||||||
|
if ((obj = moat(y, x)) != NULL && on(*obj, ISRUN))
|
||||||
|
{
|
||||||
|
obj->t_flags &= ~ISRUN;
|
||||||
|
obj->t_flags |= ISHELD;
|
||||||
|
ch++;
|
||||||
|
}
|
||||||
|
if (ch)
|
||||||
|
{
|
||||||
|
addmsg("the monster");
|
||||||
|
if (ch > 1)
|
||||||
|
addmsg("s around you");
|
||||||
|
addmsg(" freeze");
|
||||||
|
if (ch == 1)
|
||||||
|
addmsg("s");
|
||||||
|
endmsg();
|
||||||
|
scr_info[S_HOLD].oi_know = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
msg("you feel a strange sense of loss");
|
||||||
|
when S_SLEEP:
|
||||||
|
/*
|
||||||
|
* Scroll which makes you fall asleep
|
||||||
|
*/
|
||||||
|
scr_info[S_SLEEP].oi_know = TRUE;
|
||||||
|
no_command += rnd(SLEEPTIME) + 4;
|
||||||
|
player.t_flags &= ~ISRUN;
|
||||||
|
msg("you fall asleep");
|
||||||
|
when S_CREATE:
|
||||||
|
/*
|
||||||
|
* Create a monster:
|
||||||
|
* First look in a circle around him, next try his room
|
||||||
|
* otherwise give up
|
||||||
|
*/
|
||||||
|
i = 0;
|
||||||
|
for (y = hero.y - 1; y <= hero.y + 1; y++)
|
||||||
|
for (x = hero.x - 1; x <= hero.x + 1; x++)
|
||||||
|
/*
|
||||||
|
* Don't put a monster in top of the player.
|
||||||
|
*/
|
||||||
|
if (y == hero.y && x == hero.x)
|
||||||
|
continue;
|
||||||
|
/*
|
||||||
|
* Or anything else nasty
|
||||||
|
* Also avoid a xeroc which is disguised as scroll
|
||||||
|
*/
|
||||||
|
else if (moat(y, x) == NULL && step_ok(ch = winat(y, x)))
|
||||||
|
{
|
||||||
|
if (ch == SCROLL
|
||||||
|
&& find_obj(y, x)->o_which == S_SCARE)
|
||||||
|
continue;
|
||||||
|
else if (rnd(++i) == 0)
|
||||||
|
{
|
||||||
|
mp.y = y;
|
||||||
|
mp.x = x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == 0)
|
||||||
|
msg("you hear a faint cry of anguish in the distance");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
obj = new_item();
|
||||||
|
new_monster(obj, randmonster(FALSE), &mp);
|
||||||
|
}
|
||||||
|
when S_ID_POTION:
|
||||||
|
case S_ID_SCROLL:
|
||||||
|
case S_ID_WEAPON:
|
||||||
|
case S_ID_ARMOR:
|
||||||
|
case S_ID_R_OR_S:
|
||||||
|
{
|
||||||
|
int id_type[S_ID_R_OR_S + 1] =
|
||||||
|
{ 0, 0, 0, 0, 0, POTION, SCROLL, WEAPON, ARMOR, R_OR_S };
|
||||||
|
/*
|
||||||
|
* Identify, let him figure something out
|
||||||
|
*/
|
||||||
|
scr_info[obj->o_which].oi_know = TRUE;
|
||||||
|
msg("this scroll is an %s scroll", scr_info[obj->o_which].oi_name);
|
||||||
|
whatis(TRUE, id_type[obj->o_which]);
|
||||||
|
}
|
||||||
|
when S_MAP:
|
||||||
|
/*
|
||||||
|
* Scroll of magic mapping.
|
||||||
|
*/
|
||||||
|
scr_info[S_MAP].oi_know = TRUE;
|
||||||
|
msg("oh, now this scroll has a map on it");
|
||||||
|
/*
|
||||||
|
* take all the things we want to keep hidden out of the window
|
||||||
|
*/
|
||||||
|
for (y = 1; y < NUMLINES - 1; y++)
|
||||||
|
for (x = 0; x < NUMCOLS; x++)
|
||||||
|
{
|
||||||
|
pp = INDEX(y, x);
|
||||||
|
switch (ch = pp->p_ch)
|
||||||
|
{
|
||||||
|
case DOOR:
|
||||||
|
case STAIRS:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '-':
|
||||||
|
case '|':
|
||||||
|
if (!(pp->p_flags & F_REAL))
|
||||||
|
{
|
||||||
|
ch = pp->p_ch = DOOR;
|
||||||
|
pp->p_flags |= F_REAL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ' ':
|
||||||
|
if (pp->p_flags & F_REAL)
|
||||||
|
goto def;
|
||||||
|
pp->p_flags |= F_REAL;
|
||||||
|
ch = pp->p_ch = PASSAGE;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
|
case PASSAGE:
|
||||||
|
pass:
|
||||||
|
if (!(pp->p_flags & F_REAL))
|
||||||
|
pp->p_ch = PASSAGE;
|
||||||
|
pp->p_flags |= (F_SEEN|F_REAL);
|
||||||
|
ch = PASSAGE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FLOOR:
|
||||||
|
if (pp->p_flags & F_REAL)
|
||||||
|
ch = ' ';
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ch = TRAP;
|
||||||
|
pp->p_ch = TRAP;
|
||||||
|
pp->p_flags |= (F_SEEN|F_REAL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
def:
|
||||||
|
if (pp->p_flags & F_PASS)
|
||||||
|
goto pass;
|
||||||
|
ch = ' ';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ch != ' ')
|
||||||
|
{
|
||||||
|
if ((obj = pp->p_monst) != NULL)
|
||||||
|
obj->t_oldch = ch;
|
||||||
|
if (obj == NULL || !on(player, SEEMONST))
|
||||||
|
mvaddch(y, x, ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
when S_FDET:
|
||||||
|
/*
|
||||||
|
* Potion of gold detection
|
||||||
|
*/
|
||||||
|
ch = FALSE;
|
||||||
|
wclear(hw);
|
||||||
|
for (obj = lvl_obj; obj != NULL; obj = next(obj))
|
||||||
|
if (obj->o_type == FOOD)
|
||||||
|
{
|
||||||
|
ch = TRUE;
|
||||||
|
wmove(hw, obj->o_pos.y, obj->o_pos.x);
|
||||||
|
waddch(hw, FOOD);
|
||||||
|
}
|
||||||
|
if (ch)
|
||||||
|
{
|
||||||
|
scr_info[S_FDET].oi_know = TRUE;
|
||||||
|
show_win("Your nose tingles and you smell food.--More--");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
msg("your nose tingles");
|
||||||
|
when S_TELEP:
|
||||||
|
/*
|
||||||
|
* Scroll of teleportation:
|
||||||
|
* Make him dissapear and reappear
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
cur_room = proom;
|
||||||
|
teleport();
|
||||||
|
if (cur_room != proom)
|
||||||
|
scr_info[S_TELEP].oi_know = TRUE;
|
||||||
|
}
|
||||||
|
when S_ENCH:
|
||||||
|
if (cur_weapon == NULL || cur_weapon->o_type != WEAPON)
|
||||||
|
msg("you feel a strange sense of loss");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cur_weapon->o_flags &= ~ISCURSED;
|
||||||
|
if (rnd(2) == 0)
|
||||||
|
cur_weapon->o_hplus++;
|
||||||
|
else
|
||||||
|
cur_weapon->o_dplus++;
|
||||||
|
msg("your %s glows %s for a moment",
|
||||||
|
weap_info[cur_weapon->o_which].oi_name, pick_color("blue"));
|
||||||
|
}
|
||||||
|
when S_SCARE:
|
||||||
|
/*
|
||||||
|
* Reading it is a mistake and produces laughter at her
|
||||||
|
* poor boo boo.
|
||||||
|
*/
|
||||||
|
msg("you hear maniacal laughter in the distance");
|
||||||
|
when S_REMOVE:
|
||||||
|
uncurse(cur_armor);
|
||||||
|
uncurse(cur_weapon);
|
||||||
|
uncurse(cur_ring[LEFT]);
|
||||||
|
uncurse(cur_ring[RIGHT]);
|
||||||
|
msg(choose_str("you feel in touch with the Universal Onenes",
|
||||||
|
"you feel as if somebody is watching over you"));
|
||||||
|
when S_AGGR:
|
||||||
|
/*
|
||||||
|
* This scroll aggravates all the monsters on the current
|
||||||
|
* level and sets them running towards the hero
|
||||||
|
*/
|
||||||
|
aggravate();
|
||||||
|
msg("you hear a high pitched humming noise");
|
||||||
|
when S_PROTECT:
|
||||||
|
if (cur_armor != NULL)
|
||||||
|
{
|
||||||
|
cur_armor->o_flags |= ISPROT;
|
||||||
|
msg("your armor is covered by a shimmering %s shield",
|
||||||
|
pick_color("gold"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
msg("you feel a strange sense of loss");
|
||||||
|
#ifdef MASTER
|
||||||
|
otherwise:
|
||||||
|
msg("what a puzzling scroll!");
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
obj = orig_obj;
|
||||||
|
look(TRUE); /* put the result of the scroll on the screen */
|
||||||
|
status();
|
||||||
|
|
||||||
|
call_it(&scr_info[obj->o_which]);
|
||||||
|
|
||||||
|
if (discardit)
|
||||||
|
discard(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* uncurse:
|
||||||
|
* Uncurse an item
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
uncurse(THING *obj)
|
||||||
|
{
|
||||||
|
if (obj != NULL)
|
||||||
|
obj->o_flags &= ~ISCURSED;
|
||||||
|
}
|
||||||
1450
rogue5/state.c
Normal file
1450
rogue5/state.c
Normal file
File diff suppressed because it is too large
Load diff
431
rogue5/sticks.c
Normal file
431
rogue5/sticks.c
Normal file
|
|
@ -0,0 +1,431 @@
|
||||||
|
/*
|
||||||
|
* Functions to implement the various sticks one might find
|
||||||
|
* while wandering around the dungeon.
|
||||||
|
*
|
||||||
|
* @(#)sticks.c 4.39 (Berkeley) 02/05/99
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <curses.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "rogue.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fix_stick:
|
||||||
|
* Set up a new stick
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
fix_stick(THING *cur)
|
||||||
|
{
|
||||||
|
if (strcmp(ws_type[cur->o_which], "staff") == 0)
|
||||||
|
strncpy(cur->o_damage,"2x3",sizeof(cur->o_damage));
|
||||||
|
else
|
||||||
|
strncpy(cur->o_damage,"1x1",sizeof(cur->o_damage));
|
||||||
|
strncpy(cur->o_hurldmg,"1x1",sizeof(cur->o_hurldmg));
|
||||||
|
|
||||||
|
switch (cur->o_which)
|
||||||
|
{
|
||||||
|
case WS_LIGHT:
|
||||||
|
cur->o_charges = rnd(10) + 10;
|
||||||
|
otherwise:
|
||||||
|
cur->o_charges = rnd(5) + 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* do_zap:
|
||||||
|
* Perform a zap with a wand
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
do_zap(void)
|
||||||
|
{
|
||||||
|
THING *obj, *tp;
|
||||||
|
int y, x;
|
||||||
|
char *name;
|
||||||
|
int monster, oldch;
|
||||||
|
THING bolt;
|
||||||
|
|
||||||
|
if ((obj = get_item("zap with", STICK)) == NULL)
|
||||||
|
return;
|
||||||
|
if (obj->o_type != STICK)
|
||||||
|
{
|
||||||
|
after = FALSE;
|
||||||
|
msg("you can't zap with that!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (obj->o_charges == 0)
|
||||||
|
{
|
||||||
|
msg("nothing happens");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
switch (obj->o_which)
|
||||||
|
{
|
||||||
|
case WS_LIGHT:
|
||||||
|
/*
|
||||||
|
* Reddy Kilowat wand. Light up the room
|
||||||
|
*/
|
||||||
|
ws_info[WS_LIGHT].oi_know = TRUE;
|
||||||
|
if (proom->r_flags & ISGONE)
|
||||||
|
msg("the corridor glows and then fades");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
proom->r_flags &= ~ISDARK;
|
||||||
|
/*
|
||||||
|
* Light the room and put the player back up
|
||||||
|
*/
|
||||||
|
enter_room(&hero);
|
||||||
|
addmsg("the room is lit");
|
||||||
|
if (!terse)
|
||||||
|
addmsg(" by a shimmering %s light", pick_color("blue"));
|
||||||
|
endmsg();
|
||||||
|
}
|
||||||
|
when WS_DRAIN:
|
||||||
|
/*
|
||||||
|
* take away 1/2 of hero's hit points, then take it away
|
||||||
|
* evenly from the monsters in the room (or next to hero
|
||||||
|
* if he is in a passage)
|
||||||
|
*/
|
||||||
|
if (pstats.s_hpt < 2)
|
||||||
|
{
|
||||||
|
msg("you are too weak to use it");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
drain();
|
||||||
|
when WS_INVIS:
|
||||||
|
case WS_POLYMORPH:
|
||||||
|
case WS_TELAWAY:
|
||||||
|
case WS_TELTO:
|
||||||
|
case WS_CANCEL:
|
||||||
|
y = hero.y;
|
||||||
|
x = hero.x;
|
||||||
|
while (step_ok(winat(y, x)))
|
||||||
|
{
|
||||||
|
y += delta.y;
|
||||||
|
x += delta.x;
|
||||||
|
}
|
||||||
|
if ((tp = moat(y, x)) != NULL)
|
||||||
|
{
|
||||||
|
monster = tp->t_type;
|
||||||
|
if (monster == 'F')
|
||||||
|
player.t_flags &= ~ISHELD;
|
||||||
|
switch (obj->o_which) {
|
||||||
|
case WS_INVIS:
|
||||||
|
tp->t_flags |= ISINVIS;
|
||||||
|
if (cansee(y, x))
|
||||||
|
mvaddch(y, x, tp->t_oldch);
|
||||||
|
break;
|
||||||
|
case WS_POLYMORPH:
|
||||||
|
{
|
||||||
|
THING *pp;
|
||||||
|
|
||||||
|
pp = tp->t_pack;
|
||||||
|
detach(mlist, tp);
|
||||||
|
if (see_monst(tp))
|
||||||
|
mvaddch(y, x, chat(y, x));
|
||||||
|
oldch = tp->t_oldch;
|
||||||
|
delta.y = y;
|
||||||
|
delta.x = x;
|
||||||
|
new_monster(tp, monster = rnd(26) + 'A', &delta);
|
||||||
|
if (see_monst(tp))
|
||||||
|
mvaddch(y, x, monster);
|
||||||
|
tp->t_oldch = oldch;
|
||||||
|
tp->t_pack = pp;
|
||||||
|
ws_info[WS_POLYMORPH].oi_know |= see_monst(tp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WS_CANCEL:
|
||||||
|
tp->t_flags |= ISCANC;
|
||||||
|
tp->t_flags &= ~(ISINVIS|CANHUH);
|
||||||
|
tp->t_disguise = tp->t_type;
|
||||||
|
if (see_monst(tp))
|
||||||
|
mvaddch(y, x, tp->t_disguise);
|
||||||
|
break;
|
||||||
|
case WS_TELAWAY:
|
||||||
|
case WS_TELTO:
|
||||||
|
{
|
||||||
|
coord new_pos;
|
||||||
|
|
||||||
|
if (obj->o_which == WS_TELAWAY)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
find_floor(NULL, &new_pos, FALSE, TRUE);
|
||||||
|
} while (ce(new_pos, hero));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new_pos.y = hero.y + delta.y;
|
||||||
|
new_pos.x = hero.x + delta.x;
|
||||||
|
}
|
||||||
|
tp->t_dest = &hero;
|
||||||
|
tp->t_flags |= ISRUN;
|
||||||
|
relocate(tp, &new_pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
when WS_MISSILE:
|
||||||
|
ws_info[WS_MISSILE].oi_know = TRUE;
|
||||||
|
bolt.o_type = '*';
|
||||||
|
strncpy(bolt.o_hurldmg,"1x4",sizeof(bolt.o_hurldmg));
|
||||||
|
bolt.o_hplus = 100;
|
||||||
|
bolt.o_dplus = 1;
|
||||||
|
bolt.o_flags = ISMISL;
|
||||||
|
if (cur_weapon != NULL)
|
||||||
|
bolt.o_launch = cur_weapon->o_which;
|
||||||
|
do_motion(&bolt, delta.y, delta.x);
|
||||||
|
if ((tp = moat(bolt.o_pos.y, bolt.o_pos.x)) != NULL
|
||||||
|
&& !save_throw(VS_MAGIC, tp))
|
||||||
|
hit_monster(unc(bolt.o_pos), &bolt);
|
||||||
|
else if (terse)
|
||||||
|
msg("missle vanishes");
|
||||||
|
else
|
||||||
|
msg("the missle vanishes with a puff of smoke");
|
||||||
|
when WS_HASTE_M:
|
||||||
|
case WS_SLOW_M:
|
||||||
|
y = hero.y;
|
||||||
|
x = hero.x;
|
||||||
|
while (step_ok(winat(y, x)))
|
||||||
|
{
|
||||||
|
y += delta.y;
|
||||||
|
x += delta.x;
|
||||||
|
}
|
||||||
|
if ((tp = moat(y, x)) != NULL)
|
||||||
|
{
|
||||||
|
if (obj->o_which == WS_HASTE_M)
|
||||||
|
{
|
||||||
|
if (on(*tp, ISSLOW))
|
||||||
|
tp->t_flags &= ~ISSLOW;
|
||||||
|
else
|
||||||
|
tp->t_flags |= ISHASTE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (on(*tp, ISHASTE))
|
||||||
|
tp->t_flags &= ~ISHASTE;
|
||||||
|
else
|
||||||
|
tp->t_flags |= ISSLOW;
|
||||||
|
tp->t_turn = TRUE;
|
||||||
|
}
|
||||||
|
delta.y = y;
|
||||||
|
delta.x = x;
|
||||||
|
runto(&delta);
|
||||||
|
}
|
||||||
|
when WS_ELECT:
|
||||||
|
case WS_FIRE:
|
||||||
|
case WS_COLD:
|
||||||
|
if (obj->o_which == WS_ELECT)
|
||||||
|
name = "bolt";
|
||||||
|
else if (obj->o_which == WS_FIRE)
|
||||||
|
name = "flame";
|
||||||
|
else
|
||||||
|
name = "ice";
|
||||||
|
fire_bolt(&hero, &delta, name);
|
||||||
|
ws_info[obj->o_which].oi_know = TRUE;
|
||||||
|
when WS_NOP:
|
||||||
|
break;
|
||||||
|
#ifdef MASTER
|
||||||
|
otherwise:
|
||||||
|
msg("what a bizarre schtick!");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
obj->o_charges--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* drain:
|
||||||
|
* Do drain hit points from player shtick
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
drain(void)
|
||||||
|
{
|
||||||
|
THING *mp;
|
||||||
|
struct room *corp;
|
||||||
|
THING **dp;
|
||||||
|
int cnt;
|
||||||
|
int inpass;
|
||||||
|
THING *drainee[40];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* First cnt how many things we need to spread the hit points among
|
||||||
|
*/
|
||||||
|
cnt = 0;
|
||||||
|
if (chat(hero.y, hero.x) == DOOR)
|
||||||
|
corp = &passages[flat(hero.y, hero.x) & F_PNUM];
|
||||||
|
else
|
||||||
|
corp = NULL;
|
||||||
|
inpass = (proom->r_flags & ISGONE);
|
||||||
|
dp = drainee;
|
||||||
|
for (mp = mlist; mp != NULL; mp = next(mp))
|
||||||
|
if (mp->t_room == proom || mp->t_room == corp ||
|
||||||
|
(inpass && chat(mp->t_pos.y, mp->t_pos.x) == DOOR &&
|
||||||
|
&passages[flat(mp->t_pos.y, mp->t_pos.x) & F_PNUM] == proom))
|
||||||
|
*dp++ = mp;
|
||||||
|
if ((cnt = (int)(dp - drainee)) == 0)
|
||||||
|
{
|
||||||
|
msg("you have a tingling feeling");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*dp = NULL;
|
||||||
|
pstats.s_hpt /= 2;
|
||||||
|
cnt = pstats.s_hpt / cnt;
|
||||||
|
/*
|
||||||
|
* Now zot all of the monsters
|
||||||
|
*/
|
||||||
|
for (dp = drainee; *dp; dp++)
|
||||||
|
{
|
||||||
|
mp = *dp;
|
||||||
|
if ((mp->t_stats.s_hpt -= cnt) <= 0)
|
||||||
|
killed(mp, see_monst(mp));
|
||||||
|
else
|
||||||
|
runto(&mp->t_pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fire_bolt:
|
||||||
|
* Fire a bolt in a given direction from a specific starting place
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
fire_bolt(const coord *start, coord *dir, const char *name)
|
||||||
|
{
|
||||||
|
coord *c1, *c2;
|
||||||
|
THING *tp;
|
||||||
|
int dirch = 0, ch;
|
||||||
|
int hit_hero, used, changed;
|
||||||
|
coord pos;
|
||||||
|
coord spotpos[BOLT_LENGTH];
|
||||||
|
THING bolt;
|
||||||
|
|
||||||
|
bolt.o_type = WEAPON;
|
||||||
|
bolt.o_which = FLAME;
|
||||||
|
strncpy(bolt.o_hurldmg,"6x6",sizeof(bolt.o_hurldmg));
|
||||||
|
bolt.o_hplus = 100;
|
||||||
|
bolt.o_dplus = 0;
|
||||||
|
weap_info[FLAME].oi_name = name;
|
||||||
|
switch (dir->y + dir->x)
|
||||||
|
{
|
||||||
|
case 0: dirch = '/';
|
||||||
|
when 1: case -1: dirch = (dir->y == 0 ? '-' : '|');
|
||||||
|
when 2: case -2: dirch = '\\';
|
||||||
|
}
|
||||||
|
pos = *start;
|
||||||
|
hit_hero = (start != &hero);
|
||||||
|
used = FALSE;
|
||||||
|
changed = FALSE;
|
||||||
|
for (c1 = spotpos; c1 <= &spotpos[BOLT_LENGTH-1] && !used; c1++)
|
||||||
|
{
|
||||||
|
pos.y += dir->y;
|
||||||
|
pos.x += dir->x;
|
||||||
|
*c1 = pos;
|
||||||
|
ch = winat(pos.y, pos.x);
|
||||||
|
switch (ch)
|
||||||
|
{
|
||||||
|
case DOOR:
|
||||||
|
/*
|
||||||
|
* this code is necessary if the hero is on a door
|
||||||
|
* and he fires at the wall the door is in, it would
|
||||||
|
* otherwise loop infinitely
|
||||||
|
*/
|
||||||
|
if (ce(hero, pos))
|
||||||
|
goto def;
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
case '|':
|
||||||
|
case '-':
|
||||||
|
case ' ':
|
||||||
|
if (!changed)
|
||||||
|
hit_hero = !hit_hero;
|
||||||
|
changed = FALSE;
|
||||||
|
dir->y = -dir->y;
|
||||||
|
dir->x = -dir->x;
|
||||||
|
c1--;
|
||||||
|
msg("the %s bounces", name);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
def:
|
||||||
|
if (!hit_hero && (tp = moat(pos.y, pos.x)) != NULL)
|
||||||
|
{
|
||||||
|
hit_hero = TRUE;
|
||||||
|
changed = !changed;
|
||||||
|
tp->t_oldch = chat(pos.y, pos.x);
|
||||||
|
if (!save_throw(VS_MAGIC, tp))
|
||||||
|
{
|
||||||
|
bolt.o_pos = pos;
|
||||||
|
used = TRUE;
|
||||||
|
if (tp->t_type == 'D' && strcmp(name, "flame") == 0)
|
||||||
|
{
|
||||||
|
addmsg("the flame bounces");
|
||||||
|
if (!terse)
|
||||||
|
addmsg(" off the dragon");
|
||||||
|
endmsg();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
hit_monster(unc(pos), &bolt);
|
||||||
|
}
|
||||||
|
else if (ch != 'M' || tp->t_disguise == 'M')
|
||||||
|
{
|
||||||
|
if (start == &hero)
|
||||||
|
runto(&pos);
|
||||||
|
if (terse)
|
||||||
|
msg("%s misses", name);
|
||||||
|
else
|
||||||
|
msg("the %s whizzes past %s", name, set_mname(tp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (hit_hero && ce(pos, hero))
|
||||||
|
{
|
||||||
|
hit_hero = FALSE;
|
||||||
|
changed = !changed;
|
||||||
|
if (!save(VS_MAGIC))
|
||||||
|
{
|
||||||
|
if ((pstats.s_hpt -= roll(6, 6)) <= 0)
|
||||||
|
{
|
||||||
|
if (start == &hero)
|
||||||
|
death('b');
|
||||||
|
else
|
||||||
|
death(moat(start->y, start->x)->t_type);
|
||||||
|
}
|
||||||
|
used = TRUE;
|
||||||
|
if (terse)
|
||||||
|
msg("the %s hits", name);
|
||||||
|
else
|
||||||
|
msg("you are hit by the %s", name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
msg("the %s whizzes by you", name);
|
||||||
|
}
|
||||||
|
mvaddch(pos.y, pos.x, dirch);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (c2 = spotpos; c2 < c1; c2++)
|
||||||
|
mvaddch(c2->y, c2->x, chat(c2->y, c2->x));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* charge_str:
|
||||||
|
* Return an appropriate string for a wand charge
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
charge_str(const THING *obj)
|
||||||
|
{
|
||||||
|
static char buf[20];
|
||||||
|
|
||||||
|
if (!(obj->o_flags & ISKNOW))
|
||||||
|
buf[0] = '\0';
|
||||||
|
else if (terse)
|
||||||
|
sprintf(buf, " [%d]", obj->o_charges);
|
||||||
|
else
|
||||||
|
sprintf(buf, " [%d charges]", obj->o_charges);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
716
rogue5/things.c
Normal file
716
rogue5/things.c
Normal file
|
|
@ -0,0 +1,716 @@
|
||||||
|
/*
|
||||||
|
* Contains functions for dealing with things like potions, scrolls,
|
||||||
|
* and other items.
|
||||||
|
*
|
||||||
|
* @(#)things.c 4.53 (Berkeley) 02/05/99
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <curses.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "rogue.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* inv_name:
|
||||||
|
* Return the name of something as it would appear in an
|
||||||
|
* inventory.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
inv_name(const THING *obj, int drop)
|
||||||
|
{
|
||||||
|
char *pb;
|
||||||
|
struct obj_info *op;
|
||||||
|
const char *sp;
|
||||||
|
int which;
|
||||||
|
|
||||||
|
pb = prbuf;
|
||||||
|
which = obj->o_which;
|
||||||
|
switch (obj->o_type)
|
||||||
|
{
|
||||||
|
case POTION:
|
||||||
|
nameit(obj, "potion", p_colors[which], &pot_info[which], nullstr);
|
||||||
|
when RING:
|
||||||
|
nameit(obj, "ring", r_stones[which], &ring_info[which], ring_num);
|
||||||
|
when STICK:
|
||||||
|
nameit(obj, ws_type[which], ws_made[which], &ws_info[which], charge_str);
|
||||||
|
when SCROLL:
|
||||||
|
if (obj->o_count == 1)
|
||||||
|
{
|
||||||
|
strcpy(pb, "A scroll ");
|
||||||
|
pb = &prbuf[9];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprintf(pb, "%d scrolls ", obj->o_count);
|
||||||
|
pb = &prbuf[strlen(prbuf)];
|
||||||
|
}
|
||||||
|
op = &scr_info[which];
|
||||||
|
if (op->oi_know)
|
||||||
|
sprintf(pb, "of %s", op->oi_name);
|
||||||
|
else if (op->oi_guess)
|
||||||
|
sprintf(pb, "called %s", op->oi_guess);
|
||||||
|
else
|
||||||
|
sprintf(pb, "titled '%s'", s_names[which]);
|
||||||
|
when FOOD:
|
||||||
|
if (which == 1)
|
||||||
|
if (obj->o_count == 1)
|
||||||
|
sprintf(pb, "A%s %s", vowelstr(fruit), fruit);
|
||||||
|
else
|
||||||
|
sprintf(pb, "%d %ss", obj->o_count, fruit);
|
||||||
|
else
|
||||||
|
if (obj->o_count == 1)
|
||||||
|
strcpy(pb, "Some food");
|
||||||
|
else
|
||||||
|
sprintf(pb, "%d rations of food", obj->o_count);
|
||||||
|
when WEAPON:
|
||||||
|
sp = weap_info[which].oi_name;
|
||||||
|
if (obj->o_count > 1)
|
||||||
|
sprintf(pb, "%d ", obj->o_count);
|
||||||
|
else
|
||||||
|
sprintf(pb, "A%s ", vowelstr(sp));
|
||||||
|
pb = &prbuf[strlen(prbuf)];
|
||||||
|
if (obj->o_flags & ISKNOW)
|
||||||
|
sprintf(pb, "%s %s", num(obj->o_hplus,obj->o_dplus,WEAPON), sp);
|
||||||
|
else
|
||||||
|
sprintf(pb, "%s", sp);
|
||||||
|
if (obj->o_count > 1)
|
||||||
|
strcat(pb, "s");
|
||||||
|
if (obj->o_label != NULL)
|
||||||
|
{
|
||||||
|
pb = &prbuf[strlen(prbuf)];
|
||||||
|
sprintf(pb, " called %s", obj->o_label);
|
||||||
|
}
|
||||||
|
when ARMOR:
|
||||||
|
sp = arm_info[which].oi_name;
|
||||||
|
if (obj->o_flags & ISKNOW)
|
||||||
|
{
|
||||||
|
sprintf(pb, "%s %s [",
|
||||||
|
num(a_class[which] - obj->o_arm, 0, ARMOR), sp);
|
||||||
|
if (!terse)
|
||||||
|
strcat(pb, "protection ");
|
||||||
|
pb = &prbuf[strlen(prbuf)];
|
||||||
|
sprintf(pb, "%d]", 10 - obj->o_arm);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sprintf(pb, "%s", sp);
|
||||||
|
if (obj->o_label != NULL)
|
||||||
|
{
|
||||||
|
pb = &prbuf[strlen(prbuf)];
|
||||||
|
sprintf(pb, " called %s", obj->o_label);
|
||||||
|
}
|
||||||
|
when AMULET:
|
||||||
|
strcpy(pb, "The Amulet of Yendor");
|
||||||
|
when GOLD:
|
||||||
|
sprintf(prbuf, "%d Gold pieces", obj->o_goldval);
|
||||||
|
#ifdef MASTER
|
||||||
|
otherwise:
|
||||||
|
debug("Picked up something funny %s", unctrl(obj->o_type));
|
||||||
|
sprintf(pb, "Something bizarre %s", unctrl(obj->o_type));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (inv_describe)
|
||||||
|
{
|
||||||
|
if (obj == cur_armor)
|
||||||
|
strcat(pb, " (being worn)");
|
||||||
|
if (obj == cur_weapon)
|
||||||
|
strcat(pb, " (weapon in hand)");
|
||||||
|
if (obj == cur_ring[LEFT])
|
||||||
|
strcat(pb, " (on left hand)");
|
||||||
|
else if (obj == cur_ring[RIGHT])
|
||||||
|
strcat(pb, " (on right hand)");
|
||||||
|
}
|
||||||
|
if (drop && isupper((int)prbuf[0]))
|
||||||
|
prbuf[0] = (char) tolower(prbuf[0]);
|
||||||
|
else if (!drop && islower((int)*prbuf))
|
||||||
|
*prbuf = (char) toupper(*prbuf);
|
||||||
|
prbuf[MAXSTR-1] = '\0';
|
||||||
|
return prbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* drop:
|
||||||
|
* Put something down
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
drop(void)
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
THING *obj;
|
||||||
|
|
||||||
|
ch = chat(hero.y, hero.x);
|
||||||
|
if (ch != FLOOR && ch != PASSAGE)
|
||||||
|
{
|
||||||
|
after = FALSE;
|
||||||
|
msg("there is something there already");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((obj = get_item("drop", 0)) == NULL)
|
||||||
|
return;
|
||||||
|
if (!dropcheck(obj))
|
||||||
|
return;
|
||||||
|
obj = leave_pack(obj, TRUE, !ISMULT(obj->o_type));
|
||||||
|
/*
|
||||||
|
* Link it into the level object list
|
||||||
|
*/
|
||||||
|
attach(lvl_obj, obj);
|
||||||
|
chat(hero.y, hero.x) = obj->o_type;
|
||||||
|
flat(hero.y, hero.x) |= F_DROPPED;
|
||||||
|
obj->o_pos = hero;
|
||||||
|
if (obj->o_type == AMULET)
|
||||||
|
amulet = FALSE;
|
||||||
|
msg("dropped %s", inv_name(obj, TRUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dropcheck:
|
||||||
|
* Do special checks for dropping or unweilding|unwearing|unringing
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
dropcheck(const THING *obj)
|
||||||
|
{
|
||||||
|
if (obj == NULL)
|
||||||
|
return TRUE;
|
||||||
|
if (obj != cur_armor && obj != cur_weapon
|
||||||
|
&& obj != cur_ring[LEFT] && obj != cur_ring[RIGHT])
|
||||||
|
return TRUE;
|
||||||
|
if (obj->o_flags & ISCURSED)
|
||||||
|
{
|
||||||
|
msg("you can't. It appears to be cursed");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (obj == cur_weapon)
|
||||||
|
cur_weapon = NULL;
|
||||||
|
else if (obj == cur_armor)
|
||||||
|
{
|
||||||
|
waste_time();
|
||||||
|
cur_armor = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cur_ring[obj == cur_ring[LEFT] ? LEFT : RIGHT] = NULL;
|
||||||
|
switch (obj->o_which)
|
||||||
|
{
|
||||||
|
case R_ADDSTR:
|
||||||
|
chg_str(-obj->o_arm);
|
||||||
|
break;
|
||||||
|
case R_SEEINVIS:
|
||||||
|
unsee();
|
||||||
|
extinguish(unsee);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* new_thing:
|
||||||
|
* Return a new thing
|
||||||
|
*/
|
||||||
|
THING *
|
||||||
|
new_thing(void)
|
||||||
|
{
|
||||||
|
THING *cur;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
cur = new_item();
|
||||||
|
cur->o_hplus = 0;
|
||||||
|
cur->o_dplus = 0;
|
||||||
|
strncpy(cur->o_damage, "0x0", sizeof(cur->o_damage));
|
||||||
|
strncpy(cur->o_hurldmg, "0x0", sizeof(cur->o_hurldmg));
|
||||||
|
cur->o_arm = 11;
|
||||||
|
cur->o_count = 1;
|
||||||
|
cur->o_group = 0;
|
||||||
|
cur->o_flags = 0;
|
||||||
|
/*
|
||||||
|
* Decide what kind of object it will be
|
||||||
|
* If we haven't had food for a while, let it be food.
|
||||||
|
*/
|
||||||
|
switch (no_food > 3 ? 2 : pick_one(things, NUMTHINGS))
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
cur->o_type = POTION;
|
||||||
|
cur->o_which = pick_one(pot_info, MAXPOTIONS);
|
||||||
|
when 1:
|
||||||
|
cur->o_type = SCROLL;
|
||||||
|
cur->o_which = pick_one(scr_info, MAXSCROLLS);
|
||||||
|
when 2:
|
||||||
|
cur->o_type = FOOD;
|
||||||
|
no_food = 0;
|
||||||
|
if (rnd(10) != 0)
|
||||||
|
cur->o_which = 0;
|
||||||
|
else
|
||||||
|
cur->o_which = 1;
|
||||||
|
when 3:
|
||||||
|
init_weapon(cur, pick_one(weap_info, MAXWEAPONS));
|
||||||
|
if ((r = rnd(100)) < 10)
|
||||||
|
{
|
||||||
|
cur->o_flags |= ISCURSED;
|
||||||
|
cur->o_hplus -= rnd(3) + 1;
|
||||||
|
}
|
||||||
|
else if (r < 15)
|
||||||
|
cur->o_hplus += rnd(3) + 1;
|
||||||
|
when 4:
|
||||||
|
cur->o_type = ARMOR;
|
||||||
|
cur->o_which = pick_one(arm_info, MAXARMORS);
|
||||||
|
cur->o_arm = a_class[cur->o_which];
|
||||||
|
if ((r = rnd(100)) < 20)
|
||||||
|
{
|
||||||
|
cur->o_flags |= ISCURSED;
|
||||||
|
cur->o_arm += rnd(3) + 1;
|
||||||
|
}
|
||||||
|
else if (r < 28)
|
||||||
|
cur->o_arm -= rnd(3) + 1;
|
||||||
|
when 5:
|
||||||
|
cur->o_type = RING;
|
||||||
|
cur->o_which = pick_one(ring_info, MAXRINGS);
|
||||||
|
switch (cur->o_which)
|
||||||
|
{
|
||||||
|
case R_ADDSTR:
|
||||||
|
case R_PROTECT:
|
||||||
|
case R_ADDHIT:
|
||||||
|
case R_ADDDAM:
|
||||||
|
if ((cur->o_arm = rnd(3)) == 0)
|
||||||
|
{
|
||||||
|
cur->o_arm = -1;
|
||||||
|
cur->o_flags |= ISCURSED;
|
||||||
|
}
|
||||||
|
when R_AGGR:
|
||||||
|
case R_TELEPORT:
|
||||||
|
cur->o_flags |= ISCURSED;
|
||||||
|
}
|
||||||
|
when 6:
|
||||||
|
cur->o_type = STICK;
|
||||||
|
cur->o_which = pick_one(ws_info, MAXSTICKS);
|
||||||
|
fix_stick(cur);
|
||||||
|
#ifdef MASTER
|
||||||
|
otherwise:
|
||||||
|
debug("Picked a bad kind of object");
|
||||||
|
wait_for(stdscr, ' ');
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return cur;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pick_one:
|
||||||
|
* Pick an item out of a list of nitems possible objects
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
pick_one(const struct obj_info *info, int nitems)
|
||||||
|
{
|
||||||
|
const struct obj_info *end;
|
||||||
|
const struct obj_info *start;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
start = info;
|
||||||
|
for (end = &info[nitems], i = rnd(100); info < end; info++)
|
||||||
|
if (i < info->oi_prob)
|
||||||
|
break;
|
||||||
|
if (info == end)
|
||||||
|
{
|
||||||
|
#ifdef MASTER
|
||||||
|
if (wizard)
|
||||||
|
{
|
||||||
|
msg("bad pick_one: %d from %d items", i, nitems);
|
||||||
|
for (info = start; info < end; info++)
|
||||||
|
msg("%s: %d%%", info->oi_name, info->oi_prob);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
info = start;
|
||||||
|
}
|
||||||
|
return (int)(info - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* discovered:
|
||||||
|
* list what the player has discovered in this game of a certain type
|
||||||
|
*/
|
||||||
|
static int line_cnt = 0;
|
||||||
|
|
||||||
|
static int newpage = FALSE;
|
||||||
|
|
||||||
|
static const char *lastfmt, *lastarg;
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
discovered(void)
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
int disc_list;
|
||||||
|
|
||||||
|
do {
|
||||||
|
disc_list = FALSE;
|
||||||
|
if (!terse)
|
||||||
|
addmsg("for ");
|
||||||
|
addmsg("what type");
|
||||||
|
if (!terse)
|
||||||
|
addmsg(" of object do you want a list");
|
||||||
|
msg("? (* for all)");
|
||||||
|
ch = readchar();
|
||||||
|
switch (ch)
|
||||||
|
{
|
||||||
|
case ESCAPE:
|
||||||
|
msg("");
|
||||||
|
return;
|
||||||
|
case POTION:
|
||||||
|
case SCROLL:
|
||||||
|
case RING:
|
||||||
|
case STICK:
|
||||||
|
case '*':
|
||||||
|
disc_list = TRUE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (terse)
|
||||||
|
msg("Not a type");
|
||||||
|
else
|
||||||
|
msg("Please type one of %c%c%c%c (ESCAPE to quit)", POTION, SCROLL, RING, STICK);
|
||||||
|
}
|
||||||
|
} while (!disc_list);
|
||||||
|
if (ch == '*')
|
||||||
|
{
|
||||||
|
print_disc(POTION);
|
||||||
|
add_line("", NULL);
|
||||||
|
print_disc(SCROLL);
|
||||||
|
add_line("", NULL);
|
||||||
|
print_disc(RING);
|
||||||
|
add_line("", NULL);
|
||||||
|
print_disc(STICK);
|
||||||
|
end_line();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
print_disc(ch);
|
||||||
|
end_line();
|
||||||
|
}
|
||||||
|
msg("");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* print_disc:
|
||||||
|
* Print what we've discovered of type 'type'
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MAX4(a,b,c,d) (a > b ? (a > c ? (a > d ? a : d) : (c > d ? c : d)) : (b > c ? (b > d ? b : d) : (c > d ? c : d)))
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
print_disc(int type)
|
||||||
|
{
|
||||||
|
struct obj_info *info = NULL;
|
||||||
|
int i, maxnum = 0, num_found;
|
||||||
|
THING obj;
|
||||||
|
int order[MAX4(MAXSCROLLS, MAXPOTIONS, MAXRINGS, MAXSTICKS)];
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case SCROLL:
|
||||||
|
maxnum = MAXSCROLLS;
|
||||||
|
info = scr_info;
|
||||||
|
break;
|
||||||
|
case POTION:
|
||||||
|
maxnum = MAXPOTIONS;
|
||||||
|
info = pot_info;
|
||||||
|
break;
|
||||||
|
case RING:
|
||||||
|
maxnum = MAXRINGS;
|
||||||
|
info = ring_info;
|
||||||
|
break;
|
||||||
|
case STICK:
|
||||||
|
maxnum = MAXSTICKS;
|
||||||
|
info = ws_info;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
set_order(order, maxnum);
|
||||||
|
obj.o_count = 1;
|
||||||
|
obj.o_flags = 0;
|
||||||
|
num_found = 0;
|
||||||
|
for (i = 0; i < maxnum; i++)
|
||||||
|
if (info[order[i]].oi_know || info[order[i]].oi_guess)
|
||||||
|
{
|
||||||
|
obj.o_type = type;
|
||||||
|
obj.o_which = order[i];
|
||||||
|
add_line("%s", inv_name(&obj, FALSE));
|
||||||
|
num_found++;
|
||||||
|
}
|
||||||
|
if (num_found == 0)
|
||||||
|
add_line(nothing(type), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* set_order:
|
||||||
|
* Set up order for list
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
set_order(int *order, int numthings)
|
||||||
|
{
|
||||||
|
int i, r, t;
|
||||||
|
|
||||||
|
for (i = 0; i< numthings; i++)
|
||||||
|
order[i] = i;
|
||||||
|
|
||||||
|
for (i = numthings; i > 0; i--)
|
||||||
|
{
|
||||||
|
r = rnd(i);
|
||||||
|
t = order[i - 1];
|
||||||
|
order[i - 1] = order[r];
|
||||||
|
order[r] = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* add_line:
|
||||||
|
* Add a line to the list of discoveries
|
||||||
|
*/
|
||||||
|
/* VARARGS1 */
|
||||||
|
int
|
||||||
|
add_line(const char *fmt, const char *arg)
|
||||||
|
{
|
||||||
|
WINDOW *tw, *sw;
|
||||||
|
int x, y;
|
||||||
|
char *prompt = "--Press space to continue--";
|
||||||
|
static int maxlen = -1;
|
||||||
|
|
||||||
|
if (line_cnt == 0)
|
||||||
|
{
|
||||||
|
wclear(hw);
|
||||||
|
if (inv_type == INV_SLOW)
|
||||||
|
mpos = 0;
|
||||||
|
}
|
||||||
|
if (inv_type == INV_SLOW)
|
||||||
|
{
|
||||||
|
if (*fmt != '\0')
|
||||||
|
if (msg(fmt, arg) == ESCAPE)
|
||||||
|
return ESCAPE;
|
||||||
|
line_cnt++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (maxlen < 0)
|
||||||
|
maxlen = (int) strlen(prompt);
|
||||||
|
if (line_cnt >= LINES - 1 || fmt == NULL)
|
||||||
|
{
|
||||||
|
if (inv_type == INV_OVER && fmt == NULL && !newpage)
|
||||||
|
{
|
||||||
|
msg("");
|
||||||
|
refresh();
|
||||||
|
tw = newwin(line_cnt + 1, maxlen + 2, 0, COLS - maxlen - 3);
|
||||||
|
sw = subwin(tw, line_cnt + 1, maxlen + 1, 0, COLS - maxlen - 2);
|
||||||
|
for (y = 0; y <= line_cnt; y++)
|
||||||
|
{
|
||||||
|
wmove(sw, y, 0);
|
||||||
|
for (x = 0; x <= maxlen; x++)
|
||||||
|
waddch(sw, mvwinch(hw, y, x));
|
||||||
|
}
|
||||||
|
wmove(tw, line_cnt, 1);
|
||||||
|
waddstr(tw, prompt);
|
||||||
|
/*
|
||||||
|
* if there are lines below, use 'em
|
||||||
|
*/
|
||||||
|
if (LINES > NUMLINES)
|
||||||
|
{
|
||||||
|
if (NUMLINES + line_cnt > LINES)
|
||||||
|
mvwin(tw, LINES - (line_cnt + 1), COLS - maxlen - 3);
|
||||||
|
else
|
||||||
|
mvwin(tw, NUMLINES, 0);
|
||||||
|
}
|
||||||
|
touchwin(tw);
|
||||||
|
wrefresh(tw);
|
||||||
|
wait_for(tw, ' ');
|
||||||
|
if (md_hasclreol())
|
||||||
|
{
|
||||||
|
werase(tw);
|
||||||
|
leaveok(tw, TRUE);
|
||||||
|
wrefresh(tw);
|
||||||
|
}
|
||||||
|
delwin(tw);
|
||||||
|
touchwin(stdscr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wmove(hw, LINES - 1, 0);
|
||||||
|
waddstr(hw, prompt);
|
||||||
|
wrefresh(hw);
|
||||||
|
wait_for(hw, ' ');
|
||||||
|
clearok(curscr, TRUE);
|
||||||
|
wclear(hw);
|
||||||
|
touchwin(stdscr);
|
||||||
|
}
|
||||||
|
newpage = TRUE;
|
||||||
|
line_cnt = 0;
|
||||||
|
maxlen = (int) strlen(prompt);
|
||||||
|
}
|
||||||
|
if (fmt != NULL && !(line_cnt == 0 && *fmt == '\0'))
|
||||||
|
{
|
||||||
|
mvwprintw(hw, line_cnt++, 0, fmt, arg);
|
||||||
|
getyx(hw, y, x);
|
||||||
|
if (maxlen < x)
|
||||||
|
maxlen = x;
|
||||||
|
lastfmt = fmt;
|
||||||
|
lastarg = arg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ~ESCAPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* end_line:
|
||||||
|
* End the list of lines
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
end_line(void)
|
||||||
|
{
|
||||||
|
if (inv_type != INV_SLOW)
|
||||||
|
{
|
||||||
|
if (line_cnt == 1 && !newpage)
|
||||||
|
{
|
||||||
|
mpos = 0;
|
||||||
|
msg(lastfmt, lastarg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
add_line(NULL, NULL);
|
||||||
|
}
|
||||||
|
line_cnt = 0;
|
||||||
|
newpage = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* nothing:
|
||||||
|
* Set up prbuf so that message for "nothing found" is there
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
nothing(int type)
|
||||||
|
{
|
||||||
|
char *sp, *tystr = NULL;
|
||||||
|
|
||||||
|
if (terse)
|
||||||
|
sprintf(prbuf, "Nothing");
|
||||||
|
else
|
||||||
|
sprintf(prbuf, "Haven't discovered anything");
|
||||||
|
if (type != '*')
|
||||||
|
{
|
||||||
|
sp = &prbuf[strlen(prbuf)];
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case POTION: tystr = "potion";
|
||||||
|
when SCROLL: tystr = "scroll";
|
||||||
|
when RING: tystr = "ring";
|
||||||
|
when STICK: tystr = "stick";
|
||||||
|
}
|
||||||
|
sprintf(sp, " about any %ss", tystr);
|
||||||
|
}
|
||||||
|
return prbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* nameit:
|
||||||
|
* Give the proper name to a potion, stick, or ring
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
nameit(const THING *obj, const char *type, const char *which, const struct obj_info *op,
|
||||||
|
const char *(*prfunc)(const THING *))
|
||||||
|
{
|
||||||
|
char *pb;
|
||||||
|
|
||||||
|
if (op->oi_know || op->oi_guess)
|
||||||
|
{
|
||||||
|
if (obj->o_count == 1)
|
||||||
|
sprintf(prbuf, "A %s ", type);
|
||||||
|
else
|
||||||
|
sprintf(prbuf, "%d %ss ", obj->o_count, type);
|
||||||
|
pb = &prbuf[strlen(prbuf)];
|
||||||
|
if (op->oi_know)
|
||||||
|
sprintf(pb, "of %s%s(%s)", op->oi_name, (*prfunc)(obj), which);
|
||||||
|
else if (op->oi_guess)
|
||||||
|
sprintf(pb, "called %s%s(%s)", op->oi_guess, (*prfunc)(obj), which);
|
||||||
|
}
|
||||||
|
else if (obj->o_count == 1)
|
||||||
|
sprintf(prbuf, "A%s %s %s", vowelstr(which), which, type);
|
||||||
|
else
|
||||||
|
sprintf(prbuf, "%d %s %ss", obj->o_count, which, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* nullstr:
|
||||||
|
* Return a pointer to a null-length string
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
nullstr(const THING *ignored)
|
||||||
|
{
|
||||||
|
NOOP(ignored);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
# ifdef MASTER
|
||||||
|
/*
|
||||||
|
* pr_list:
|
||||||
|
* List possible potions, scrolls, etc. for wizard.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
pr_list(void)
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
if (!terse)
|
||||||
|
addmsg("for ");
|
||||||
|
addmsg("what type");
|
||||||
|
if (!terse)
|
||||||
|
addmsg(" of object do you want a list");
|
||||||
|
msg("? ");
|
||||||
|
ch = readchar();
|
||||||
|
msg("");
|
||||||
|
switch (ch)
|
||||||
|
{
|
||||||
|
case POTION:
|
||||||
|
pr_spec(pot_info, MAXPOTIONS);
|
||||||
|
when SCROLL:
|
||||||
|
pr_spec(scr_info, MAXSCROLLS);
|
||||||
|
when RING:
|
||||||
|
pr_spec(ring_info, MAXRINGS);
|
||||||
|
when STICK:
|
||||||
|
pr_spec(ws_info, MAXSTICKS);
|
||||||
|
when ARMOR:
|
||||||
|
pr_spec(arm_info, MAXARMORS);
|
||||||
|
when WEAPON:
|
||||||
|
pr_spec(weap_info, MAXWEAPONS);
|
||||||
|
otherwise:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pr_spec:
|
||||||
|
* Print specific list of possible items to choose from
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
pr_spec(const struct obj_info *info, int nitems)
|
||||||
|
{
|
||||||
|
const struct obj_info *endp;
|
||||||
|
int i, lastprob;
|
||||||
|
|
||||||
|
endp = &info[nitems];
|
||||||
|
lastprob = 0;
|
||||||
|
for (i = '0'; info < endp; i++)
|
||||||
|
{
|
||||||
|
if (i == '9' + 1)
|
||||||
|
i = 'a';
|
||||||
|
sprintf(prbuf, "%c: %%s (%d%%%%)", i, info->oi_prob - lastprob);
|
||||||
|
lastprob = info->oi_prob;
|
||||||
|
add_line(prbuf, info->oi_name);
|
||||||
|
info++;
|
||||||
|
}
|
||||||
|
end_line();
|
||||||
|
}
|
||||||
|
# endif /* MASTER */
|
||||||
17
rogue5/vers.c
Normal file
17
rogue5/vers.c
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
/*
|
||||||
|
* Version number. Whenever a new version number is desired, use sccs
|
||||||
|
* to get vers.c. encstr is declared here to force it to be loaded
|
||||||
|
* before the version number, and therefore not to be written in saved
|
||||||
|
* games.
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const char *release = "5.4.5";
|
||||||
|
const char encstr[] = "\300k||`\251Y.'\305\321\201+\277~r\"]\240_\223=1\341)\222\212\241t;\t$\270\314/<#\201\254";
|
||||||
|
const char statlist[] = "\355kl{+\204\255\313idJ\361\214=4:\311\271\341wK<\312\321\213,,7\271/Rk%\b\312\f\246";
|
||||||
|
const char version[] = "rogue (rogueforge) 09/05/07";
|
||||||
286
rogue5/weapons.c
Normal file
286
rogue5/weapons.c
Normal file
|
|
@ -0,0 +1,286 @@
|
||||||
|
/*
|
||||||
|
* Functions for dealing with problems brought about by weapons
|
||||||
|
*
|
||||||
|
* @(#)weapons.c 4.34 (Berkeley) 02/05/99
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <curses.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "rogue.h"
|
||||||
|
|
||||||
|
#define NO_WEAPON -1
|
||||||
|
|
||||||
|
static const struct init_weaps {
|
||||||
|
char *iw_dam; /* Damage when wielded */
|
||||||
|
char *iw_hrl; /* Damage when thrown */
|
||||||
|
int iw_launch; /* Launching weapon */
|
||||||
|
int iw_flags; /* Miscellaneous flags */
|
||||||
|
} init_dam[MAXWEAPONS] = {
|
||||||
|
{ "2x4", "1x3", NO_WEAPON, 0, }, /* Mace */
|
||||||
|
{ "3x4", "1x2", NO_WEAPON, 0, }, /* Long sword */
|
||||||
|
{ "1x1", "1x1", NO_WEAPON, 0, }, /* Bow */
|
||||||
|
{ "1x1", "2x3", BOW, ISMANY|ISMISL, }, /* Arrow */
|
||||||
|
{ "1x6", "1x4", NO_WEAPON, ISMISL|ISMISL, }, /* Dagger */
|
||||||
|
{ "4x4", "1x2", NO_WEAPON, 0, }, /* 2h sword */
|
||||||
|
{ "1x1", "1x3", NO_WEAPON, ISMANY|ISMISL, }, /* Dart */
|
||||||
|
{ "1x2", "2x4", NO_WEAPON, ISMANY|ISMISL, }, /* Shuriken */
|
||||||
|
{ "2x3", "1x6", NO_WEAPON, ISMISL, }, /* Spear */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* missile:
|
||||||
|
* Fire a missile in a given direction
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
missile(int ydelta, int xdelta)
|
||||||
|
{
|
||||||
|
THING *obj;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get which thing we are hurling
|
||||||
|
*/
|
||||||
|
if ((obj = get_item("throw", WEAPON)) == NULL)
|
||||||
|
return;
|
||||||
|
if (!dropcheck(obj) || is_current(obj))
|
||||||
|
return;
|
||||||
|
obj = leave_pack(obj, TRUE, FALSE);
|
||||||
|
do_motion(obj, ydelta, xdelta);
|
||||||
|
/*
|
||||||
|
* AHA! Here it has hit something. If it is a wall or a door,
|
||||||
|
* or if it misses (combat) the monster, put it on the floor
|
||||||
|
*/
|
||||||
|
if (moat(obj->o_pos.y, obj->o_pos.x) == NULL ||
|
||||||
|
!hit_monster(unc(obj->o_pos), obj))
|
||||||
|
fall(obj, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* do_motion:
|
||||||
|
* Do the actual motion on the screen done by an object traveling
|
||||||
|
* across the room
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
do_motion(THING *obj, int ydelta, int xdelta)
|
||||||
|
{
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Come fly with us ...
|
||||||
|
*/
|
||||||
|
obj->o_pos = hero;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Erase the old one
|
||||||
|
*/
|
||||||
|
if (!ce(obj->o_pos, hero) && cansee(unc(obj->o_pos)) && !terse)
|
||||||
|
{
|
||||||
|
ch = chat(obj->o_pos.y, obj->o_pos.x);
|
||||||
|
if (ch == FLOOR && !show_floor())
|
||||||
|
ch = ' ';
|
||||||
|
mvaddch(obj->o_pos.y, obj->o_pos.x, ch);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Get the new position
|
||||||
|
*/
|
||||||
|
obj->o_pos.y += ydelta;
|
||||||
|
obj->o_pos.x += xdelta;
|
||||||
|
if (step_ok(ch = winat(obj->o_pos.y, obj->o_pos.x)) && ch != DOOR)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* It hasn't hit anything yet, so display it
|
||||||
|
* If it alright.
|
||||||
|
*/
|
||||||
|
if (cansee(unc(obj->o_pos)) && !terse)
|
||||||
|
{
|
||||||
|
mvaddch(obj->o_pos.y, obj->o_pos.x, obj->o_type);
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fall:
|
||||||
|
* Drop an item someplace around here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
fall(THING *obj, int pr)
|
||||||
|
{
|
||||||
|
PLACE *pp;
|
||||||
|
coord fpos;
|
||||||
|
|
||||||
|
if (fallpos(&obj->o_pos, &fpos))
|
||||||
|
{
|
||||||
|
pp = INDEX(fpos.y, fpos.x);
|
||||||
|
pp->p_ch = obj->o_type;
|
||||||
|
obj->o_pos = fpos;
|
||||||
|
if (cansee(fpos.y, fpos.x))
|
||||||
|
{
|
||||||
|
if (pp->p_monst != NULL)
|
||||||
|
pp->p_monst->t_oldch = obj->o_type;
|
||||||
|
else
|
||||||
|
mvaddch(fpos.y, fpos.x, obj->o_type);
|
||||||
|
}
|
||||||
|
attach(lvl_obj, obj);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (pr)
|
||||||
|
{
|
||||||
|
if (has_hit)
|
||||||
|
{
|
||||||
|
endmsg();
|
||||||
|
has_hit = FALSE;
|
||||||
|
}
|
||||||
|
msg("the %s vanishes as it hits the ground",
|
||||||
|
weap_info[obj->o_which].oi_name);
|
||||||
|
}
|
||||||
|
discard(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* init_weapon:
|
||||||
|
* Set up the initial goodies for a weapon
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
init_weapon(THING *weap, int which)
|
||||||
|
{
|
||||||
|
const struct init_weaps *iwp;
|
||||||
|
|
||||||
|
weap->o_type = WEAPON;
|
||||||
|
weap->o_which = which;
|
||||||
|
iwp = &init_dam[which];
|
||||||
|
strncpy(weap->o_damage, iwp->iw_dam, sizeof(weap->o_damage));
|
||||||
|
strncpy(weap->o_hurldmg,iwp->iw_hrl, sizeof(weap->o_hurldmg));
|
||||||
|
weap->o_launch = iwp->iw_launch;
|
||||||
|
weap->o_flags = iwp->iw_flags;
|
||||||
|
weap->o_hplus = 0;
|
||||||
|
weap->o_dplus = 0;
|
||||||
|
if (which == DAGGER)
|
||||||
|
{
|
||||||
|
weap->o_count = rnd(4) + 2;
|
||||||
|
weap->o_group = group++;
|
||||||
|
}
|
||||||
|
else if (weap->o_flags & ISMANY)
|
||||||
|
{
|
||||||
|
weap->o_count = rnd(8) + 8;
|
||||||
|
weap->o_group = group++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
weap->o_count = 1;
|
||||||
|
weap->o_group = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* hit_monster:
|
||||||
|
* Does the missile hit the monster?
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
hit_monster(int y, int x, const THING *obj)
|
||||||
|
{
|
||||||
|
coord mp;
|
||||||
|
|
||||||
|
mp.y = y;
|
||||||
|
mp.x = x;
|
||||||
|
return fight(&mp, obj, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* num:
|
||||||
|
* Figure out the plus number for armor/weapons
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
num(int n1, int n2, int type)
|
||||||
|
{
|
||||||
|
static char numbuf[10];
|
||||||
|
|
||||||
|
sprintf(numbuf, n1 < 0 ? "%d" : "+%d", n1);
|
||||||
|
if (type == WEAPON)
|
||||||
|
sprintf(&numbuf[strlen(numbuf)], n2 < 0 ? ",%d" : ",+%d", n2);
|
||||||
|
return numbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* wield:
|
||||||
|
* Pull out a certain weapon
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
wield(void)
|
||||||
|
{
|
||||||
|
THING *obj, *oweapon;
|
||||||
|
char *sp;
|
||||||
|
|
||||||
|
oweapon = cur_weapon;
|
||||||
|
if (!dropcheck(cur_weapon))
|
||||||
|
{
|
||||||
|
cur_weapon = oweapon;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cur_weapon = oweapon;
|
||||||
|
if ((obj = get_item("wield", WEAPON)) == NULL)
|
||||||
|
{
|
||||||
|
bad:
|
||||||
|
after = FALSE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj->o_type == ARMOR)
|
||||||
|
{
|
||||||
|
msg("you can't wield armor");
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
if (is_current(obj))
|
||||||
|
goto bad;
|
||||||
|
|
||||||
|
sp = inv_name(obj, TRUE);
|
||||||
|
cur_weapon = obj;
|
||||||
|
if (!terse)
|
||||||
|
addmsg("you are now ");
|
||||||
|
msg("wielding %s (%c)", sp, obj->o_packch);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fallpos:
|
||||||
|
* Pick a random position around the give (y, x) coordinates
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
fallpos(const coord *pos, coord *newpos)
|
||||||
|
{
|
||||||
|
int y, x, cnt, ch;
|
||||||
|
|
||||||
|
cnt = 0;
|
||||||
|
for (y = pos->y - 1; y <= pos->y + 1; y++)
|
||||||
|
for (x = pos->x - 1; x <= pos->x + 1; x++)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* check to make certain the spot is empty, if it is,
|
||||||
|
* put the object there, set it in the level list
|
||||||
|
* and re-draw the room if he can see it
|
||||||
|
*/
|
||||||
|
if (y == hero.y && x == hero.x)
|
||||||
|
continue;
|
||||||
|
if (((ch = chat(y, x)) == FLOOR || ch == PASSAGE)
|
||||||
|
&& rnd(++cnt) == 0)
|
||||||
|
{
|
||||||
|
newpos->y = y;
|
||||||
|
newpos->x = x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (cnt != 0);
|
||||||
|
}
|
||||||
285
rogue5/wizard.c
Normal file
285
rogue5/wizard.c
Normal file
|
|
@ -0,0 +1,285 @@
|
||||||
|
/*
|
||||||
|
* Special wizard commands (some of which are also non-wizard commands
|
||||||
|
* under strange circumstances)
|
||||||
|
*
|
||||||
|
* @(#)wizard.c 4.30 (Berkeley) 02/05/99
|
||||||
|
*
|
||||||
|
* Rogue: Exploring the Dungeons of Doom
|
||||||
|
* Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <curses.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "rogue.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* whatis:
|
||||||
|
* What a certin object is
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
whatis(int insist, int type)
|
||||||
|
{
|
||||||
|
THING *obj;
|
||||||
|
|
||||||
|
if (pack == NULL)
|
||||||
|
{
|
||||||
|
msg("you don't have anything in your pack to identify");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
obj = get_item("identify", type);
|
||||||
|
if (insist)
|
||||||
|
{
|
||||||
|
if (n_objs == 0)
|
||||||
|
return;
|
||||||
|
else if (obj == NULL)
|
||||||
|
msg("you must identify something");
|
||||||
|
else if (type && obj->o_type != type &&
|
||||||
|
!(type == R_OR_S && (obj->o_type == RING || obj->o_type == STICK)) )
|
||||||
|
msg("you must identify a %s", type_name(type));
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (obj->o_type)
|
||||||
|
{
|
||||||
|
case SCROLL:
|
||||||
|
set_know(obj, scr_info);
|
||||||
|
when POTION:
|
||||||
|
set_know(obj, pot_info);
|
||||||
|
when STICK:
|
||||||
|
set_know(obj, ws_info);
|
||||||
|
when WEAPON:
|
||||||
|
case ARMOR:
|
||||||
|
obj->o_flags |= ISKNOW;
|
||||||
|
when RING:
|
||||||
|
set_know(obj, ring_info);
|
||||||
|
}
|
||||||
|
msg(inv_name(obj, FALSE));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* set_know:
|
||||||
|
* Set things up when we really know what a thing is
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
set_know(THING *obj, struct obj_info *info)
|
||||||
|
{
|
||||||
|
char **guess;
|
||||||
|
|
||||||
|
info[obj->o_which].oi_know = TRUE;
|
||||||
|
obj->o_flags |= ISKNOW;
|
||||||
|
guess = &info[obj->o_which].oi_guess;
|
||||||
|
if (*guess)
|
||||||
|
{
|
||||||
|
free(*guess);
|
||||||
|
*guess = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* type_name:
|
||||||
|
* Return a pointer to the name of the type
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
type_name(int type)
|
||||||
|
{
|
||||||
|
struct h_list *hp;
|
||||||
|
struct h_list tlist[] = {
|
||||||
|
{POTION, "potion", FALSE},
|
||||||
|
{SCROLL, "scroll", FALSE},
|
||||||
|
{FOOD, "food", FALSE},
|
||||||
|
{R_OR_S, "ring, wand or staff", FALSE},
|
||||||
|
{RING, "ring", FALSE},
|
||||||
|
{STICK, "wand or staff", FALSE},
|
||||||
|
{WEAPON, "weapon", FALSE},
|
||||||
|
{ARMOR, "suit of armor", FALSE},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (hp = tlist; hp->h_ch; hp++)
|
||||||
|
if (type == hp->h_ch)
|
||||||
|
return hp->h_desc;
|
||||||
|
/* NOTREACHED */
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MASTER
|
||||||
|
/*
|
||||||
|
* create_obj:
|
||||||
|
* wizard command for getting anything he wants
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
create_obj(void)
|
||||||
|
{
|
||||||
|
THING *obj;
|
||||||
|
int ch, bless;
|
||||||
|
|
||||||
|
obj = new_item();
|
||||||
|
msg("type of item: ");
|
||||||
|
obj->o_type = readchar();
|
||||||
|
mpos = 0;
|
||||||
|
msg("which %c do you want? (0-f)", obj->o_type);
|
||||||
|
obj->o_which = (isdigit((ch = readchar())) ? ch - '0' : ch - 'a' + 10);
|
||||||
|
obj->o_group = 0;
|
||||||
|
obj->o_count = 1;
|
||||||
|
mpos = 0;
|
||||||
|
if (obj->o_type == WEAPON || obj->o_type == ARMOR)
|
||||||
|
{
|
||||||
|
msg("blessing? (+,-,n)");
|
||||||
|
bless = readchar();
|
||||||
|
mpos = 0;
|
||||||
|
if (bless == '-')
|
||||||
|
obj->o_flags |= ISCURSED;
|
||||||
|
if (obj->o_type == WEAPON)
|
||||||
|
{
|
||||||
|
init_weapon(obj, obj->o_which);
|
||||||
|
if (bless == '-')
|
||||||
|
obj->o_hplus -= rnd(3)+1;
|
||||||
|
if (bless == '+')
|
||||||
|
obj->o_hplus += rnd(3)+1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
obj->o_arm = a_class[obj->o_which];
|
||||||
|
if (bless == '-')
|
||||||
|
obj->o_arm += rnd(3)+1;
|
||||||
|
if (bless == '+')
|
||||||
|
obj->o_arm -= rnd(3)+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (obj->o_type == RING)
|
||||||
|
switch (obj->o_which)
|
||||||
|
{
|
||||||
|
case R_PROTECT:
|
||||||
|
case R_ADDSTR:
|
||||||
|
case R_ADDHIT:
|
||||||
|
case R_ADDDAM:
|
||||||
|
msg("blessing? (+,-,n)");
|
||||||
|
bless = readchar();
|
||||||
|
mpos = 0;
|
||||||
|
if (bless == '-')
|
||||||
|
obj->o_flags |= ISCURSED;
|
||||||
|
obj->o_arm = (bless == '-' ? -1 : rnd(2) + 1);
|
||||||
|
when R_AGGR:
|
||||||
|
case R_TELEPORT:
|
||||||
|
obj->o_flags |= ISCURSED;
|
||||||
|
}
|
||||||
|
else if (obj->o_type == STICK)
|
||||||
|
fix_stick(obj);
|
||||||
|
else if (obj->o_type == GOLD)
|
||||||
|
{
|
||||||
|
msg("how much?");
|
||||||
|
get_num(&obj->o_goldval, stdscr);
|
||||||
|
}
|
||||||
|
add_pack(obj, FALSE);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* telport:
|
||||||
|
* Bamf the hero someplace else
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
teleport(void)
|
||||||
|
{
|
||||||
|
coord c;
|
||||||
|
|
||||||
|
mvaddch(hero.y, hero.x, floor_at());
|
||||||
|
find_floor(NULL, &c, FALSE, TRUE);
|
||||||
|
if (roomin(&c) != proom)
|
||||||
|
{
|
||||||
|
leave_room(&hero);
|
||||||
|
hero = c;
|
||||||
|
enter_room(&hero);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hero = c;
|
||||||
|
look(TRUE);
|
||||||
|
}
|
||||||
|
mvaddch(hero.y, hero.x, PLAYER);
|
||||||
|
/*
|
||||||
|
* turn off ISHELD in case teleportation was done while fighting
|
||||||
|
* a Flytrap
|
||||||
|
*/
|
||||||
|
if (on(player, ISHELD)) {
|
||||||
|
player.t_flags &= ~ISHELD;
|
||||||
|
vf_hit = 0;
|
||||||
|
strcpy(monsters['F'-'A'].m_stats.s_dmg, "000x0");
|
||||||
|
}
|
||||||
|
no_move = 0;
|
||||||
|
count = 0;
|
||||||
|
running = FALSE;
|
||||||
|
flush_type();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MASTER
|
||||||
|
/*
|
||||||
|
* passwd:
|
||||||
|
* See if user knows password
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
passwd(void)
|
||||||
|
{
|
||||||
|
char *sp;
|
||||||
|
int c;
|
||||||
|
static char buf[MAXSTR];
|
||||||
|
|
||||||
|
msg("wizard's Password:");
|
||||||
|
mpos = 0;
|
||||||
|
sp = buf;
|
||||||
|
while ((c = readchar()) != '\n' && c != '\r' && c != ESCAPE)
|
||||||
|
if (c == md_killchar())
|
||||||
|
sp = buf;
|
||||||
|
else if (c == md_erasechar() && sp > buf)
|
||||||
|
sp--;
|
||||||
|
else
|
||||||
|
*sp++ = (char) c;
|
||||||
|
if (sp == buf)
|
||||||
|
return FALSE;
|
||||||
|
*sp = '\0';
|
||||||
|
return (strcmp(PASSWD, md_crypt(buf, "mT")) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* show_map:
|
||||||
|
* Print out the map for the wizard
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
show_map(void)
|
||||||
|
{
|
||||||
|
int y, x, real;
|
||||||
|
|
||||||
|
wclear(hw);
|
||||||
|
for (y = 1; y < NUMLINES - 1; y++)
|
||||||
|
for (x = 0; x < NUMCOLS; x++)
|
||||||
|
{
|
||||||
|
real = flat(y, x) & F_REAL;
|
||||||
|
if (!real)
|
||||||
|
wstandout(hw);
|
||||||
|
wmove(hw, y, x);
|
||||||
|
waddch(hw, chat(y, x));
|
||||||
|
if (!(real & F_REAL))
|
||||||
|
wstandend(hw);
|
||||||
|
}
|
||||||
|
show_win("---More (level map)---");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
707
rogue5/xcrypt.c
Normal file
707
rogue5/xcrypt.c
Normal file
|
|
@ -0,0 +1,707 @@
|
||||||
|
/*
|
||||||
|
* FreeSec: libcrypt
|
||||||
|
*
|
||||||
|
* Copyright (C) 1994 David Burren
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name(s) of the author(s) nor the names of other contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This is an original implementation of the DES and the crypt(3) interfaces
|
||||||
|
* by David Burren <davidb@werj.com.au>.
|
||||||
|
*
|
||||||
|
* An excellent reference on the underlying algorithm (and related
|
||||||
|
* algorithms) is:
|
||||||
|
*
|
||||||
|
* B. Schneier, Applied Cryptography: protocols, algorithms,
|
||||||
|
* and source code in C, John Wiley & Sons, 1994.
|
||||||
|
*
|
||||||
|
* Note that in that book's description of DES the lookups for the initial,
|
||||||
|
* pbox, and final permutations are inverted (this has been brought to the
|
||||||
|
* attention of the author). A list of errata for this book has been
|
||||||
|
* posted to the sci.crypt newsgroup by the author and is available for FTP.
|
||||||
|
*
|
||||||
|
* NOTE:
|
||||||
|
* This file has a static version of des_setkey() so that crypt.o exports
|
||||||
|
* only the crypt() interface. This is required to make binaries linked
|
||||||
|
* against crypt.o exportable or re-exportable from the USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static unsigned int md_endian = 0x01020304;
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
xntohl(unsigned int x)
|
||||||
|
{
|
||||||
|
if ( *((char *)&md_endian) == 0x01 )
|
||||||
|
return(x);
|
||||||
|
else
|
||||||
|
return( ((x & 0x000000ffU) << 24) |
|
||||||
|
((x & 0x0000ff00U) << 8) |
|
||||||
|
((x & 0x00ff0000U) >> 8) |
|
||||||
|
((x & 0xff000000U) >> 24) );
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
xhtonl(unsigned int x)
|
||||||
|
{
|
||||||
|
if ( *((char *)&md_endian) == 0x01 )
|
||||||
|
return(x);
|
||||||
|
else
|
||||||
|
return( ((x & 0x000000ffU) << 24) |
|
||||||
|
((x & 0x0000ff00U) << 8) |
|
||||||
|
((x & 0x00ff0000U) >> 8) |
|
||||||
|
((x & 0xff000000U) >> 24) );
|
||||||
|
}
|
||||||
|
|
||||||
|
#define _PASSWORD_EFMT1 '_'
|
||||||
|
|
||||||
|
static unsigned char IP[64] = {
|
||||||
|
58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
|
||||||
|
62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
|
||||||
|
57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
|
||||||
|
61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned char inv_key_perm[64];
|
||||||
|
static unsigned char key_perm[56] = {
|
||||||
|
57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
|
||||||
|
10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
|
||||||
|
63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
|
||||||
|
14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned char key_shifts[16] = {
|
||||||
|
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned char inv_comp_perm[56];
|
||||||
|
static unsigned char comp_perm[48] = {
|
||||||
|
14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
|
||||||
|
23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
|
||||||
|
41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
|
||||||
|
44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No E box is used, as it's replaced by some ANDs, shifts, and ORs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static unsigned char u_sbox[8][64];
|
||||||
|
static unsigned char sbox[8][64] = {
|
||||||
|
{
|
||||||
|
14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
|
||||||
|
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
|
||||||
|
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
|
||||||
|
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
|
||||||
|
},
|
||||||
|
{
|
||||||
|
15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
|
||||||
|
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
|
||||||
|
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
|
||||||
|
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
|
||||||
|
},
|
||||||
|
{
|
||||||
|
10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
|
||||||
|
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
|
||||||
|
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
|
||||||
|
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
|
||||||
|
},
|
||||||
|
{
|
||||||
|
7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
|
||||||
|
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
|
||||||
|
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
|
||||||
|
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
|
||||||
|
},
|
||||||
|
{
|
||||||
|
2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
|
||||||
|
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
|
||||||
|
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
|
||||||
|
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
|
||||||
|
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
|
||||||
|
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
|
||||||
|
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
|
||||||
|
},
|
||||||
|
{
|
||||||
|
4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
|
||||||
|
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
|
||||||
|
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
|
||||||
|
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
|
||||||
|
},
|
||||||
|
{
|
||||||
|
13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
|
||||||
|
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
|
||||||
|
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
|
||||||
|
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned char un_pbox[32];
|
||||||
|
static unsigned char pbox[32] = {
|
||||||
|
16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
|
||||||
|
2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned int bits32[32] =
|
||||||
|
{
|
||||||
|
0x80000000, 0x40000000, 0x20000000, 0x10000000,
|
||||||
|
0x08000000, 0x04000000, 0x02000000, 0x01000000,
|
||||||
|
0x00800000, 0x00400000, 0x00200000, 0x00100000,
|
||||||
|
0x00080000, 0x00040000, 0x00020000, 0x00010000,
|
||||||
|
0x00008000, 0x00004000, 0x00002000, 0x00001000,
|
||||||
|
0x00000800, 0x00000400, 0x00000200, 0x00000100,
|
||||||
|
0x00000080, 0x00000040, 0x00000020, 0x00000010,
|
||||||
|
0x00000008, 0x00000004, 0x00000002, 0x00000001
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned char bits8[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
|
||||||
|
|
||||||
|
static unsigned int saltbits;
|
||||||
|
static int old_salt;
|
||||||
|
static unsigned int *bits28, *bits24;
|
||||||
|
static unsigned char init_perm[64], final_perm[64];
|
||||||
|
static unsigned int en_keysl[16], en_keysr[16];
|
||||||
|
static unsigned int de_keysl[16], de_keysr[16];
|
||||||
|
static int des_initialised = 0;
|
||||||
|
static unsigned char m_sbox[4][4096];
|
||||||
|
static unsigned int psbox[4][256];
|
||||||
|
static unsigned int ip_maskl[8][256], ip_maskr[8][256];
|
||||||
|
static unsigned int fp_maskl[8][256], fp_maskr[8][256];
|
||||||
|
static unsigned int key_perm_maskl[8][128], key_perm_maskr[8][128];
|
||||||
|
static unsigned int comp_maskl[8][128], comp_maskr[8][128];
|
||||||
|
static unsigned int old_rawkey0, old_rawkey1;
|
||||||
|
|
||||||
|
static unsigned char ascii64[] =
|
||||||
|
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||||
|
/* 0000000000111111111122222222223333333333444444444455555555556666 */
|
||||||
|
/* 0123456789012345678901234567890123456789012345678901234567890123 */
|
||||||
|
|
||||||
|
static __inline int
|
||||||
|
ascii_to_bin(int ch)
|
||||||
|
{
|
||||||
|
if (ch > 'z')
|
||||||
|
return(0);
|
||||||
|
if (ch >= 'a')
|
||||||
|
return(ch - 'a' + 38);
|
||||||
|
if (ch > 'Z')
|
||||||
|
return(0);
|
||||||
|
if (ch >= 'A')
|
||||||
|
return(ch - 'A' + 12);
|
||||||
|
if (ch > '9')
|
||||||
|
return(0);
|
||||||
|
if (ch >= '.')
|
||||||
|
return(ch - '.');
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
des_init(void)
|
||||||
|
{
|
||||||
|
int i, j, b, k, inbit, obit;
|
||||||
|
unsigned int *p, *il, *ir, *fl, *fr;
|
||||||
|
|
||||||
|
old_rawkey0 = old_rawkey1 = 0;
|
||||||
|
saltbits = 0;
|
||||||
|
old_salt = 0;
|
||||||
|
bits24 = (bits28 = bits32 + 4) + 4;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Invert the S-boxes, reordering the input bits.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
for (j = 0; j < 64; j++) {
|
||||||
|
b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf);
|
||||||
|
u_sbox[i][j] = sbox[i][b];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert the inverted S-boxes into 4 arrays of 8 bits.
|
||||||
|
* Each will handle 12 bits of the S-box input.
|
||||||
|
*/
|
||||||
|
for (b = 0; b < 4; b++)
|
||||||
|
for (i = 0; i < 64; i++)
|
||||||
|
for (j = 0; j < 64; j++)
|
||||||
|
m_sbox[b][(i << 6) | j] =
|
||||||
|
(u_sbox[(b << 1)][i] << 4) |
|
||||||
|
u_sbox[(b << 1) + 1][j];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up the initial & final permutations into a useful form, and
|
||||||
|
* initialise the inverted key permutation.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < 64; i++) {
|
||||||
|
init_perm[final_perm[i] = IP[i] - 1] = (unsigned char) i;
|
||||||
|
inv_key_perm[i] = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Invert the key permutation and initialise the inverted key
|
||||||
|
* compression permutation.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < 56; i++) {
|
||||||
|
inv_key_perm[key_perm[i] - 1] = (unsigned char) i;
|
||||||
|
inv_comp_perm[i] = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Invert the key compression permutation.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < 48; i++) {
|
||||||
|
inv_comp_perm[comp_perm[i] - 1] = (unsigned char) i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up the OR-mask arrays for the initial and final permutations,
|
||||||
|
* and for the key initial and compression permutations.
|
||||||
|
*/
|
||||||
|
for (k = 0; k < 8; k++) {
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
*(il = &ip_maskl[k][i]) = 0;
|
||||||
|
*(ir = &ip_maskr[k][i]) = 0;
|
||||||
|
*(fl = &fp_maskl[k][i]) = 0;
|
||||||
|
*(fr = &fp_maskr[k][i]) = 0;
|
||||||
|
for (j = 0; j < 8; j++) {
|
||||||
|
inbit = 8 * k + j;
|
||||||
|
if (i & bits8[j]) {
|
||||||
|
if ((obit = init_perm[inbit]) < 32)
|
||||||
|
*il |= bits32[obit];
|
||||||
|
else
|
||||||
|
*ir |= bits32[obit-32];
|
||||||
|
if ((obit = final_perm[inbit]) < 32)
|
||||||
|
*fl |= bits32[obit];
|
||||||
|
else
|
||||||
|
*fr |= bits32[obit - 32];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < 128; i++) {
|
||||||
|
*(il = &key_perm_maskl[k][i]) = 0;
|
||||||
|
*(ir = &key_perm_maskr[k][i]) = 0;
|
||||||
|
for (j = 0; j < 7; j++) {
|
||||||
|
inbit = 8 * k + j;
|
||||||
|
if (i & bits8[j + 1]) {
|
||||||
|
if ((obit = inv_key_perm[inbit]) == 255)
|
||||||
|
continue;
|
||||||
|
if (obit < 28)
|
||||||
|
*il |= bits28[obit];
|
||||||
|
else
|
||||||
|
*ir |= bits28[obit - 28];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*(il = &comp_maskl[k][i]) = 0;
|
||||||
|
*(ir = &comp_maskr[k][i]) = 0;
|
||||||
|
for (j = 0; j < 7; j++) {
|
||||||
|
inbit = 7 * k + j;
|
||||||
|
if (i & bits8[j + 1]) {
|
||||||
|
if ((obit=inv_comp_perm[inbit]) == 255)
|
||||||
|
continue;
|
||||||
|
if (obit < 24)
|
||||||
|
*il |= bits24[obit];
|
||||||
|
else
|
||||||
|
*ir |= bits24[obit - 24];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Invert the P-box permutation, and convert into OR-masks for
|
||||||
|
* handling the output of the S-box arrays setup above.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < 32; i++)
|
||||||
|
un_pbox[pbox[i] - 1] = (unsigned char) i;
|
||||||
|
|
||||||
|
for (b = 0; b < 4; b++)
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
*(p = &psbox[b][i]) = 0;
|
||||||
|
for (j = 0; j < 8; j++) {
|
||||||
|
if (i & bits8[j])
|
||||||
|
*p |= bits32[un_pbox[8 * b + j]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
des_initialised = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
setup_salt(int salt)
|
||||||
|
{
|
||||||
|
unsigned int obit, saltbit;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (salt == old_salt)
|
||||||
|
return;
|
||||||
|
old_salt = salt;
|
||||||
|
|
||||||
|
saltbits = 0;
|
||||||
|
saltbit = 1;
|
||||||
|
obit = 0x800000;
|
||||||
|
for (i = 0; i < 24; i++) {
|
||||||
|
if (salt & saltbit)
|
||||||
|
saltbits |= obit;
|
||||||
|
saltbit <<= 1;
|
||||||
|
obit >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
des_setkey(const char *key)
|
||||||
|
{
|
||||||
|
unsigned int k0, k1, rawkey0, rawkey1;
|
||||||
|
int shifts, round;
|
||||||
|
|
||||||
|
if (!des_initialised)
|
||||||
|
des_init();
|
||||||
|
|
||||||
|
rawkey0 = xntohl(*(unsigned int *) key);
|
||||||
|
rawkey1 = xntohl(*(unsigned int *) (key + 4));
|
||||||
|
|
||||||
|
if ((rawkey0 | rawkey1)
|
||||||
|
&& rawkey0 == old_rawkey0
|
||||||
|
&& rawkey1 == old_rawkey1) {
|
||||||
|
/*
|
||||||
|
* Already setup for this key.
|
||||||
|
* This optimisation fails on a zero key (which is weak and
|
||||||
|
* has bad parity anyway) in order to simplify the starting
|
||||||
|
* conditions.
|
||||||
|
*/
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
old_rawkey0 = rawkey0;
|
||||||
|
old_rawkey1 = rawkey1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do key permutation and split into two 28-bit subkeys.
|
||||||
|
*/
|
||||||
|
k0 = key_perm_maskl[0][rawkey0 >> 25]
|
||||||
|
| key_perm_maskl[1][(rawkey0 >> 17) & 0x7f]
|
||||||
|
| key_perm_maskl[2][(rawkey0 >> 9) & 0x7f]
|
||||||
|
| key_perm_maskl[3][(rawkey0 >> 1) & 0x7f]
|
||||||
|
| key_perm_maskl[4][rawkey1 >> 25]
|
||||||
|
| key_perm_maskl[5][(rawkey1 >> 17) & 0x7f]
|
||||||
|
| key_perm_maskl[6][(rawkey1 >> 9) & 0x7f]
|
||||||
|
| key_perm_maskl[7][(rawkey1 >> 1) & 0x7f];
|
||||||
|
k1 = key_perm_maskr[0][rawkey0 >> 25]
|
||||||
|
| key_perm_maskr[1][(rawkey0 >> 17) & 0x7f]
|
||||||
|
| key_perm_maskr[2][(rawkey0 >> 9) & 0x7f]
|
||||||
|
| key_perm_maskr[3][(rawkey0 >> 1) & 0x7f]
|
||||||
|
| key_perm_maskr[4][rawkey1 >> 25]
|
||||||
|
| key_perm_maskr[5][(rawkey1 >> 17) & 0x7f]
|
||||||
|
| key_perm_maskr[6][(rawkey1 >> 9) & 0x7f]
|
||||||
|
| key_perm_maskr[7][(rawkey1 >> 1) & 0x7f];
|
||||||
|
/*
|
||||||
|
* Rotate subkeys and do compression permutation.
|
||||||
|
*/
|
||||||
|
shifts = 0;
|
||||||
|
for (round = 0; round < 16; round++) {
|
||||||
|
unsigned int t0, t1;
|
||||||
|
|
||||||
|
shifts += key_shifts[round];
|
||||||
|
|
||||||
|
t0 = (k0 << shifts) | (k0 >> (28 - shifts));
|
||||||
|
t1 = (k1 << shifts) | (k1 >> (28 - shifts));
|
||||||
|
|
||||||
|
de_keysl[15 - round] =
|
||||||
|
en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f]
|
||||||
|
| comp_maskl[1][(t0 >> 14) & 0x7f]
|
||||||
|
| comp_maskl[2][(t0 >> 7) & 0x7f]
|
||||||
|
| comp_maskl[3][t0 & 0x7f]
|
||||||
|
| comp_maskl[4][(t1 >> 21) & 0x7f]
|
||||||
|
| comp_maskl[5][(t1 >> 14) & 0x7f]
|
||||||
|
| comp_maskl[6][(t1 >> 7) & 0x7f]
|
||||||
|
| comp_maskl[7][t1 & 0x7f];
|
||||||
|
|
||||||
|
de_keysr[15 - round] =
|
||||||
|
en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f]
|
||||||
|
| comp_maskr[1][(t0 >> 14) & 0x7f]
|
||||||
|
| comp_maskr[2][(t0 >> 7) & 0x7f]
|
||||||
|
| comp_maskr[3][t0 & 0x7f]
|
||||||
|
| comp_maskr[4][(t1 >> 21) & 0x7f]
|
||||||
|
| comp_maskr[5][(t1 >> 14) & 0x7f]
|
||||||
|
| comp_maskr[6][(t1 >> 7) & 0x7f]
|
||||||
|
| comp_maskr[7][t1 & 0x7f];
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_des(unsigned int l_in, unsigned int r_in, unsigned int *l_out,
|
||||||
|
unsigned int *r_out, int count)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format.
|
||||||
|
*/
|
||||||
|
unsigned int l, r, *kl, *kr, *kl1, *kr1;
|
||||||
|
unsigned int f = 0, r48l, r48r;
|
||||||
|
int round;
|
||||||
|
|
||||||
|
if (count == 0) {
|
||||||
|
return(1);
|
||||||
|
} else if (count > 0) {
|
||||||
|
/*
|
||||||
|
* Encrypting
|
||||||
|
*/
|
||||||
|
kl1 = en_keysl;
|
||||||
|
kr1 = en_keysr;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Decrypting
|
||||||
|
*/
|
||||||
|
count = -count;
|
||||||
|
kl1 = de_keysl;
|
||||||
|
kr1 = de_keysr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do initial permutation (IP).
|
||||||
|
*/
|
||||||
|
l = ip_maskl[0][l_in >> 24]
|
||||||
|
| ip_maskl[1][(l_in >> 16) & 0xff]
|
||||||
|
| ip_maskl[2][(l_in >> 8) & 0xff]
|
||||||
|
| ip_maskl[3][l_in & 0xff]
|
||||||
|
| ip_maskl[4][r_in >> 24]
|
||||||
|
| ip_maskl[5][(r_in >> 16) & 0xff]
|
||||||
|
| ip_maskl[6][(r_in >> 8) & 0xff]
|
||||||
|
| ip_maskl[7][r_in & 0xff];
|
||||||
|
r = ip_maskr[0][l_in >> 24]
|
||||||
|
| ip_maskr[1][(l_in >> 16) & 0xff]
|
||||||
|
| ip_maskr[2][(l_in >> 8) & 0xff]
|
||||||
|
| ip_maskr[3][l_in & 0xff]
|
||||||
|
| ip_maskr[4][r_in >> 24]
|
||||||
|
| ip_maskr[5][(r_in >> 16) & 0xff]
|
||||||
|
| ip_maskr[6][(r_in >> 8) & 0xff]
|
||||||
|
| ip_maskr[7][r_in & 0xff];
|
||||||
|
|
||||||
|
while (count--) {
|
||||||
|
/*
|
||||||
|
* Do each round.
|
||||||
|
*/
|
||||||
|
kl = kl1;
|
||||||
|
kr = kr1;
|
||||||
|
round = 16;
|
||||||
|
while (round--) {
|
||||||
|
/*
|
||||||
|
* Expand R to 48 bits (simulate the E-box).
|
||||||
|
*/
|
||||||
|
r48l = ((r & 0x00000001) << 23)
|
||||||
|
| ((r & 0xf8000000) >> 9)
|
||||||
|
| ((r & 0x1f800000) >> 11)
|
||||||
|
| ((r & 0x01f80000) >> 13)
|
||||||
|
| ((r & 0x001f8000) >> 15);
|
||||||
|
|
||||||
|
r48r = ((r & 0x0001f800) << 7)
|
||||||
|
| ((r & 0x00001f80) << 5)
|
||||||
|
| ((r & 0x000001f8) << 3)
|
||||||
|
| ((r & 0x0000001f) << 1)
|
||||||
|
| ((r & 0x80000000) >> 31);
|
||||||
|
/*
|
||||||
|
* Do salting for crypt() and friends, and
|
||||||
|
* XOR with the permuted key.
|
||||||
|
*/
|
||||||
|
f = (r48l ^ r48r) & saltbits;
|
||||||
|
r48l ^= f ^ *kl++;
|
||||||
|
r48r ^= f ^ *kr++;
|
||||||
|
/*
|
||||||
|
* Do sbox lookups (which shrink it back to 32 bits)
|
||||||
|
* and do the pbox permutation at the same time.
|
||||||
|
*/
|
||||||
|
f = psbox[0][m_sbox[0][r48l >> 12]]
|
||||||
|
| psbox[1][m_sbox[1][r48l & 0xfff]]
|
||||||
|
| psbox[2][m_sbox[2][r48r >> 12]]
|
||||||
|
| psbox[3][m_sbox[3][r48r & 0xfff]];
|
||||||
|
/*
|
||||||
|
* Now that we've permuted things, complete f().
|
||||||
|
*/
|
||||||
|
f ^= l;
|
||||||
|
l = r;
|
||||||
|
r = f;
|
||||||
|
}
|
||||||
|
r = l;
|
||||||
|
l = f;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Do final permutation (inverse of IP).
|
||||||
|
*/
|
||||||
|
*l_out = fp_maskl[0][l >> 24]
|
||||||
|
| fp_maskl[1][(l >> 16) & 0xff]
|
||||||
|
| fp_maskl[2][(l >> 8) & 0xff]
|
||||||
|
| fp_maskl[3][l & 0xff]
|
||||||
|
| fp_maskl[4][r >> 24]
|
||||||
|
| fp_maskl[5][(r >> 16) & 0xff]
|
||||||
|
| fp_maskl[6][(r >> 8) & 0xff]
|
||||||
|
| fp_maskl[7][r & 0xff];
|
||||||
|
*r_out = fp_maskr[0][l >> 24]
|
||||||
|
| fp_maskr[1][(l >> 16) & 0xff]
|
||||||
|
| fp_maskr[2][(l >> 8) & 0xff]
|
||||||
|
| fp_maskr[3][l & 0xff]
|
||||||
|
| fp_maskr[4][r >> 24]
|
||||||
|
| fp_maskr[5][(r >> 16) & 0xff]
|
||||||
|
| fp_maskr[6][(r >> 8) & 0xff]
|
||||||
|
| fp_maskr[7][r & 0xff];
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
des_cipher(const char *in, char *out, int salt, int count)
|
||||||
|
{
|
||||||
|
unsigned int l_out, r_out, rawl, rawr;
|
||||||
|
unsigned int x[2];
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
if (!des_initialised)
|
||||||
|
des_init();
|
||||||
|
|
||||||
|
setup_salt(salt);
|
||||||
|
|
||||||
|
memcpy(x, in, sizeof x);
|
||||||
|
rawl = xntohl(x[0]);
|
||||||
|
rawr = xntohl(x[1]);
|
||||||
|
retval = do_des(rawl, rawr, &l_out, &r_out, count);
|
||||||
|
|
||||||
|
x[0] = xhtonl(l_out);
|
||||||
|
x[1] = xhtonl(r_out);
|
||||||
|
memcpy(out, x, sizeof x);
|
||||||
|
return(retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
xcrypt(const char *key, const char *setting)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned int count, salt, l, r0, r1, keybuf[2];
|
||||||
|
unsigned char *p, *q;
|
||||||
|
static unsigned char output[21];
|
||||||
|
|
||||||
|
if (!des_initialised)
|
||||||
|
des_init();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy the key, shifting each character up by one bit
|
||||||
|
* and padding with zeros.
|
||||||
|
*/
|
||||||
|
q = (unsigned char *) keybuf;
|
||||||
|
while ((q - (unsigned char *) keybuf) < sizeof(keybuf)) {
|
||||||
|
if ((*q++ = *key << 1))
|
||||||
|
key++;
|
||||||
|
}
|
||||||
|
if (des_setkey((const char *) keybuf))
|
||||||
|
return(NULL);
|
||||||
|
|
||||||
|
if (*setting == _PASSWORD_EFMT1) {
|
||||||
|
/*
|
||||||
|
* "new"-style:
|
||||||
|
* setting - underscore, 4 bytes of count, 4 bytes of salt
|
||||||
|
* key - unlimited characters
|
||||||
|
*/
|
||||||
|
for (i = 1, count = 0; i < 5; i++)
|
||||||
|
count |= ascii_to_bin(setting[i]) << (i - 1) * 6;
|
||||||
|
|
||||||
|
for (i = 5, salt = 0; i < 9; i++)
|
||||||
|
salt |= ascii_to_bin(setting[i]) << (i - 5) * 6;
|
||||||
|
|
||||||
|
while (*key) {
|
||||||
|
/*
|
||||||
|
* Encrypt the key with itself.
|
||||||
|
*/
|
||||||
|
if (des_cipher((const char*)keybuf, (char*)keybuf, 0, 1))
|
||||||
|
return(NULL);
|
||||||
|
/*
|
||||||
|
* And XOR with the next 8 characters of the key.
|
||||||
|
*/
|
||||||
|
q = (unsigned char *) keybuf;
|
||||||
|
while (((q - (unsigned char *) keybuf) < sizeof(keybuf)) &&
|
||||||
|
*key)
|
||||||
|
*q++ ^= *key++ << 1;
|
||||||
|
|
||||||
|
if (des_setkey((const char *) keybuf))
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
strncpy((char *)output, setting, 9);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Double check that we weren't given a short setting.
|
||||||
|
* If we were, the above code will probably have created
|
||||||
|
* wierd values for count and salt, but we don't really care.
|
||||||
|
* Just make sure the output string doesn't have an extra
|
||||||
|
* NUL in it.
|
||||||
|
*/
|
||||||
|
output[9] = '\0';
|
||||||
|
p = output + strlen((const char *)output);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* "old"-style:
|
||||||
|
* setting - 2 bytes of salt
|
||||||
|
* key - up to 8 characters
|
||||||
|
*/
|
||||||
|
count = 25;
|
||||||
|
|
||||||
|
salt = (ascii_to_bin(setting[1]) << 6)
|
||||||
|
| ascii_to_bin(setting[0]);
|
||||||
|
|
||||||
|
output[0] = setting[0];
|
||||||
|
/*
|
||||||
|
* If the encrypted password that the salt was extracted from
|
||||||
|
* is only 1 character long, the salt will be corrupted. We
|
||||||
|
* need to ensure that the output string doesn't have an extra
|
||||||
|
* NUL in it!
|
||||||
|
*/
|
||||||
|
output[1] = setting[1] ? setting[1] : output[0];
|
||||||
|
|
||||||
|
p = output + 2;
|
||||||
|
}
|
||||||
|
setup_salt(salt);
|
||||||
|
/*
|
||||||
|
* Do it.
|
||||||
|
*/
|
||||||
|
if (do_des(0, 0, &r0, &r1, count))
|
||||||
|
return(NULL);
|
||||||
|
/*
|
||||||
|
* Now encode the result...
|
||||||
|
*/
|
||||||
|
l = (r0 >> 8);
|
||||||
|
*p++ = ascii64[(l >> 18) & 0x3f];
|
||||||
|
*p++ = ascii64[(l >> 12) & 0x3f];
|
||||||
|
*p++ = ascii64[(l >> 6) & 0x3f];
|
||||||
|
*p++ = ascii64[l & 0x3f];
|
||||||
|
|
||||||
|
l = (r0 << 16) | ((r1 >> 16) & 0xffff);
|
||||||
|
*p++ = ascii64[(l >> 18) & 0x3f];
|
||||||
|
*p++ = ascii64[(l >> 12) & 0x3f];
|
||||||
|
*p++ = ascii64[(l >> 6) & 0x3f];
|
||||||
|
*p++ = ascii64[l & 0x3f];
|
||||||
|
|
||||||
|
l = r1 << 2;
|
||||||
|
*p++ = ascii64[(l >> 12) & 0x3f];
|
||||||
|
*p++ = ascii64[(l >> 6) & 0x3f];
|
||||||
|
*p++ = ascii64[l & 0x3f];
|
||||||
|
*p = 0;
|
||||||
|
|
||||||
|
return((char *)output);
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue