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