├── LICENSE.TXT ├── Makefile.in ├── Makefile.std ├── armor.c ├── chase.c ├── command.c ├── config.guess ├── config.h.in ├── config.sub ├── configure ├── configure.ac ├── daemon.c ├── daemons.c ├── extern.c ├── extern.h ├── fight.c ├── init.c ├── install-sh ├── 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 ├── rogue.6.in ├── rogue.cat.in ├── rogue.desktop ├── rogue.doc.in ├── rogue.h ├── rogue.html.in ├── rogue.me.in ├── rogue.png ├── rogue.spec ├── rogue54.sln ├── rogue54.vcproj ├── rooms.c ├── save.c ├── score.h ├── scrolls.c ├── state.c ├── sticks.c ├── things.c ├── vers.c ├── weapons.c ├── wizard.c └── xcrypt.c /LICENSE.TXT: -------------------------------------------------------------------------------- 1 | Rogue: Exploring the Dungeons of Doom 2 | Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 3. Neither the name(s) of the author(s) nor the names of other contributors 14 | may be used to endorse or promote products derived from this software 15 | without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE 21 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | SUCH DAMAGE. 28 | 29 | =========================================================================== 30 | 31 | Portions of this software (state.c, mdport.c) are based on the work 32 | of Nicholas J. Kisseberth. Used under license: 33 | 34 | Copyright (C) 1999, 2000, 2005 Nicholas J. Kisseberth 35 | All rights reserved. 36 | 37 | Redistribution and use in source and binary forms, with or without 38 | modification, are permitted provided that the following conditions 39 | are met: 40 | 1. Redistributions of source code must retain the above copyright 41 | notice, this list of conditions and the following disclaimer. 42 | 2. Redistributions in binary form must reproduce the above copyright 43 | notice, this list of conditions and the following disclaimer in the 44 | documentation and/or other materials provided with the distribution. 45 | 3. Neither the name(s) of the author(s) nor the names of other contributors 46 | may be used to endorse or promote products derived from this software 47 | without specific prior written permission. 48 | 49 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND 50 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 51 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 52 | ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE 53 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 54 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 55 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 56 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 57 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 58 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 59 | SUCH DAMAGE. 60 | 61 | =========================================================================== 62 | 63 | Portions of this software (xcrypt.c) are based on the work 64 | of David Burren. Used under license: 65 | 66 | FreeSec: libcrypt 67 | 68 | Copyright (C) 1994 David Burren 69 | All rights reserved. 70 | 71 | Redistribution and use in source and binary forms, with or without 72 | modification, are permitted provided that the following conditions 73 | are met: 74 | 1. Redistributions of source code must retain the above copyright 75 | notice, this list of conditions and the following disclaimer. 76 | 2. Redistributions in binary form must reproduce the above copyright 77 | notice, this list of conditions and the following disclaimer in the 78 | documentation and/or other materials provided with the distribution. 79 | 3. Neither the name(s) of the author(s) nor the names of other contributors 80 | may be used to endorse or promote products derived from this software 81 | without specific prior written permission. 82 | 83 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND 84 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 85 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 86 | ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE 87 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 88 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 89 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 90 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 91 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 92 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 93 | SUCH DAMAGE. 94 | -------------------------------------------------------------------------------- /Makefile.in: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # Makefile for rogue 4 | # 5 | # Rogue: Exploring the Dungeons of Doom 6 | # Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman 7 | # All rights reserved. 8 | # 9 | # See the file LICENSE.TXT for full copyright and licensing information. 10 | # 11 | ############################################################################### 12 | 13 | ############################################################################### 14 | # Site configuration occurs beneath this comment 15 | # Typically ./configure (autoconf tools) configures this section 16 | # This section could be manually configured if autoconf/configure fails 17 | ############################################################################### 18 | 19 | DISTNAME=@PACKAGE_TARNAME@@PACKAGE_VERSION@ 20 | PACKAGE_TARNAME = @PACKAGE_TARNAME@-@PACKAGE_VERSION@ 21 | PROGRAM=@PROGRAM@ 22 | 23 | O=o 24 | 25 | #CC=gcc 26 | CC = @CC@ 27 | 28 | #CFLAGS=-O2 29 | CFLAGS= @CFLAGS@ 30 | 31 | #LIBS=-lcurses 32 | LIBS = @LIBS@ 33 | 34 | #RM=rm -f 35 | RM = rm -f 36 | 37 | #GROFF=groff 38 | GROFF = @GROFF@ 39 | 40 | #NROFF=nroff 41 | NROFF = @NROFF@ 42 | 43 | #TBL=tbl 44 | TBL = @TBL@ 45 | 46 | #COLCRT=colcrt 47 | COLCRT = @COLCRT@ 48 | 49 | #SED=sed 50 | SED = @SED@ 51 | 52 | #SCOREFILE=rogue54.scr 53 | SCOREFILE = @SCOREFILE@ 54 | 55 | #LOCKFILE=rogue54.lck 56 | LOCKFILE = @LOCKFILE@ 57 | 58 | #GROUPOWNER=games 59 | GROUPOWNER = @GROUPOWNER@ 60 | 61 | #CPPFLAGS=-DHAVE_CONFIG_H 62 | CPPFLAGS =@DEFS@ @CPPFLAGS@ 63 | 64 | #DISTFILE = $(PROGRAM) 65 | DISTFILE = $(DISTNAME)-@TARGET@ 66 | 67 | INSTALL=./install-sh 68 | 69 | #INSTGROUP=-g games 70 | INSTGROUP= 71 | #INSTOWNER=-u root 72 | INSTOWNER= 73 | 74 | CHGRP=chgrp 75 | 76 | MKDIR=mkdir 77 | 78 | TOUCH=touch 79 | 80 | RMDIR=rmdir 81 | 82 | CHMOD=chmod 83 | 84 | DESTDIR= 85 | 86 | prefix=@prefix@ 87 | exec_prefix=@exec_prefix@ 88 | datarootdir=@datarootdir@ 89 | datadir=@datadir@ 90 | bindir=@bindir@ 91 | mandir=@mandir@ 92 | docdir=@docdir@ 93 | man6dir = $(mandir)/man6 94 | 95 | ############################################################################### 96 | # Site configuration occurs above this comment 97 | # It should not be necessary to change anything below this comment 98 | ############################################################################### 99 | 100 | HDRS = rogue.h extern.h score.h 101 | OBJS1 = vers.$(O) extern.$(O) armor.$(O) chase.$(O) command.$(O) \ 102 | daemon.$(O) daemons.$(O) fight.$(O) init.$(O) io.$(O) list.$(O) \ 103 | mach_dep.$(O) main.$(O) mdport.$(O) misc.$(O) monsters.$(O) \ 104 | move.$(O) new_level.$(O) 105 | OBJS2 = options.$(O) pack.$(O) passages.$(O) potions.$(O) rings.$(O) \ 106 | rip.$(O) rooms.$(O) save.$(O) scrolls.$(O) state.$(O) sticks.$(O) \ 107 | things.$(O) weapons.$(O) wizard.$(O) xcrypt.$(O) 108 | OBJS = $(OBJS1) $(OBJS2) 109 | CFILES = vers.c extern.c armor.c chase.c command.c daemon.c \ 110 | daemons.c fight.c init.c io.c list.c mach_dep.c \ 111 | main.c mdport.c misc.c monsters.c move.c new_level.c \ 112 | options.c pack.c passages.c potions.c rings.c rip.c \ 113 | rooms.c save.c scrolls.c state.c sticks.c things.c \ 114 | weapons.c wizard.c xcrypt.c 115 | MISC_C = findpw.c scedit.c scmisc.c 116 | DOCSRC = rogue.me.in rogue.6.in rogue.doc.in rogue.html.in rogue.cat.in 117 | DOCS = $(PROGRAM).doc $(PROGRAM).html $(PROGRAM).cat $(PROGRAM).me \ 118 | $(PROGRAM).6 119 | AFILES = configure Makefile.in configure.ac config.h.in config.sub config.guess \ 120 | install-sh rogue.6.in rogue.me.in rogue.html.in rogue.doc.in rogue.cat.in 121 | MISC = Makefile.std LICENSE.TXT rogue54.sln rogue54.vcproj rogue.spec \ 122 | rogue.png rogue.desktop 123 | 124 | .SUFFIXES: .obj 125 | 126 | .c.obj: 127 | $(CC) $(CFLAGS) $(CPPFLAGS) /c $*.c 128 | 129 | .c.o: 130 | $(CC) $(CFLAGS) $(CPPFLAGS) -c $*.c 131 | 132 | $(PROGRAM): $(HDRS) $(OBJS) 133 | $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o $@ 134 | 135 | clean: 136 | $(RM) $(OBJS1) 137 | $(RM) $(OBJS2) 138 | $(RM) core a.exe a.out a.exe.stackdump $(PROGRAM) $(PROGRAM).exe 139 | $(RM) $(PROGRAM).tar $(PROGRAM).tar.gz $(PROGRAM).zip 140 | $(RM) $(DISTNAME)/* 141 | -rmdir $(DISTNAME) 142 | 143 | maintainer-clean: 144 | $(RM) config.h 145 | $(RM) Makefile 146 | $(RM) config.status 147 | $(RM) -r autom4te.cache 148 | $(RM) config.log 149 | $(RM) $(PROGRAM).scr $(PROGRAM).lck 150 | 151 | stddocs: 152 | sed -e 's/@PROGRAM@/rogue/' -e 's/@SCOREFILE@/rogue.scr/' rogue.6.in > rogue.6 153 | sed -e 's/@PROGRAM@/rogue/' -e 's/@SCOREFILE@/rogue.scr/' rogue.me.in > rogue.me 154 | sed -e 's/@PROGRAM@/rogue/' -e 's/@SCOREFILE@/rogue.scr/' rogue.html.in > rogue,html 155 | sed -e 's/@PROGRAM@/rogue/' -e 's/@SCOREFILE@/rogue.scr/' rogue.doc.in > rogue.doc 156 | sed -e 's/@PROGRAM@/rogue/' -e 's/@SCOREFILE@/rogue.scr/' rogue.cat.in > rogue.cat 157 | 158 | dist.src: 159 | $(MAKE) $(MAKEFILE) clean 160 | mkdir $(DISTNAME) 161 | cp $(CFILES) $(HDRS) $(MISC) $(AFILES) $(DISTNAME) 162 | tar cf $(DISTNAME)-src.tar $(DISTNAME) 163 | gzip -f $(DISTNAME)-src.tar 164 | rm -fr $(DISTNAME) 165 | 166 | findpw: findpw.c xcrypt.o mdport.o xcrypt.o 167 | $(CC) -s -o findpw findpw.c xcrypt.o mdport.o -lcurses 168 | 169 | scedit: scedit.o scmisc.o vers.o mdport.o xcrypt.o 170 | $(CC) -s -o scedit vers.o scedit.o scmisc.o mdport.o xcrypt.o -lcurses 171 | 172 | scmisc.o scedit.o: 173 | $(CC) -O -c $(SF) $*.c 174 | 175 | $(PROGRAM).doc: rogue.me 176 | if test "x$(GROFF)" != "x" -a "x$(SED)" != "x" ; then \ 177 | $(GROFF) -P-c -t -me -Tascii rogue.me | $(SED) -e 's/.\x08//g' > $(PROGRAM).doc ;\ 178 | elif test "x$(NROFF)" != "x" -a "x$(TBL)" != "x" -a "x$(COLCRT)" != "x" ; then \ 179 | tbl rogue.me | $(NROFF) -me | colcrt - > $(PROGRAM).doc ;\ 180 | fi 181 | 182 | $(PROGRAM).cat: rogue.6 183 | if test "x$(GROFF)" != "x" -a "x$(SED)" != "x" ; then \ 184 | $(GROFF) -Tascii -man rogue.6 | $(SED) -e 's/.\x08//g' > $(PROGRAM).cat ;\ 185 | elif test "x$(NROFF)" != "x" -a "x$(TBL)" != "x" -a "x$(COLCRT)" != "x" ; then \ 186 | $(NROFF) -man rogue.6 | $(COLCRT) - > $(PROGRAM).cat ;\ 187 | fi 188 | 189 | dist: clean $(PROGRAM) 190 | tar cf $(DISTFILE).tar $(PROGRAM) LICENSE.TXT $(DOCS) 191 | gzip -f $(DISTFILE).tar 192 | 193 | install: $(PROGRAM) 194 | -$(TOUCH) test 195 | -if test ! -f $(DESTDIR)$(SCOREFILE) ; then $(INSTALL) -m 0664 test $(DESTDIR)$(SCOREFILE) ; fi 196 | -$(INSTALL) -m 0755 $(PROGRAM) $(DESTDIR)$(bindir)/$(PROGRAM) 197 | -if test "x$(GROUPOWNER)" != "x" ; then \ 198 | $(CHGRP) $(GROUPOWNER) $(DESTDIR)$(SCOREFILE) ; \ 199 | $(CHGRP) $(GROUPOWNER) $(DESTDIR)$(bindir)/$(PROGRAM) ; \ 200 | $(CHMOD) 02755 $(DESTDIR)$(bindir)/$(PROGRAM) ; \ 201 | $(CHMOD) 0464 $(DESTDIR)$(SCOREFILE) ; \ 202 | fi 203 | -if test -d $(man6dir) ; then $(INSTALL) -m 0644 rogue.6 $(DESTDIR)$(man6dir)/$(PROGRAM).6 ; fi 204 | -if test ! -d $(man6dir) ; then $(INSTALL) -m 0644 rogue.6 $(DESTDIR)$(mandir)/$(PROGRAM).6 ; fi 205 | -$(INSTALL) -m 0644 rogue.doc $(DESTDIR)$(docdir)/$(PROGRAM).doc 206 | -$(INSTALL) -m 0644 rogue.html $(DESTDIR)$(docdir)/$(PROGRAM).html 207 | -$(INSTALL) -m 0644 rogue.cat $(DESTDIR)$(docdir)/$(PROGRAM).cat 208 | -$(INSTALL) -m 0644 LICENSE.TXT $(DESTDIR)$(docdir)/LICENSE.TXT 209 | -$(INSTALL) -m 0644 rogue.me $(DESTDIR)$(docdir)/$(PROGRAM).me 210 | -if test ! -f $(DESTDIR)$(LOCKFILE) ; then $(INSTALL) -m 0666 test $(DESTDIR)$(LOCKFILE) ; $(RM) $(DESTDIR)$(LOCKFILE) ; fi 211 | -$(RM) test 212 | 213 | uninstall: 214 | -$(RM) $(DESTDIR)$(bindir)/$(PROGRAM) 215 | -$(RM) $(DESTDIR)$(man6dir)/$(PROGRAM).6 216 | -$(RM) $(DESTDIR)$(docdir)$(PROGRAM)/$(PROGRAM).doc 217 | -$(RM) $(DESTDIR)$(LOCKFILE) 218 | -$(RMDIR) $(DESTDIR)$(docdir)$(PROGRAM) 219 | 220 | reinstall: uninstall install 221 | -------------------------------------------------------------------------------- /Makefile.std: -------------------------------------------------------------------------------- 1 | # 2 | # Makefile for rogue 3 | # @(#)Makefile 4.21 (Berkeley) 02/04/99 4 | # 5 | # Rogue: Exploring the Dungeons of Doom 6 | # Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman 7 | # All rights reserved. 8 | # 9 | # See the file LICENSE.TXT for full copyright and licensing information. 10 | # 11 | 12 | DISTNAME = rogue5.4.4 13 | PROGRAM = rogue54 14 | O = o 15 | HDRS = rogue.h extern.h score.h 16 | OBJS1 = vers.$(O) extern.$(O) armor.$(O) chase.$(O) command.$(O) \ 17 | daemon.$(O) daemons.$(O) fight.$(O) init.$(O) io.$(O) list.$(O) \ 18 | mach_dep.$(O) main.$(O) mdport.$(O) misc.$(O) monsters.$(O) \ 19 | move.$(O) new_level.$(O) 20 | OBJS2 = options.$(O) pack.$(O) passages.$(O) potions.$(O) rings.$(O) \ 21 | rip.$(O) rooms.$(O) save.$(O) scrolls.$(O) state.$(O) sticks.$(O) \ 22 | things.$(O) weapons.$(O) wizard.$(O) xcrypt.$(O) 23 | OBJS = $(OBJS1) $(OBJS2) 24 | CFILES = vers.c extern.c armor.c chase.c command.c daemon.c \ 25 | daemons.c fight.c init.c io.c list.c mach_dep.c \ 26 | main.c mdport.c misc.c monsters.c move.c new_level.c \ 27 | options.c pack.c passages.c potions.c rings.c rip.c \ 28 | rooms.c save.c scrolls.c state.c sticks.c things.c \ 29 | weapons.c wizard.c xcrypt.c 30 | MISC_C = findpw.c scedit.c scmisc.c 31 | DOCSRC = rogue.me.in rogue.6.in rogue.doc.in rogue.html.in rogue.cat.in 32 | DOCS = $(PROGRAM).doc $(PROGRAM).html $(PROGRAM).cat $(PROGRAM).me \ 33 | $(PROGRAM).6 34 | AFILES = configure Makefile.in configure.ac config.h.in config.sub config.guess \ 35 | install-sh rogue.6.in rogue.me.in rogue.html.in rogue.doc.in rogue.cat.in 36 | MISC = Makefile.std LICENSE.TXT rogue54.sln rogue54.vcproj rogue.spec \ 37 | rogue.png rogue.desktop 38 | CC = gcc 39 | FEATURES = -DALLSCORES -DSCOREFILE=\"$(SCOREFILE)\" -DLOCKFILE=\"$(LOCKFILE)\" 40 | CPPFLAGS = 41 | CFLAGS = -O3 42 | LDFLAGS = 43 | LIBS = -lcurses 44 | RM = rm -f 45 | MAKEFILE = -f Makefile.std 46 | SCOREFILE= $(PROGRAM).scr 47 | LOCKFILE = $(PROGRAM).lck 48 | OUTFLAG = -o 49 | EXE = 50 | 51 | .SUFFIXES: .obj 52 | 53 | .c.obj: 54 | $(CC) $(CFLAGS) $(CPPFLAGS) $(FEATURES) /c $*.c 55 | 56 | .c.o: 57 | $(CC) $(CFLAGS) $(CPPFLAGS) $(FEATURES) -c $*.c 58 | 59 | $(PROGRAM): $(HDRS) $(OBJS) fixdocs 60 | $(CC) $(LDFLAGS) $(OBJS) $(LIBS) $(OUTFLAG)$@$(EXE) 61 | 62 | clean: 63 | $(RM) $(OBJS1) 64 | $(RM) $(OBJS2) 65 | $(RM) core a.exe a.out a.exe.stackdump $(PROGRAM) $(PROGRAM).exe $(PROGRAM).lck 66 | $(RM) $(PROGRAM).tar $(PROGRAM).tar.gz $(PROGRAM).zip 67 | $(RM) $(DISTNAME)/* 68 | 69 | dist.src: 70 | $(MAKE) $(MAKEFILE) clean 71 | mkdir $(DISTNAME) 72 | cp $(CFILES) $(HDRS) $(MISC) $(AFILES) $(DISTNAME) 73 | tar cf $(DISTNAME)-src.tar $(DISTNAME) 74 | gzip -f $(DISTNAME)-src.tar 75 | rm -fr $(DISTNAME) 76 | 77 | findpw: findpw.c xcrypt.o mdport.o xcrypt.o 78 | $(CC) -s -o findpw findpw.c xcrypt.o mdport.o -lcurses 79 | 80 | scedit: scedit.o scmisc.o vers.o mdport.o xcrypt.o 81 | $(CC) -s -o scedit vers.o scedit.o scmisc.o mdport.o xcrypt.o -lcurses 82 | 83 | scmisc.o scedit.o: 84 | $(CC) -O -c $(SF) $*.c 85 | 86 | doc.nroff: 87 | tbl rogue.me | nroff -me | colcrt - > rogue.doc 88 | nroff -man rogue.6 | colcrt - > rogue.cat 89 | 90 | doc.groff: 91 | groff -P-c -t -me -Tascii rogue.me | sed -e 's/.\x08//g' > rogue.doc 92 | groff -man rogue.6 | sed -e 's/.\x08//g' > rogue.cat 93 | 94 | fixdocs: 95 | sed -e 's/@PROGRAM@/$(PROGRAM)/' -e 's/@SCOREFILE@/$(SCOREFILE)/' rogue.6.in > $(PROGRAM).6 96 | sed -e 's/@PROGRAM@/$(PROGRAM)/' -e 's/@SCOREFILE@/$(SCOREFILE)/' rogue.me.in > $(PROGRAM).me 97 | sed -e 's/@PROGRAM@/$(PROGRAM)/' -e 's/@SCOREFILE@/$(SCOREFILE)/' rogue.html.in > $(PROGRAM).html 98 | sed -e 's/@PROGRAM@/$(PROGRAM)/' -e 's/@SCOREFILE@/$(SCOREFILE)/' rogue.doc.in > $(PROGRAM).doc 99 | sed -e 's/@PROGRAM@/$(PROGRAM)/' -e 's/@SCOREFILE@/$(SCOREFILE)/' rogue.cat.in > $(PROGRAM).cat 100 | 101 | dist.irix: 102 | $(MAKE) $(MAKEFILE) clean 103 | $(MAKE) $(MAKEFILE) CC=cc $(PROGRAM) 104 | tar cf $(DISTNAME)-irix.tar $(PROGRAM) LICENSE.TXT $(DOCS) 105 | gzip -f $(DISTNAME)-irix.tar 106 | 107 | dist.aix: 108 | $(MAKE) $(MAKEFILE) clean 109 | $(MAKE) $(MAKEFILE) CC=xlc CFLAGS="-qmaxmem=16768 -O3 -qstrict" $(PROGRAM) 110 | tar cf $(DISTNAME)-aix.tar $(PROGRAM) LICENSE.TXT $(DOCS) 111 | gzip -f $(DISTNAME)-aix.tar 112 | 113 | dist.linux: 114 | $(MAKE) $(MAKEFILE) clean 115 | $(MAKE) $(MAKEFILE) $(PROGRAM) 116 | tar cf $(DISTNAME)-linux.tar $(PROGRAM) LICENSE.TXT $(DOCS) 117 | gzip -f $(DISTNAME)-linux.tar 118 | 119 | dist.interix: 120 | @$(MAKE) $(MAKEFILE) clean 121 | @$(MAKE) $(MAKEFILE) CFLAGS="-ansi" $(PROGRAM) 122 | tar cf $(DISTNAME)-interix.tar $(PROGRAM) LICENSE.TXT $(DOCS) 123 | gzip -f $(DISTNAME)-interix.tar 124 | 125 | dist.cygwin: 126 | @$(MAKE) $(MAKEFILE) --no-print-directory clean 127 | @$(MAKE) $(MAKEFILE) CPPFLAGS="-I/usr/include/ncurses" --no-print-directory $(PROGRAM) 128 | tar cf $(DISTNAME)-cygwin.tar $(PROGRAM).exe LICENSE.TXT $(DOCS) 129 | gzip -f $(DISTNAME)-cygwin.tar 130 | 131 | # 132 | # Use MINGW32-MAKE to build this target 133 | # 134 | dist.mingw32: 135 | @$(MAKE) $(MAKEFILE) --no-print-directory RM="cmd /c del" clean 136 | @$(MAKE) $(MAKEFILE) --no-print-directory CPPFLAGS="-I../pdcurses" LIBS="../pdcurses/pdcurses.a" $(PROGRAM) 137 | cmd /c del $(DISTNAME)-mingw32.zip 138 | zip $(DISTNAME)-mingw32.zip $(PROGRAM).exe LICENSE.TXT $(DOCS) 139 | 140 | dist.djgpp: 141 | @$(MAKE) $(MAKEFILE) --no-print-directory clean 142 | @$(MAKE) $(MAKEFILE) --no-print-directory LDFLAGS="-L$(DJDIR)/LIB" \ 143 | LIBS="-lpdcurses" $(PROGRAM) 144 | rm -f $(DISTNAME)-djgpp.zip 145 | zip $(DISTNAME)-djgpp.zip $(PROGRAM) LICENSE.TXT $(DOCS) 146 | 147 | # 148 | # Use NMAKE to build this targer 149 | # 150 | 151 | dist.win32: 152 | @$(MAKE) $(MAKEFILE) /NOLOGO O="obj" RM="-del" clean 153 | @$(MAKE) $(MAKEFILE) /NOLOGO O="obj" CC="CL" \ 154 | LIBS="..\pdcurses\pdcurses.lib shell32.lib user32.lib Advapi32.lib" \ 155 | EXE=".exe" OUTFLAG="/Fe" CPPFLAGS="-I..\pdcurses" \ 156 | CFLAGS="-nologo -Ox -wd4033 -wd4716" $(PROGRAM) 157 | -del $(DISTNAME)-win32.zip 158 | zip $(DISTNAME)-win32.zip $(PROGRAM).exe LICENSE.TXT $(DOCS) 159 | -------------------------------------------------------------------------------- /armor.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file contains misc functions for dealing with armor 3 | * @(#)armor.c 4.14 (Berkeley) 02/05/99 4 | * 5 | * Rogue: Exploring the Dungeons of Doom 6 | * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman 7 | * All rights reserved. 8 | * 9 | * See the file LICENSE.TXT for full copyright and licensing information. 10 | */ 11 | 12 | #include 13 | #include "rogue.h" 14 | 15 | /* 16 | * wear: 17 | * The player wants to wear something, so let him/her put it on. 18 | */ 19 | void 20 | wear() 21 | { 22 | register THING *obj; 23 | register char *sp; 24 | 25 | if ((obj = get_item("wear", ARMOR)) == NULL) 26 | return; 27 | if (cur_armor != NULL) 28 | { 29 | addmsg("you are already wearing some"); 30 | if (!terse) 31 | addmsg(". You'll have to take it off first"); 32 | endmsg(); 33 | after = FALSE; 34 | return; 35 | } 36 | if (obj->o_type != ARMOR) 37 | { 38 | msg("you can't wear that"); 39 | return; 40 | } 41 | waste_time(); 42 | obj->o_flags |= ISKNOW; 43 | sp = inv_name(obj, TRUE); 44 | cur_armor = obj; 45 | if (!terse) 46 | addmsg("you are now "); 47 | msg("wearing %s", sp); 48 | } 49 | 50 | /* 51 | * take_off: 52 | * Get the armor off of the players back 53 | */ 54 | void 55 | take_off() 56 | { 57 | register THING *obj; 58 | 59 | if ((obj = cur_armor) == NULL) 60 | { 61 | after = FALSE; 62 | if (terse) 63 | msg("not wearing armor"); 64 | else 65 | msg("you aren't wearing any armor"); 66 | return; 67 | } 68 | if (!dropcheck(cur_armor)) 69 | return; 70 | cur_armor = NULL; 71 | if (terse) 72 | addmsg("was"); 73 | else 74 | addmsg("you used to be"); 75 | msg(" wearing %c) %s", obj->o_packch, inv_name(obj, TRUE)); 76 | } 77 | 78 | /* 79 | * waste_time: 80 | * Do nothing but let other things happen 81 | */ 82 | void 83 | waste_time() 84 | { 85 | do_daemons(BEFORE); 86 | do_fuses(BEFORE); 87 | do_daemons(AFTER); 88 | do_fuses(AFTER); 89 | } 90 | -------------------------------------------------------------------------------- /config.h.in: -------------------------------------------------------------------------------- 1 | /* config.h.in. Generated from configure.ac by autoheader. */ 2 | 3 | /* Define if scorefile is top scores, not top players */ 4 | #undef ALLSCORES 5 | 6 | /* Define if checktime feature should be enabled */ 7 | #undef CHECKTIME 8 | 9 | /* Define to group owner of setgid executable */ 10 | #undef GROUPOWNER 11 | 12 | /* Define to 1 if you have the `alarm' function. */ 13 | #undef HAVE_ALARM 14 | 15 | /* Define to 1 if you have the header file. */ 16 | #undef HAVE_ARPA_INET_H 17 | 18 | /* Define to 1 if libcurses is requested */ 19 | #undef HAVE_CURSES_H 20 | 21 | /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ 22 | #undef HAVE_DOPRNT 23 | 24 | /* Define to 1 if you have the `erasechar' function. */ 25 | #undef HAVE_ERASECHAR 26 | 27 | /* Define if ncurses has ESCDELAY variable */ 28 | #undef HAVE_ESCDELAY 29 | 30 | /* Define to 1 if you have the header file. */ 31 | #undef HAVE_FCNTL_H 32 | 33 | /* Define to 1 if you have the `fork' function. */ 34 | #undef HAVE_FORK 35 | 36 | /* Define to 1 if you have the `getgid' function. */ 37 | #undef HAVE_GETGID 38 | 39 | /* Define to 1 if you have the `getloadavg' function. */ 40 | #undef HAVE_GETLOADAVG 41 | 42 | /* Define to 1 if you have the `getpass' function. */ 43 | #undef HAVE_GETPASS 44 | 45 | /* Define to 1 if you have the `getpwuid' function. */ 46 | #undef HAVE_GETPWUID 47 | 48 | /* Define to 1 if you have the `getuid' function. */ 49 | #undef HAVE_GETUID 50 | 51 | /* Define to 1 if you have the header file. */ 52 | #undef HAVE_INTTYPES_H 53 | 54 | /* Define to 1 if you have the `killchar' function. */ 55 | #undef HAVE_KILLCHAR 56 | 57 | /* Define to 1 if you have the header file. */ 58 | #undef HAVE_LIMITS_H 59 | 60 | /* Define to 1 if you have the `loadav' function. */ 61 | #undef HAVE_LOADAV 62 | 63 | /* Define to 1 if `lstat' has the bug that it succeeds when given the 64 | zero-length file name argument. */ 65 | #undef HAVE_LSTAT_EMPTY_STRING_BUG 66 | 67 | /* Define to 1 if you have the header file. */ 68 | #undef HAVE_MEMORY_H 69 | 70 | /* Define to 1 if you have the `memset' function. */ 71 | #undef HAVE_MEMSET 72 | 73 | /* Define to 1 if libncurses is requested */ 74 | #undef HAVE_NCURSES_H 75 | 76 | /* Define to 1 if you have the header file. */ 77 | #undef HAVE_NCURSES_TERM_H 78 | 79 | /* Define to 1 if you have the `nlist' function. */ 80 | #undef HAVE_NLIST 81 | 82 | /* Define to 1 if you have the header file. */ 83 | #undef HAVE_NLIST_H 84 | 85 | /* Define to 1 if you have the header file. */ 86 | #undef HAVE_PROCESS_H 87 | 88 | /* Define to 1 if you have the header file. */ 89 | #undef HAVE_PWD_H 90 | 91 | /* Define to 1 if you have the `setenv' function. */ 92 | #undef HAVE_SETENV 93 | 94 | /* Define to 1 if you have the `setgid' function. */ 95 | #undef HAVE_SETGID 96 | 97 | /* Define to 1 if you have the `setregid' function. */ 98 | #undef HAVE_SETREGID 99 | 100 | /* Define to 1 if you have the `setresgid' function. */ 101 | #undef HAVE_SETRESGID 102 | 103 | /* Define to 1 if you have the `setresuid' function. */ 104 | #undef HAVE_SETRESUID 105 | 106 | /* Define to 1 if you have the `setreuid' function. */ 107 | #undef HAVE_SETREUID 108 | 109 | /* Define to 1 if you have the `setuid' function. */ 110 | #undef HAVE_SETUID 111 | 112 | /* Define to 1 if you have the `spawnl' function. */ 113 | #undef HAVE_SPAWNL 114 | 115 | /* Define to 1 if `stat' has the bug that it succeeds when given the 116 | zero-length file name argument. */ 117 | #undef HAVE_STAT_EMPTY_STRING_BUG 118 | 119 | /* Define to 1 if stdbool.h conforms to C99. */ 120 | #undef HAVE_STDBOOL_H 121 | 122 | /* Define to 1 if you have the header file. */ 123 | #undef HAVE_STDINT_H 124 | 125 | /* Define to 1 if you have the header file. */ 126 | #undef HAVE_STDLIB_H 127 | 128 | /* Define to 1 if you have the `strchr' function. */ 129 | #undef HAVE_STRCHR 130 | 131 | /* Define to 1 if you have the `strerror' function. */ 132 | #undef HAVE_STRERROR 133 | 134 | /* Define to 1 if you have the header file. */ 135 | #undef HAVE_STRINGS_H 136 | 137 | /* Define to 1 if you have the header file. */ 138 | #undef HAVE_STRING_H 139 | 140 | /* Define to 1 if you have the header file. */ 141 | #undef HAVE_SYS_IOCTL_H 142 | 143 | /* Define to 1 if you have the header file. */ 144 | #undef HAVE_SYS_STAT_H 145 | 146 | /* Define to 1 if you have the header file. */ 147 | #undef HAVE_SYS_TYPES_H 148 | 149 | /* Define to 1 if you have the header file. */ 150 | #undef HAVE_SYS_UTSNAME_H 151 | 152 | /* Define to 1 if you have the header file. */ 153 | #undef HAVE_TERMIOS_H 154 | 155 | /* Define to 1 if you have the header file. */ 156 | #undef HAVE_TERM_H 157 | 158 | /* Define to 1 if you have the header file. */ 159 | #undef HAVE_UNISTD_H 160 | 161 | /* Define to 1 if you have the header file. */ 162 | #undef HAVE_UTMP_H 163 | 164 | /* Define to 1 if you have the `vfork' function. */ 165 | #undef HAVE_VFORK 166 | 167 | /* Define to 1 if you have the header file. */ 168 | #undef HAVE_VFORK_H 169 | 170 | /* Define to 1 if you have the `vprintf' function. */ 171 | #undef HAVE_VPRINTF 172 | 173 | /* Define to 1 if `fork' works. */ 174 | #undef HAVE_WORKING_FORK 175 | 176 | /* Define to 1 if `vfork' works. */ 177 | #undef HAVE_WORKING_VFORK 178 | 179 | /* Define to 1 if the system has the type `_Bool'. */ 180 | #undef HAVE__BOOL 181 | 182 | /* Define to 1 if you have the `_spawnl' function. */ 183 | #undef HAVE__SPAWNL 184 | 185 | /* define if we should use program's load average function instead of system 186 | */ 187 | #undef LOADAV 188 | 189 | /* Define to file to use for scoreboard lockfile */ 190 | #undef LOCKFILE 191 | 192 | /* Define to 1 if `lstat' dereferences a symlink specified with a trailing 193 | slash. */ 194 | #undef LSTAT_FOLLOWS_SLASHED_SYMLINK 195 | 196 | /* Define to include wizard mode */ 197 | #undef MASTER 198 | 199 | /* Define if maxusers feature should be enabled */ 200 | #undef MAXLOAD 201 | 202 | /* Define if maxusers feature should be enabled */ 203 | #undef MAXUSERS 204 | 205 | /* kernel file to pass to nlist() when reading load average (unlikely to work) 206 | */ 207 | #undef NAMELIST 208 | 209 | /* word for the number of scores to store in scoreboard */ 210 | #undef NUMNAME 211 | 212 | /* number of scores to store in scoreboard */ 213 | #undef NUMSCORES 214 | 215 | /* Define to the address where bug reports for this package should be sent. */ 216 | #undef PACKAGE_BUGREPORT 217 | 218 | /* Define to the full name of this package. */ 219 | #undef PACKAGE_NAME 220 | 221 | /* Define to the full name and version of this package. */ 222 | #undef PACKAGE_STRING 223 | 224 | /* Define to the one symbol short name of this package. */ 225 | #undef PACKAGE_TARNAME 226 | 227 | /* Define to the version of this package. */ 228 | #undef PACKAGE_VERSION 229 | 230 | /* Define crypt(3) wizard mode password */ 231 | #undef PASSWD 232 | 233 | /* Define as the return type of signal handlers (`int' or `void'). */ 234 | #undef RETSIGTYPE 235 | 236 | /* Define to file to use for scoreboard */ 237 | #undef SCOREFILE 238 | 239 | /* Define to 1 if you have the ANSI C header files. */ 240 | #undef STDC_HEADERS 241 | 242 | /* Define to 1 if your declares `struct tm'. */ 243 | #undef TM_IN_SYS_TIME 244 | 245 | /* define if we should use program's user counting function instead of 246 | system's */ 247 | #undef UCOUNT 248 | 249 | /* utmp like file to pass to ucount() when counting online users (unlikely to 250 | work) */ 251 | #undef UTMP 252 | 253 | /* Define to empty if `const' does not conform to ANSI C. */ 254 | #undef const 255 | 256 | /* Define to `int' if doesn't define. */ 257 | #undef gid_t 258 | 259 | /* Define to `int' if does not define. */ 260 | #undef pid_t 261 | 262 | /* Define to `unsigned int' if does not define. */ 263 | #undef size_t 264 | 265 | /* Define to `int' if doesn't define. */ 266 | #undef uid_t 267 | 268 | /* Define as `fork' if `vfork' does not work. */ 269 | #undef vfork 270 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # -*- Autoconf -*- 2 | # Process this file with autoconf to produce a configure script. 3 | 4 | AC_PREREQ(2.56) 5 | AC_INIT([Rogue],[5.4.4], [yendor@rogueforge.net]) 6 | AC_CONFIG_SRCDIR([armor.c]) 7 | AC_CONFIG_HEADER([config.h]) 8 | AC_CONFIG_FILES([Makefile rogue.6 rogue.cat rogue.doc rogue.html rogue.me]) 9 | AC_CANONICAL_SYSTEM([]) 10 | 11 | # Checks for programs. 12 | AC_PROG_CC 13 | 14 | # Checks for libraries. 15 | 16 | # Checks for header files. 17 | AC_HEADER_STDC 18 | 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]) 19 | 20 | # Checks for typedefs, structures, and compiler characteristics. 21 | AC_HEADER_STDBOOL 22 | AC_C_CONST 23 | AC_TYPE_UID_T 24 | AC_TYPE_SIZE_T 25 | AC_STRUCT_TM 26 | MP_WITH_CURSES 27 | # Checks for library functions. 28 | AC_FUNC_FORK 29 | AC_PROG_GCC_TRADITIONAL 30 | AC_FUNC_LSTAT 31 | AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK 32 | AC_TYPE_SIGNAL 33 | AC_FUNC_STAT 34 | AC_FUNC_VPRINTF 35 | 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]) 36 | 37 | AC_CHECK_PROG([NROFF], [nroff], [nroff],) 38 | AC_CHECK_PROG([GROFF], [groff], [groff],) 39 | AC_CHECK_PROG([COLCRT], [colcrt], [colcrt],) 40 | AC_CHECK_PROG([TBL], [tbl], [tbl],) 41 | AC_CHECK_PROG([SED], [sed], [sed],) 42 | 43 | AC_ARG_WITH(program-name, AC_HELP_STRING([--with-program-name=NAME],[alternate executable name]),[progname="$withval" ], [progname="rogue"] ) 44 | PROGRAM=$progname 45 | AC_SUBST(PROGRAM) 46 | 47 | AC_ARG_ENABLE(setgid, AC_HELP_STRING([--enable-setgid=NAME],[install executable as setgid with group ownership of NAME @<:@default=no@:>@])],[],[]) 48 | AC_MSG_CHECKING([if using setgid execute bit]) 49 | if test "x$enable_setgid" = "xno" ; then 50 | GROUPOWNER= 51 | elif test "x$enable_setgid" = "xyes" ; then 52 | GROUPOWNER=games 53 | elif test "x$enable_setgid" = "x" ; then 54 | GROUPOWNER= 55 | else 56 | GROUPOWNER=$enable_setgid 57 | fi 58 | 59 | if test "x$GROUPOWNER" != "x" ; then 60 | AC_DEFINE_UNQUOTED([GROUPOWNER],[$GROUPOWNER], [Define to group owner of setgid executable]) 61 | AC_MSG_RESULT([$GROUPOWNER]) 62 | else 63 | AC_MSG_RESULT([no]) 64 | fi 65 | 66 | AC_SUBST(GROUPOWNER) 67 | 68 | AC_ARG_ENABLE([scorefile],[AC_HELP_STRING([--enable-scorefile=SCOREFILE], [enable scoreboard with given filename])],[],[]) 69 | AC_MSG_CHECKING([for scoreboard file]) 70 | if test "x$enable_scorefile" = "xno" ; then 71 | SCOREFILE= 72 | elif test "x$enable_scorefile" = "xyes" ; then 73 | SCOREFILE=$progname.scr 74 | elif test "x$enable_scorefile" = "x" ; then 75 | SCOREFILE=$progname.scr 76 | else 77 | SCOREFILE=$enable_scorefile 78 | fi 79 | 80 | if test "x$SCOREFILE" != "x" ; then 81 | AC_DEFINE_UNQUOTED([SCOREFILE], ["$SCOREFILE"], [Define to file to use for scoreboard]) 82 | AC_MSG_RESULT([$SCOREFILE]) 83 | else 84 | AC_MSG_RESULT([disabled]) 85 | fi 86 | 87 | AC_SUBST(SCOREFILE) 88 | 89 | AC_ARG_ENABLE([lockfile],[AC_HELP_STRING([--enable-lockfile=LOCKFILE], [enable scoreboard lockfile with given filename])],[],[]) 90 | AC_MSG_CHECKING([for scoreboard lockfile file]) 91 | if test "x$enable_lockfile" = "xno" ; then 92 | LOCKFILE= 93 | elif test "x$enable_lockfile" = "xyes" ; then 94 | LOCKFILE=$progname.lck 95 | elif test "x$enable_lockfile" = "x" ; then 96 | LOCKFILE=$progname.lck 97 | else 98 | LOCKFILE=$enable_lockfile 99 | fi 100 | 101 | if test "x$LOCKFILE" != "x" ; then 102 | AC_DEFINE_UNQUOTED([LOCKFILE], ["$LOCKFILE"], [Define to file to use for scoreboard lockfile]) 103 | AC_MSG_RESULT([$LOCKFILE]) 104 | else 105 | AC_MSG_RESULT([disabled]) 106 | fi 107 | 108 | AC_SUBST(LOCKFILE) 109 | 110 | AC_ARG_ENABLE([wizardmode],[AC_HELP_STRING([--enable-wizardmode], [enable availability of wizard mode @<:@default=no@:>@])],[],[]) 111 | AC_MSG_CHECKING([if wizard mode is enabled]) 112 | if test "x$enable_wizardmode" = "xno" ; then 113 | AC_MSG_RESULT([no]) 114 | elif test "x$enable_wizardmode" = "x" ; then 115 | AC_MSG_RESULT([no]) 116 | else 117 | AC_DEFINE([MASTER], [], [Define to include wizard mode]) 118 | if test "x$enable_wizardmode" != "xyes" ; then 119 | AC_DEFINE_UNQUOTED([PASSWD],[$enable_wizardmode], [Define crypt(3) wizard mode password]) 120 | fi 121 | AC_MSG_RESULT([yes]) 122 | fi 123 | 124 | AC_ARG_ENABLE([allscores],[AC_HELP_STRING([--enable-allscores], [enable scoreboard to show top scores, not just top players @<:@default=yes@:>@])],[],[enable_allscores=yes]) 125 | AC_MSG_CHECKING([if allscores is enabled]) 126 | if test "x$enable_allscores" = "xyes" ; then 127 | AC_DEFINE([ALLSCORES], [1], [Define if scorefile is top scores, not top players]) 128 | AC_MSG_RESULT([yes]) 129 | else 130 | AC_MSG_RESULT([no]) 131 | fi 132 | 133 | AC_ARG_ENABLE([checktime],[AC_HELP_STRING([--enable-checktime], [enable checktime @<:@default=no@:>@])],[],[]) 134 | AC_MSG_CHECKING([if checktime is enabled]) 135 | if test "x$enable_checktime" = "xyes" ; then 136 | AC_DEFINE([CHECKTIME], [1], [Define if checktime feature should be enabled]) 137 | AC_MSG_RESULT([yes]) 138 | else 139 | AC_MSG_RESULT([no]) 140 | fi 141 | 142 | AC_ARG_ENABLE([maxload],[AC_HELP_STRING([--enable-maxload], [enable maxload @<:@default=no@:>@])],[],[]) 143 | AC_MSG_CHECKING([runtime execution limit (maximum system load average)]) 144 | if test "x$enable_maxload" = "xyes" ; then 145 | AC_DEFINE([MAXLOAD], [100], [Define if maxload feature should be enabled]) 146 | AC_MSG_RESULT([100]) 147 | elif test "x$enable_maxload" = "x" ; then 148 | AC_MSG_RESULT([unlimited]) 149 | elif test "x$enable_maxload" = "xno" ; then 150 | AC_MSG_RESULT([unlimited]) 151 | else 152 | AC_DEFINE_UNQUOTED([MAXLOAD], [$enable_maxload], [Define if maxload feature should be enabled]) 153 | AC_MSG_RESULT([$enable_maxload]) 154 | fi 155 | 156 | AC_ARG_ENABLE([maxusers],[AC_HELP_STRING([--enable-maxusers], [enable maxuser @<:@default=no@:>@])],[],[]) 157 | AC_MSG_CHECKING([runtime execution limit (maximum online system users)]) 158 | if test "x$enable_maxusers" = "xyes" ; then 159 | AC_DEFINE([MAXUSERS], [100], [Define if maxusers feature should be enabled]) 160 | AC_MSG_RESULT([100]) 161 | elif test "x$enable_maxusers" = "x" ; then 162 | AC_MSG_RESULT([unlimited]) 163 | elif test "x$enable_maxload" = "xno" ; then 164 | AC_MSG_RESULT([unlimited]) 165 | else 166 | AC_DEFINE_UNQUOTED([MAXLOAD], [$enable_maxusers], [Define if maxusers feature should be enabled]) 167 | AC_MSG_RESULT([$enable_maxusers]) 168 | fi 169 | 170 | AC_ARG_ENABLE([numscores],[AC_HELP_STRING([--enable-numscores], [number of scores to store in scoreboard @<:@default=10@:>@])],[],[]) 171 | AC_MSG_CHECKING([what the number of scores to store in scoreboard is]) 172 | if test "x$numscores" = "xyes" ; then 173 | AC_DEFINE([NUMSCORES], [10], [number of scores to store in scoreboard]) 174 | AC_MSG_RESULT([10]) 175 | elif test "x$enable_numscores" = "x" ; then 176 | AC_DEFINE([NUMSCORES], [10], [number of scores to store in scoreboard]) 177 | AC_MSG_RESULT([10]) 178 | elif test "x$enable_numscores" = "xno" ; then 179 | AC_DEFINE([NUMSCORES], [10], [number of scores to store in scoreboard]) 180 | AC_MSG_RESULT([10]) 181 | else 182 | AC_DEFINE_UNQUOTED([NUMSCORES], [$enable_numscores], [number of scores to store in scoreboard]) 183 | AC_MSG_RESULT([$enable_numscores]) 184 | fi 185 | 186 | AC_ARG_ENABLE([numname],[AC_HELP_STRING([--enable-numname], [word for number of scores to store in scoreboard @<:@default=Ten@:>@])],[],[]) 187 | AC_MSG_CHECKING([word for the number of scores to store in scoreboard is]) 188 | if test "x$enable_numname" = "xyes" ; then 189 | AC_DEFINE([NUMNAME], ["Ten"], [word for the number of scores to store in scoreboard]) 190 | AC_MSG_RESULT([Ten]) 191 | elif test "x$enable_numname" = "x" ; then 192 | AC_DEFINE([NUMNAME], ["Ten"], [word for the number of scores to store in scoreboard]) 193 | AC_MSG_RESULT([Ten]) 194 | elif test "x$enable_numname" = "xno" ; then 195 | AC_DEFINE([NUMNAME], ["Ten"], [word for the number of scores to store in scoreboard]) 196 | AC_MSG_RESULT([Ten]) 197 | else 198 | AC_DEFINE_UNQUOTED([NUMNAME], ["$enable_numname"], [word for the number of scores to store in scoreboard]) 199 | AC_MSG_RESULT([$enable_numname]) 200 | fi 201 | 202 | AC_ARG_ENABLE([loadav],[AC_HELP_STRING([--enable-loadav=NAMELIST], [use program's load average function (unlikely to work) @<:@default=no@:>@])],[],[]) 203 | AC_MSG_CHECKING([whether to use program's built in load average function]) 204 | if test "x$enable_loadav" = "xyes" ; then 205 | AC_DEFINE([LOADAV], [], [define if we should use program's load average function instead of system]) 206 | AC_DEFINE([NAMELIST], [/vmunix], [kernel file to pass to nlist() when reading load average (unlikely to work)]) 207 | AC_MSG_RESULT([/vmunix]) 208 | elif test "x$enable_loadav" = "x" ; then 209 | AC_MSG_RESULT([no]) 210 | elif test "x$enable_loadav" = "xno" ; then 211 | AC_MSG_RESULT([no]) 212 | else 213 | AC_DEFINE([LOADAV], [], [define if we should use program's load average function instead of system]) 214 | AC_DEFINE_UNQUOTED([NAMELIST], [$enable_loadav], [kernel file to pass to nlist() when reading load average (unlikely to work)]) 215 | AC_MSG_RESULT([$enable_loadav]) 216 | fi 217 | 218 | AC_ARG_ENABLE([ucount],[AC_HELP_STRING([--enable-ucount=UTMPFILE], [use program's own function to count users (unlikely to work) @<:@default=no@:>@])],[],[]) 219 | AC_MSG_CHECKING([whether to use program's built in user counting function]) 220 | if test "x$enable_ucount" = "xyes" ; then 221 | AC_DEFINE([UCOUNT], [], [define if we should use program's user counting function instead of system's]) 222 | AC_DEFINE([UTMP], [/etc/utmp], [utmp like file to pass to ucount() when counting online users (unlikely to work)]) 223 | AC_MSG_RESULT([/etc/utmp]) 224 | elif test "x$enable_ucount" = "x" ; then 225 | AC_MSG_RESULT([no]) 226 | elif test "x$enable_count" = "xno" ; then 227 | AC_MSG_RESULT([no]) 228 | else 229 | AC_DEFINE([UCOUNT], [], [define if we should use program's user counting function instead of system's]) 230 | AC_DEFINE_UNQUOTED([UTMP], [$enable_ucount], [utmp like file to pass to ucount() when counting online users (unlikely to work)]) 231 | AC_MSG_RESULT([$enable_ucount]) 232 | fi 233 | 234 | TARGET=$target 235 | AC_SUBST(TARGET) 236 | 237 | AC_MSG_CHECKING([whether to docdir is defined]) 238 | if test "x$docdir" = "x" ; then 239 | AC_MSG_RESULT([docdir undefined]) 240 | docdir=\${datadir}/doc/\${PACKAGE_TARNAME} 241 | AC_SUBST(docdir) 242 | else 243 | AC_MSG_RESULT([docdir defined]) 244 | fi 245 | 246 | AC_OUTPUT 247 | -------------------------------------------------------------------------------- /daemon.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Contains functions for dealing with things that happen in the 3 | * future. 4 | * 5 | * @(#)daemon.c 4.7 (Berkeley) 02/05/99 6 | * 7 | * Rogue: Exploring the Dungeons of Doom 8 | * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman 9 | * All rights reserved. 10 | * 11 | * See the file LICENSE.TXT for full copyright and licensing information. 12 | */ 13 | 14 | #include 15 | #include "rogue.h" 16 | 17 | #define EMPTY 0 18 | #define DAEMON -1 19 | #define MAXDAEMONS 20 20 | 21 | #define _X_ { EMPTY } 22 | 23 | struct delayed_action d_list[MAXDAEMONS] = { 24 | _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, 25 | _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, 26 | }; 27 | 28 | /* 29 | * d_slot: 30 | * Find an empty slot in the daemon/fuse list 31 | */ 32 | struct delayed_action * 33 | d_slot() 34 | { 35 | register struct delayed_action *dev; 36 | 37 | for (dev = d_list; dev <= &d_list[MAXDAEMONS-1]; dev++) 38 | if (dev->d_type == EMPTY) 39 | return dev; 40 | #ifdef MASTER 41 | debug("Ran out of fuse slots"); 42 | #endif 43 | return NULL; 44 | } 45 | 46 | /* 47 | * find_slot: 48 | * Find a particular slot in the table 49 | */ 50 | struct delayed_action * 51 | find_slot(void (*func)()) 52 | { 53 | register struct delayed_action *dev; 54 | 55 | for (dev = d_list; dev <= &d_list[MAXDAEMONS-1]; dev++) 56 | if (dev->d_type != EMPTY && func == dev->d_func) 57 | return dev; 58 | return NULL; 59 | } 60 | 61 | /* 62 | * start_daemon: 63 | * Start a daemon, takes a function. 64 | */ 65 | void 66 | start_daemon(void (*func)(), int arg, int type) 67 | { 68 | register struct delayed_action *dev; 69 | 70 | dev = d_slot(); 71 | dev->d_type = type; 72 | dev->d_func = func; 73 | dev->d_arg = arg; 74 | dev->d_time = DAEMON; 75 | } 76 | 77 | /* 78 | * kill_daemon: 79 | * Remove a daemon from the list 80 | */ 81 | void 82 | kill_daemon(void (*func)()) 83 | { 84 | register struct delayed_action *dev; 85 | 86 | if ((dev = find_slot(func)) == NULL) 87 | return; 88 | /* 89 | * Take it out of the list 90 | */ 91 | dev->d_type = EMPTY; 92 | } 93 | 94 | /* 95 | * do_daemons: 96 | * Run all the daemons that are active with the current flag, 97 | * passing the argument to the function. 98 | */ 99 | void 100 | do_daemons(int flag) 101 | { 102 | register struct delayed_action *dev; 103 | 104 | /* 105 | * Loop through the devil list 106 | */ 107 | for (dev = d_list; dev <= &d_list[MAXDAEMONS-1]; dev++) 108 | /* 109 | * Executing each one, giving it the proper arguments 110 | */ 111 | if (dev->d_type == flag && dev->d_time == DAEMON) 112 | (*dev->d_func)(dev->d_arg); 113 | } 114 | 115 | /* 116 | * fuse: 117 | * Start a fuse to go off in a certain number of turns 118 | */ 119 | void 120 | fuse(void (*func)(), int arg, int time, int type) 121 | { 122 | register struct delayed_action *wire; 123 | 124 | wire = d_slot(); 125 | wire->d_type = type; 126 | wire->d_func = func; 127 | wire->d_arg = arg; 128 | wire->d_time = time; 129 | } 130 | 131 | /* 132 | * lengthen: 133 | * Increase the time until a fuse goes off 134 | */ 135 | void 136 | lengthen(void (*func)(), int xtime) 137 | { 138 | register struct delayed_action *wire; 139 | 140 | if ((wire = find_slot(func)) == NULL) 141 | return; 142 | wire->d_time += xtime; 143 | } 144 | 145 | /* 146 | * extinguish: 147 | * Put out a fuse 148 | */ 149 | void 150 | extinguish(void (*func)()) 151 | { 152 | register struct delayed_action *wire; 153 | 154 | if ((wire = find_slot(func)) == NULL) 155 | return; 156 | wire->d_type = EMPTY; 157 | } 158 | 159 | /* 160 | * do_fuses: 161 | * Decrement counters and start needed fuses 162 | */ 163 | void 164 | do_fuses(int flag) 165 | { 166 | register struct delayed_action *wire; 167 | 168 | /* 169 | * Step though the list 170 | */ 171 | for (wire = d_list; wire <= &d_list[MAXDAEMONS-1]; wire++) 172 | /* 173 | * Decrementing counters and starting things we want. We also need 174 | * to remove the fuse from the list once it has gone off. 175 | */ 176 | if (flag == wire->d_type && wire->d_time > 0 && --wire->d_time == 0) 177 | { 178 | wire->d_type = EMPTY; 179 | (*wire->d_func)(wire->d_arg); 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /daemons.c: -------------------------------------------------------------------------------- 1 | /* 2 | * All the daemon and fuse functions are in here 3 | * 4 | * @(#)daemons.c 4.24 (Berkeley) 02/05/99 5 | * 6 | * Rogue: Exploring the Dungeons of Doom 7 | * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman 8 | * All rights reserved. 9 | * 10 | * See the file LICENSE.TXT for full copyright and licensing information. 11 | */ 12 | 13 | #include 14 | #include "rogue.h" 15 | 16 | /* 17 | * doctor: 18 | * A healing daemon that restors hit points after rest 19 | */ 20 | void 21 | doctor() 22 | { 23 | register int lv, ohp; 24 | 25 | lv = pstats.s_lvl; 26 | ohp = pstats.s_hpt; 27 | quiet++; 28 | if (lv < 8) 29 | { 30 | if (quiet + (lv << 1) > 20) 31 | pstats.s_hpt++; 32 | } 33 | else 34 | if (quiet >= 3) 35 | pstats.s_hpt += rnd(lv - 7) + 1; 36 | if (ISRING(LEFT, R_REGEN)) 37 | pstats.s_hpt++; 38 | if (ISRING(RIGHT, R_REGEN)) 39 | pstats.s_hpt++; 40 | if (ohp != pstats.s_hpt) 41 | { 42 | if (pstats.s_hpt > max_hp) 43 | pstats.s_hpt = max_hp; 44 | quiet = 0; 45 | } 46 | } 47 | 48 | /* 49 | * Swander: 50 | * Called when it is time to start rolling for wandering monsters 51 | */ 52 | void 53 | swander() 54 | { 55 | start_daemon(rollwand, 0, BEFORE); 56 | } 57 | 58 | /* 59 | * rollwand: 60 | * Called to roll to see if a wandering monster starts up 61 | */ 62 | int between = 0; 63 | void 64 | rollwand() 65 | { 66 | 67 | if (++between >= 4) 68 | { 69 | if (roll(1, 6) == 4) 70 | { 71 | wanderer(); 72 | kill_daemon(rollwand); 73 | fuse(swander, 0, WANDERTIME, BEFORE); 74 | } 75 | between = 0; 76 | } 77 | } 78 | 79 | /* 80 | * unconfuse: 81 | * Release the poor player from his confusion 82 | */ 83 | void 84 | unconfuse() 85 | { 86 | player.t_flags &= ~ISHUH; 87 | msg("you feel less %s now", choose_str("trippy", "confused")); 88 | } 89 | 90 | /* 91 | * unsee: 92 | * Turn off the ability to see invisible 93 | */ 94 | void 95 | unsee() 96 | { 97 | register THING *th; 98 | 99 | for (th = mlist; th != NULL; th = next(th)) 100 | if (on(*th, ISINVIS) && see_monst(th)) 101 | mvaddch(th->t_pos.y, th->t_pos.x, th->t_oldch); 102 | player.t_flags &= ~CANSEE; 103 | } 104 | 105 | /* 106 | * sight: 107 | * He gets his sight back 108 | */ 109 | void 110 | sight() 111 | { 112 | if (on(player, ISBLIND)) 113 | { 114 | extinguish(sight); 115 | player.t_flags &= ~ISBLIND; 116 | if (!(proom->r_flags & ISGONE)) 117 | enter_room(&hero); 118 | msg(choose_str("far out! Everything is all cosmic again", 119 | "the veil of darkness lifts")); 120 | } 121 | } 122 | 123 | /* 124 | * nohaste: 125 | * End the hasting 126 | */ 127 | void 128 | nohaste() 129 | { 130 | player.t_flags &= ~ISHASTE; 131 | msg("you feel yourself slowing down"); 132 | } 133 | 134 | /* 135 | * stomach: 136 | * Digest the hero's food 137 | */ 138 | void 139 | stomach() 140 | { 141 | register int oldfood; 142 | int orig_hungry = hungry_state; 143 | 144 | if (food_left <= 0) 145 | { 146 | if (food_left-- < -STARVETIME) 147 | death('s'); 148 | /* 149 | * the hero is fainting 150 | */ 151 | if (no_command || rnd(5) != 0) 152 | return; 153 | no_command += rnd(8) + 4; 154 | hungry_state = 3; 155 | if (!terse) 156 | addmsg(choose_str("the munchies overpower your motor capabilities. ", 157 | "you feel too weak from lack of food. ")); 158 | msg(choose_str("You freak out", "You faint")); 159 | } 160 | else 161 | { 162 | oldfood = food_left; 163 | food_left -= ring_eat(LEFT) + ring_eat(RIGHT) + 1 - amulet; 164 | 165 | if (food_left < MORETIME && oldfood >= MORETIME) 166 | { 167 | hungry_state = 2; 168 | msg(choose_str("the munchies are interfering with your motor capabilites", 169 | "you are starting to feel weak")); 170 | } 171 | else if (food_left < 2 * MORETIME && oldfood >= 2 * MORETIME) 172 | { 173 | hungry_state = 1; 174 | if (terse) 175 | msg(choose_str("getting the munchies", "getting hungry")); 176 | else 177 | msg(choose_str("you are getting the munchies", 178 | "you are starting to get hungry")); 179 | } 180 | } 181 | if (hungry_state != orig_hungry) { 182 | player.t_flags &= ~ISRUN; 183 | running = FALSE; 184 | to_death = FALSE; 185 | count = 0; 186 | } 187 | } 188 | 189 | /* 190 | * come_down: 191 | * Take the hero down off her acid trip. 192 | */ 193 | void 194 | come_down() 195 | { 196 | register THING *tp; 197 | register bool seemonst; 198 | 199 | if (!on(player, ISHALU)) 200 | return; 201 | 202 | kill_daemon(visuals); 203 | player.t_flags &= ~ISHALU; 204 | 205 | if (on(player, ISBLIND)) 206 | return; 207 | 208 | /* 209 | * undo the things 210 | */ 211 | for (tp = lvl_obj; tp != NULL; tp = next(tp)) 212 | if (cansee(tp->o_pos.y, tp->o_pos.x)) 213 | mvaddch(tp->o_pos.y, tp->o_pos.x, tp->o_type); 214 | 215 | /* 216 | * undo the monsters 217 | */ 218 | seemonst = on(player, SEEMONST); 219 | for (tp = mlist; tp != NULL; tp = next(tp)) 220 | { 221 | move(tp->t_pos.y, tp->t_pos.x); 222 | if (cansee(tp->t_pos.y, tp->t_pos.x)) 223 | if (!on(*tp, ISINVIS) || on(player, CANSEE)) 224 | addch(tp->t_disguise); 225 | else 226 | addch(chat(tp->t_pos.y, tp->t_pos.x)); 227 | else if (seemonst) 228 | { 229 | standout(); 230 | addch(tp->t_type); 231 | standend(); 232 | } 233 | } 234 | msg("Everything looks SO boring now."); 235 | } 236 | 237 | /* 238 | * visuals: 239 | * change the characters for the player 240 | */ 241 | void 242 | visuals() 243 | { 244 | register THING *tp; 245 | register bool seemonst; 246 | 247 | if (!after || (running && jump)) 248 | return; 249 | /* 250 | * change the things 251 | */ 252 | for (tp = lvl_obj; tp != NULL; tp = next(tp)) 253 | if (cansee(tp->o_pos.y, tp->o_pos.x)) 254 | mvaddch(tp->o_pos.y, tp->o_pos.x, rnd_thing()); 255 | 256 | /* 257 | * change the stairs 258 | */ 259 | if (!seenstairs && cansee(stairs.y, stairs.x)) 260 | mvaddch(stairs.y, stairs.x, rnd_thing()); 261 | 262 | /* 263 | * change the monsters 264 | */ 265 | seemonst = on(player, SEEMONST); 266 | for (tp = mlist; tp != NULL; tp = next(tp)) 267 | { 268 | move(tp->t_pos.y, tp->t_pos.x); 269 | if (see_monst(tp)) 270 | { 271 | if (tp->t_type == 'X' && tp->t_disguise != 'X') 272 | addch(rnd_thing()); 273 | else 274 | addch(rnd(26) + 'A'); 275 | } 276 | else if (seemonst) 277 | { 278 | standout(); 279 | addch(rnd(26) + 'A'); 280 | standend(); 281 | } 282 | } 283 | } 284 | 285 | /* 286 | * land: 287 | * Land from a levitation potion 288 | */ 289 | void 290 | land() 291 | { 292 | player.t_flags &= ~ISLEVIT; 293 | msg(choose_str("bummer! You've hit the ground", 294 | "you float gently to the ground")); 295 | } 296 | -------------------------------------------------------------------------------- /extern.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Defines for things used in mach_dep.c 3 | * 4 | * @(#)extern.h 4.35 (Berkeley) 02/05/99 5 | * 6 | * Rogue: Exploring the Dungeons of Doom 7 | * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman 8 | * All rights reserved. 9 | * 10 | * See the file LICENSE.TXT for full copyright and licensing information. 11 | */ 12 | 13 | 14 | #ifdef HAVE_CONFIG_H 15 | #ifdef PDCURSES 16 | #undef HAVE_UNISTD_H 17 | #undef HAVE_LIMITS_H 18 | #undef HAVE_MEMORY_H 19 | #undef HAVE_STRING_H 20 | #endif 21 | #include "config.h" 22 | #elif defined(__DJGPP__) 23 | #define HAVE_SYS_TYPES_H 1 24 | #define HAVE_PROCESS_H 1 25 | #define HAVE_PWD_H 1 26 | #define HAVE_TERMIOS_H 1 27 | #define HAVE_SETGID 1 28 | #define HAVE_GETGID 1 29 | #define HAVE_SETUID 1 30 | #define HAVE_GETUID 1 31 | #define HAVE_GETPASS 1 32 | #define HAVE_SPAWNL 1 33 | #define HAVE_ALARM 1 34 | #define HAVE_ERASECHAR 1 35 | #define HAVE_KILLCHAR 1 36 | #elif defined(_WIN32) 37 | #define HAVE_CURSES_H 38 | #define HAVE_TERM_H 39 | #define HAVE__SPAWNL 40 | #define HAVE_SYS_TYPES_H 41 | #define HAVE_PROCESS_H 42 | #define HAVE_ERASECHAR 1 43 | #define HAVE_KILLCHAR 1 44 | #elif defined(__CYGWIN__) 45 | #define HAVE_SYS_TYPES_H 1 46 | #define HAVE_PWD_H 1 47 | #define HAVE_PWD_H 1 48 | #define HAVE_SYS_UTSNAME_H 1 49 | #define HAVE_ARPA_INET_H 1 50 | #define HAVE_UNISTD_H 1 51 | #define HAVE_TERMIOS_H 1 52 | #define HAVE_NCURSES_TERM_H 1 53 | #define HAVE_ESCDELAY 54 | #define HAVE_SETGID 1 55 | #define HAVE_GETGID 1 56 | #define HAVE_SETUID 1 57 | #define HAVE_GETUID 1 58 | #define HAVE_GETPASS 1 59 | #define HAVE_GETPWUID 1 60 | #define HAVE_WORKING_FORK 1 61 | #define HAVE_ALARM 1 62 | #define HAVE_SPAWNL 1 63 | #define HAVE__SPAWNL 1 64 | #define HAVE_ERASECHAR 1 65 | #define HAVE_KILLCHAR 1 66 | #else /* POSIX */ 67 | #define HAVE_SYS_TYPES_H 1 68 | #define HAVE_PWD_H 1 69 | #define HAVE_PWD_H 1 70 | #define HAVE_SYS_UTSNAME_H 1 71 | #define HAVE_ARPA_INET_H 1 72 | #define HAVE_UNISTD_H 1 73 | #define HAVE_TERMIOS_H 1 74 | #define HAVE_TERM_H 1 75 | #define HAVE_SETGID 1 76 | #define HAVE_GETGID 1 77 | #define HAVE_SETUID 1 78 | #define HAVE_GETUID 1 79 | #define HAVE_SETREUID 1 80 | #define HAVE_SETREGID 1 81 | #define HAVE_GETPASS 1 82 | #define HAVE_GETPWUID 1 83 | #define HAVE_WORKING_FORK 1 84 | #define HAVE_ERASECHAR 1 85 | #define HAVE_KILLCHAR 1 86 | #ifndef _AIX 87 | #define HAVE_GETLOADAVG 1 88 | #endif 89 | #define HAVE_ALARM 1 90 | #endif 91 | 92 | #ifdef __DJGPP__ 93 | #undef HAVE_GETPWUID /* DJGPP's limited version doesn't even work as documented */ 94 | #endif 95 | 96 | /* 97 | * Don't change the constants, since they are used for sizes in many 98 | * places in the program. 99 | */ 100 | 101 | #include 102 | 103 | #undef SIGTSTP 104 | 105 | #define MAXSTR 1024 /* maximum length of strings */ 106 | #define MAXLINES 32 /* maximum number of screen lines used */ 107 | #define MAXCOLS 80 /* maximum number of screen columns used */ 108 | 109 | #define RN (((seed = seed*11109+13849) >> 16) & 0xffff) 110 | #ifdef CTRL 111 | #undef CTRL 112 | #endif 113 | #define CTRL(c) (c & 037) 114 | 115 | /* 116 | * Now all the global variables 117 | */ 118 | 119 | extern bool got_ltc, in_shell; 120 | extern int wizard; 121 | extern char fruit[], prbuf[], whoami[]; 122 | extern int orig_dsusp; 123 | extern FILE *scoreboard; 124 | 125 | /* 126 | * Function types 127 | */ 128 | 129 | void auto_save(int); 130 | void come_down(); 131 | void doctor(); 132 | void end_line(); 133 | void endit(int sig); 134 | void fatal(); 135 | void getltchars(); 136 | void land(); 137 | void leave(int); 138 | void my_exit(); 139 | void nohaste(); 140 | void playit(); 141 | void playltchars(void); 142 | void print_disc(char); 143 | void quit(int); 144 | void resetltchars(void); 145 | void rollwand(); 146 | void runners(); 147 | void set_order(); 148 | void sight(); 149 | void stomach(); 150 | void swander(); 151 | void tstp(int ignored); 152 | void unconfuse(); 153 | void unsee(); 154 | void visuals(); 155 | 156 | char add_line(char *fmt, char *arg); 157 | 158 | char *killname(char monst, bool doart); 159 | char *nothing(char type); 160 | char *type_name(int type); 161 | 162 | #ifdef CHECKTIME 163 | int checkout(); 164 | #endif 165 | 166 | int md_chmod(char *filename, int mode); 167 | char *md_crypt(char *key, char *salt); 168 | int md_dsuspchar(); 169 | int md_erasechar(); 170 | char *md_gethomedir(); 171 | char *md_getusername(); 172 | int md_getuid(); 173 | char *md_getpass(char *prompt); 174 | int md_getpid(); 175 | char *md_getrealname(int uid); 176 | void md_init(); 177 | int md_killchar(); 178 | void md_normaluser(); 179 | void md_raw_standout(); 180 | void md_raw_standend(); 181 | int md_readchar(); 182 | int md_setdsuspchar(int c); 183 | int md_shellescape(); 184 | void md_sleep(int s); 185 | int md_suspchar(); 186 | int md_hasclreol(); 187 | int md_unlink(char *file); 188 | int md_unlink_open_file(char *file, FILE *inf); 189 | void md_tstpsignal(); 190 | void md_tstphold(); 191 | void md_tstpresume(); 192 | void md_ignoreallsignals(); 193 | void md_onsignal_autosave(); 194 | void md_onsignal_exit(); 195 | void md_onsignal_default(); 196 | int md_issymlink(char *sp); 197 | 198 | -------------------------------------------------------------------------------- /init.c: -------------------------------------------------------------------------------- 1 | /* 2 | * global variable initializaton 3 | * 4 | * @(#)init.c 4.31 (Berkeley) 02/05/99 5 | * 6 | * Rogue: Exploring the Dungeons of Doom 7 | * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman 8 | * All rights reserved. 9 | * 10 | * See the file LICENSE.TXT for full copyright and licensing information. 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "rogue.h" 18 | 19 | /* 20 | * init_player: 21 | * Roll her up 22 | */ 23 | void 24 | init_player() 25 | { 26 | register THING *obj; 27 | 28 | pstats = max_stats; 29 | food_left = HUNGERTIME; 30 | /* 31 | * Give him some food 32 | */ 33 | obj = new_item(); 34 | obj->o_type = FOOD; 35 | obj->o_count = 1; 36 | add_pack(obj, TRUE); 37 | /* 38 | * And his suit of armor 39 | */ 40 | obj = new_item(); 41 | obj->o_type = ARMOR; 42 | obj->o_which = RING_MAIL; 43 | obj->o_arm = a_class[RING_MAIL] - 1; 44 | obj->o_flags |= ISKNOW; 45 | obj->o_count = 1; 46 | cur_armor = obj; 47 | add_pack(obj, TRUE); 48 | /* 49 | * Give him his weaponry. First a mace. 50 | */ 51 | obj = new_item(); 52 | init_weapon(obj, MACE); 53 | obj->o_hplus = 1; 54 | obj->o_dplus = 1; 55 | obj->o_flags |= ISKNOW; 56 | add_pack(obj, TRUE); 57 | cur_weapon = obj; 58 | /* 59 | * Now a +1 bow 60 | */ 61 | obj = new_item(); 62 | init_weapon(obj, BOW); 63 | obj->o_hplus = 1; 64 | obj->o_flags |= ISKNOW; 65 | add_pack(obj, TRUE); 66 | /* 67 | * Now some arrows 68 | */ 69 | obj = new_item(); 70 | init_weapon(obj, ARROW); 71 | obj->o_count = rnd(15) + 25; 72 | obj->o_flags |= ISKNOW; 73 | add_pack(obj, TRUE); 74 | } 75 | 76 | /* 77 | * Contains defintions and functions for dealing with things like 78 | * potions and scrolls 79 | */ 80 | 81 | char *rainbow[] = { 82 | "amber", 83 | "aquamarine", 84 | "black", 85 | "blue", 86 | "brown", 87 | "clear", 88 | "crimson", 89 | "cyan", 90 | "ecru", 91 | "gold", 92 | "green", 93 | "grey", 94 | "magenta", 95 | "orange", 96 | "pink", 97 | "plaid", 98 | "purple", 99 | "red", 100 | "silver", 101 | "tan", 102 | "tangerine", 103 | "topaz", 104 | "turquoise", 105 | "vermilion", 106 | "violet", 107 | "white", 108 | "yellow", 109 | }; 110 | 111 | #define NCOLORS (sizeof rainbow / sizeof (char *)) 112 | int cNCOLORS = NCOLORS; 113 | 114 | static char *sylls[] = { 115 | "a", "ab", "ag", "aks", "ala", "an", "app", "arg", "arze", "ash", 116 | "bek", "bie", "bit", "bjor", "blu", "bot", "bu", "byt", "comp", 117 | "con", "cos", "cre", "dalf", "dan", "den", "do", "e", "eep", "el", 118 | "eng", "er", "ere", "erk", "esh", "evs", "fa", "fid", "fri", "fu", 119 | "gan", "gar", "glen", "gop", "gre", "ha", "hyd", "i", "ing", "ip", 120 | "ish", "it", "ite", "iv", "jo", "kho", "kli", "klis", "la", "lech", 121 | "mar", "me", "mi", "mic", "mik", "mon", "mung", "mur", "nej", 122 | "nelg", "nep", "ner", "nes", "nes", "nih", "nin", "o", "od", "ood", 123 | "org", "orn", "ox", "oxy", "pay", "ple", "plu", "po", "pot", 124 | "prok", "re", "rea", "rhov", "ri", "ro", "rog", "rok", "rol", "sa", 125 | "san", "sat", "sef", "seh", "shu", "ski", "sna", "sne", "snik", 126 | "sno", "so", "sol", "sri", "sta", "sun", "ta", "tab", "tem", 127 | "ther", "ti", "tox", "trol", "tue", "turs", "u", "ulk", "um", "un", 128 | "uni", "ur", "val", "viv", "vly", "vom", "wah", "wed", "werg", 129 | "wex", "whon", "wun", "xo", "y", "yot", "yu", "zant", "zeb", "zim", 130 | "zok", "zon", "zum", 131 | }; 132 | 133 | STONE stones[] = { 134 | { "agate", 25}, 135 | { "alexandrite", 40}, 136 | { "amethyst", 50}, 137 | { "carnelian", 40}, 138 | { "diamond", 300}, 139 | { "emerald", 300}, 140 | { "germanium", 225}, 141 | { "granite", 5}, 142 | { "garnet", 50}, 143 | { "jade", 150}, 144 | { "kryptonite", 300}, 145 | { "lapis lazuli", 50}, 146 | { "moonstone", 50}, 147 | { "obsidian", 15}, 148 | { "onyx", 60}, 149 | { "opal", 200}, 150 | { "pearl", 220}, 151 | { "peridot", 63}, 152 | { "ruby", 350}, 153 | { "sapphire", 285}, 154 | { "stibotantalite", 200}, 155 | { "tiger eye", 50}, 156 | { "topaz", 60}, 157 | { "turquoise", 70}, 158 | { "taaffeite", 300}, 159 | { "zircon", 80}, 160 | }; 161 | 162 | #define NSTONES (sizeof stones / sizeof (STONE)) 163 | int cNSTONES = NSTONES; 164 | 165 | char *wood[] = { 166 | "avocado wood", 167 | "balsa", 168 | "bamboo", 169 | "banyan", 170 | "birch", 171 | "cedar", 172 | "cherry", 173 | "cinnibar", 174 | "cypress", 175 | "dogwood", 176 | "driftwood", 177 | "ebony", 178 | "elm", 179 | "eucalyptus", 180 | "fall", 181 | "hemlock", 182 | "holly", 183 | "ironwood", 184 | "kukui wood", 185 | "mahogany", 186 | "manzanita", 187 | "maple", 188 | "oaken", 189 | "persimmon wood", 190 | "pecan", 191 | "pine", 192 | "poplar", 193 | "redwood", 194 | "rosewood", 195 | "spruce", 196 | "teak", 197 | "walnut", 198 | "zebrawood", 199 | }; 200 | 201 | #define NWOOD (sizeof wood / sizeof (char *)) 202 | int cNWOOD = NWOOD; 203 | 204 | char *metal[] = { 205 | "aluminum", 206 | "beryllium", 207 | "bone", 208 | "brass", 209 | "bronze", 210 | "copper", 211 | "electrum", 212 | "gold", 213 | "iron", 214 | "lead", 215 | "magnesium", 216 | "mercury", 217 | "nickel", 218 | "pewter", 219 | "platinum", 220 | "steel", 221 | "silver", 222 | "silicon", 223 | "tin", 224 | "titanium", 225 | "tungsten", 226 | "zinc", 227 | }; 228 | 229 | #define NMETAL (sizeof metal / sizeof (char *)) 230 | int cNMETAL = NMETAL; 231 | #define MAX3(a,b,c) (a > b ? (a > c ? a : c) : (b > c ? b : c)) 232 | 233 | static bool used[MAX3(NCOLORS, NSTONES, NWOOD)]; 234 | 235 | /* 236 | * init_colors: 237 | * Initialize the potion color scheme for this time 238 | */ 239 | void 240 | init_colors() 241 | { 242 | register int i, j; 243 | 244 | for (i = 0; i < NCOLORS; i++) 245 | used[i] = FALSE; 246 | for (i = 0; i < MAXPOTIONS; i++) 247 | { 248 | do 249 | j = rnd(NCOLORS); 250 | until (!used[j]); 251 | used[j] = TRUE; 252 | p_colors[i] = rainbow[j]; 253 | } 254 | } 255 | 256 | /* 257 | * init_names: 258 | * Generate the names of the various scrolls 259 | */ 260 | #define MAXNAME 40 /* Max number of characters in a name */ 261 | 262 | void 263 | init_names() 264 | { 265 | register int nsyl; 266 | register char *cp, *sp; 267 | register int i, nwords; 268 | 269 | for (i = 0; i < MAXSCROLLS; i++) 270 | { 271 | cp = prbuf; 272 | nwords = rnd(3) + 2; 273 | while (nwords--) 274 | { 275 | nsyl = rnd(3) + 1; 276 | while (nsyl--) 277 | { 278 | sp = sylls[rnd((sizeof sylls) / (sizeof (char *)))]; 279 | if (&cp[strlen(sp)] > &prbuf[MAXNAME]) 280 | break; 281 | while (*sp) 282 | *cp++ = *sp++; 283 | } 284 | *cp++ = ' '; 285 | } 286 | *--cp = '\0'; 287 | s_names[i] = (char *) malloc((unsigned) strlen(prbuf)+1); 288 | strcpy(s_names[i], prbuf); 289 | } 290 | } 291 | 292 | /* 293 | * init_stones: 294 | * Initialize the ring stone setting scheme for this time 295 | */ 296 | void 297 | init_stones() 298 | { 299 | register int i, j; 300 | 301 | for (i = 0; i < NSTONES; i++) 302 | used[i] = FALSE; 303 | for (i = 0; i < MAXRINGS; i++) 304 | { 305 | do 306 | j = rnd(NSTONES); 307 | until (!used[j]); 308 | used[j] = TRUE; 309 | r_stones[i] = stones[j].st_name; 310 | ring_info[i].oi_worth += stones[j].st_value; 311 | } 312 | } 313 | 314 | /* 315 | * init_materials: 316 | * Initialize the construction materials for wands and staffs 317 | */ 318 | void 319 | init_materials() 320 | { 321 | register int i, j; 322 | register char *str; 323 | static bool metused[NMETAL]; 324 | 325 | for (i = 0; i < NWOOD; i++) 326 | used[i] = FALSE; 327 | for (i = 0; i < NMETAL; i++) 328 | metused[i] = FALSE; 329 | for (i = 0; i < MAXSTICKS; i++) 330 | { 331 | for (;;) 332 | if (rnd(2) == 0) 333 | { 334 | j = rnd(NMETAL); 335 | if (!metused[j]) 336 | { 337 | ws_type[i] = "wand"; 338 | str = metal[j]; 339 | metused[j] = TRUE; 340 | break; 341 | } 342 | } 343 | else 344 | { 345 | j = rnd(NWOOD); 346 | if (!used[j]) 347 | { 348 | ws_type[i] = "staff"; 349 | str = wood[j]; 350 | used[j] = TRUE; 351 | break; 352 | } 353 | } 354 | ws_made[i] = str; 355 | } 356 | } 357 | 358 | #ifdef MASTER 359 | # define NT NUMTHINGS, "things" 360 | # define MP MAXPOTIONS, "potions" 361 | # define MS MAXSCROLLS, "scrolls" 362 | # define MR MAXRINGS, "rings" 363 | # define MWS MAXSTICKS, "sticks" 364 | # define MW MAXWEAPONS, "weapons" 365 | # define MA MAXARMORS, "armor" 366 | #else 367 | # define NT NUMTHINGS 368 | # define MP MAXPOTIONS 369 | # define MS MAXSCROLLS 370 | # define MR MAXRINGS 371 | # define MWS MAXSTICKS 372 | # define MW MAXWEAPONS 373 | # define MA MAXARMORS 374 | #endif 375 | 376 | /* 377 | * sumprobs: 378 | * Sum up the probabilities for items appearing 379 | */ 380 | void 381 | sumprobs(struct obj_info *info, int bound 382 | #ifdef MASTER 383 | , char *name 384 | #endif 385 | ) 386 | { 387 | #ifdef MASTER 388 | struct obj_info *start = info; 389 | #endif 390 | struct obj_info *endp; 391 | 392 | endp = info + bound; 393 | while (++info < endp) 394 | info->oi_prob += (info - 1)->oi_prob; 395 | #ifdef MASTER 396 | badcheck(name, start, bound); 397 | #endif 398 | } 399 | 400 | /* 401 | * init_probs: 402 | * Initialize the probabilities for the various items 403 | */ 404 | void 405 | init_probs() 406 | { 407 | sumprobs(things, NT); 408 | sumprobs(pot_info, MP); 409 | sumprobs(scr_info, MS); 410 | sumprobs(ring_info, MR); 411 | sumprobs(ws_info, MWS); 412 | sumprobs(weap_info, MW); 413 | sumprobs(arm_info, MA); 414 | } 415 | 416 | #ifdef MASTER 417 | /* 418 | * badcheck: 419 | * Check to see if a series of probabilities sums to 100 420 | */ 421 | void 422 | badcheck(char *name, struct obj_info *info, int bound) 423 | { 424 | register struct obj_info *end; 425 | 426 | if (info[bound - 1].oi_prob == 100) 427 | return; 428 | printf("\nBad percentages for %s (bound = %d):\n", name, bound); 429 | for (end = &info[bound]; info < end; info++) 430 | printf("%3d%% %s\n", info->oi_prob, info->oi_name); 431 | printf("[hit RETURN to continue]"); 432 | fflush(stdout); 433 | while (getchar() != '\n') 434 | continue; 435 | } 436 | #endif 437 | 438 | /* 439 | * pick_color: 440 | * If he is halucinating, pick a random color name and return it, 441 | * otherwise return the given color. 442 | */ 443 | char * 444 | pick_color(char *col) 445 | { 446 | return (on(player, ISHALU) ? rainbow[rnd(NCOLORS)] : col); 447 | } 448 | -------------------------------------------------------------------------------- /install-sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # install - install a program, script, or datafile 3 | 4 | scriptversion=2005-05-14.22 5 | 6 | # This originates from X11R5 (mit/util/scripts/install.sh), which was 7 | # later released in X11R6 (xc/config/util/install.sh) with the 8 | # following copyright and license. 9 | # 10 | # Copyright (C) 1994 X Consortium 11 | # 12 | # Permission is hereby granted, free of charge, to any person obtaining a copy 13 | # of this software and associated documentation files (the "Software"), to 14 | # deal in the Software without restriction, including without limitation the 15 | # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16 | # sell copies of the Software, and to permit persons to whom the Software is 17 | # furnished to do so, subject to the following conditions: 18 | # 19 | # The above copyright notice and this permission notice shall be included in 20 | # all copies or substantial portions of the Software. 21 | # 22 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26 | # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27 | # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | # 29 | # Except as contained in this notice, the name of the X Consortium shall not 30 | # be used in advertising or otherwise to promote the sale, use or other deal- 31 | # ings in this Software without prior written authorization from the X Consor- 32 | # tium. 33 | # 34 | # 35 | # FSF changes to this file are in the public domain. 36 | # 37 | # Calling this script install-sh is preferred over install.sh, to prevent 38 | # `make' implicit rules from creating a file called install from it 39 | # when there is no Makefile. 40 | # 41 | # This script is compatible with the BSD install script, but was written 42 | # from scratch. It can only install one file at a time, a restriction 43 | # shared with many OS's install programs. 44 | 45 | # set DOITPROG to echo to test this script 46 | 47 | # Don't use :- since 4.3BSD and earlier shells don't like it. 48 | doit="${DOITPROG-}" 49 | 50 | # put in absolute paths if you don't have them in your path; or use env. vars. 51 | 52 | mvprog="${MVPROG-mv}" 53 | cpprog="${CPPROG-cp}" 54 | chmodprog="${CHMODPROG-chmod}" 55 | chownprog="${CHOWNPROG-chown}" 56 | chgrpprog="${CHGRPPROG-chgrp}" 57 | stripprog="${STRIPPROG-strip}" 58 | rmprog="${RMPROG-rm}" 59 | mkdirprog="${MKDIRPROG-mkdir}" 60 | 61 | chmodcmd="$chmodprog 0755" 62 | chowncmd= 63 | chgrpcmd= 64 | stripcmd= 65 | rmcmd="$rmprog -f" 66 | mvcmd="$mvprog" 67 | src= 68 | dst= 69 | dir_arg= 70 | dstarg= 71 | no_target_directory= 72 | 73 | usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE 74 | or: $0 [OPTION]... SRCFILES... DIRECTORY 75 | or: $0 [OPTION]... -t DIRECTORY SRCFILES... 76 | or: $0 [OPTION]... -d DIRECTORIES... 77 | 78 | In the 1st form, copy SRCFILE to DSTFILE. 79 | In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 80 | In the 4th, create DIRECTORIES. 81 | 82 | Options: 83 | -c (ignored) 84 | -d create directories instead of installing files. 85 | -g GROUP $chgrpprog installed files to GROUP. 86 | -m MODE $chmodprog installed files to MODE. 87 | -o USER $chownprog installed files to USER. 88 | -s $stripprog installed files. 89 | -t DIRECTORY install into DIRECTORY. 90 | -T report an error if DSTFILE is a directory. 91 | --help display this help and exit. 92 | --version display version info and exit. 93 | 94 | Environment variables override the default commands: 95 | CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG 96 | " 97 | 98 | while test -n "$1"; do 99 | case $1 in 100 | -c) shift 101 | continue;; 102 | 103 | -d) dir_arg=true 104 | shift 105 | continue;; 106 | 107 | -g) chgrpcmd="$chgrpprog $2" 108 | shift 109 | shift 110 | continue;; 111 | 112 | --help) echo "$usage"; exit $?;; 113 | 114 | -m) chmodcmd="$chmodprog $2" 115 | shift 116 | shift 117 | continue;; 118 | 119 | -o) chowncmd="$chownprog $2" 120 | shift 121 | shift 122 | continue;; 123 | 124 | -s) stripcmd=$stripprog 125 | shift 126 | continue;; 127 | 128 | -t) dstarg=$2 129 | shift 130 | shift 131 | continue;; 132 | 133 | -T) no_target_directory=true 134 | shift 135 | continue;; 136 | 137 | --version) echo "$0 $scriptversion"; exit $?;; 138 | 139 | *) # When -d is used, all remaining arguments are directories to create. 140 | # When -t is used, the destination is already specified. 141 | test -n "$dir_arg$dstarg" && break 142 | # Otherwise, the last argument is the destination. Remove it from $@. 143 | for arg 144 | do 145 | if test -n "$dstarg"; then 146 | # $@ is not empty: it contains at least $arg. 147 | set fnord "$@" "$dstarg" 148 | shift # fnord 149 | fi 150 | shift # arg 151 | dstarg=$arg 152 | done 153 | break;; 154 | esac 155 | done 156 | 157 | if test -z "$1"; then 158 | if test -z "$dir_arg"; then 159 | echo "$0: no input file specified." >&2 160 | exit 1 161 | fi 162 | # It's OK to call `install-sh -d' without argument. 163 | # This can happen when creating conditional directories. 164 | exit 0 165 | fi 166 | 167 | for src 168 | do 169 | # Protect names starting with `-'. 170 | case $src in 171 | -*) src=./$src ;; 172 | esac 173 | 174 | if test -n "$dir_arg"; then 175 | dst=$src 176 | src= 177 | 178 | if test -d "$dst"; then 179 | mkdircmd=: 180 | chmodcmd= 181 | else 182 | mkdircmd=$mkdirprog 183 | fi 184 | else 185 | # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 186 | # might cause directories to be created, which would be especially bad 187 | # if $src (and thus $dsttmp) contains '*'. 188 | if test ! -f "$src" && test ! -d "$src"; then 189 | echo "$0: $src does not exist." >&2 190 | exit 1 191 | fi 192 | 193 | if test -z "$dstarg"; then 194 | echo "$0: no destination specified." >&2 195 | exit 1 196 | fi 197 | 198 | dst=$dstarg 199 | # Protect names starting with `-'. 200 | case $dst in 201 | -*) dst=./$dst ;; 202 | esac 203 | 204 | # If destination is a directory, append the input filename; won't work 205 | # if double slashes aren't ignored. 206 | if test -d "$dst"; then 207 | if test -n "$no_target_directory"; then 208 | echo "$0: $dstarg: Is a directory" >&2 209 | exit 1 210 | fi 211 | dst=$dst/`basename "$src"` 212 | fi 213 | fi 214 | 215 | # This sed command emulates the dirname command. 216 | dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'` 217 | 218 | # Make sure that the destination directory exists. 219 | 220 | # Skip lots of stat calls in the usual case. 221 | if test ! -d "$dstdir"; then 222 | defaultIFS=' 223 | ' 224 | IFS="${IFS-$defaultIFS}" 225 | 226 | oIFS=$IFS 227 | # Some sh's can't handle IFS=/ for some reason. 228 | IFS='%' 229 | set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'` 230 | shift 231 | IFS=$oIFS 232 | 233 | pathcomp= 234 | 235 | while test $# -ne 0 ; do 236 | pathcomp=$pathcomp$1 237 | shift 238 | if test ! -d "$pathcomp"; then 239 | $mkdirprog "$pathcomp" 240 | # mkdir can fail with a `File exist' error in case several 241 | # install-sh are creating the directory concurrently. This 242 | # is OK. 243 | test -d "$pathcomp" || exit 244 | fi 245 | pathcomp=$pathcomp/ 246 | done 247 | fi 248 | 249 | if test -n "$dir_arg"; then 250 | $doit $mkdircmd "$dst" \ 251 | && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \ 252 | && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \ 253 | && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \ 254 | && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; } 255 | 256 | else 257 | dstfile=`basename "$dst"` 258 | 259 | # Make a couple of temp file names in the proper directory. 260 | dsttmp=$dstdir/_inst.$$_ 261 | rmtmp=$dstdir/_rm.$$_ 262 | 263 | # Trap to clean up those temp files at exit. 264 | trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 265 | trap '(exit $?); exit' 1 2 13 15 266 | 267 | # Copy the file name to the temp name. 268 | $doit $cpprog "$src" "$dsttmp" && 269 | 270 | # and set any options; do chmod last to preserve setuid bits. 271 | # 272 | # If any of these fail, we abort the whole thing. If we want to 273 | # ignore errors from any of these, just make sure not to ignore 274 | # errors from the above "$doit $cpprog $src $dsttmp" command. 275 | # 276 | { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ 277 | && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ 278 | && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ 279 | && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } && 280 | 281 | # Now rename the file to the real destination. 282 | { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \ 283 | || { 284 | # The rename failed, perhaps because mv can't rename something else 285 | # to itself, or perhaps because mv is so ancient that it does not 286 | # support -f. 287 | 288 | # Now remove or move aside any old file at destination location. 289 | # We try this two ways since rm can't unlink itself on some 290 | # systems and the destination file might be busy for other 291 | # reasons. In this case, the final cleanup might fail but the new 292 | # file should still install successfully. 293 | { 294 | if test -f "$dstdir/$dstfile"; then 295 | $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \ 296 | || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \ 297 | || { 298 | echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2 299 | (exit 1); exit 1 300 | } 301 | else 302 | : 303 | fi 304 | } && 305 | 306 | # Now rename the file to the real destination. 307 | $doit $mvcmd "$dsttmp" "$dstdir/$dstfile" 308 | } 309 | } 310 | fi || { (exit 1); exit 1; } 311 | done 312 | 313 | # The final little trick to "correctly" pass the exit status to the exit trap. 314 | { 315 | (exit 0); exit 0 316 | } 317 | 318 | # Local variables: 319 | # eval: (add-hook 'write-file-hooks 'time-stamp) 320 | # time-stamp-start: "scriptversion=" 321 | # time-stamp-format: "%:y-%02m-%02d.%02H" 322 | # time-stamp-end: "$" 323 | # End: 324 | -------------------------------------------------------------------------------- /io.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Various input/output functions 3 | * 4 | * @(#)io.c 4.32 (Berkeley) 02/05/99 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "rogue.h" 12 | 13 | /* 14 | * msg: 15 | * Display a message at the top of the screen. 16 | */ 17 | #define MAXMSG (NUMCOLS - sizeof "--More--") 18 | 19 | static char msgbuf[2*MAXMSG+1]; 20 | static int newpos = 0; 21 | 22 | /* VARARGS1 */ 23 | int 24 | msg(char *fmt, ...) 25 | { 26 | va_list args; 27 | 28 | /* 29 | * if the string is "", just clear the line 30 | */ 31 | if (*fmt == '\0') 32 | { 33 | move(0, 0); 34 | clrtoeol(); 35 | mpos = 0; 36 | return ~ESCAPE; 37 | } 38 | /* 39 | * otherwise add to the message and flush it out 40 | */ 41 | va_start(args, fmt); 42 | doadd(fmt, args); 43 | va_end(args); 44 | return endmsg(); 45 | } 46 | 47 | /* 48 | * addmsg: 49 | * Add things to the current message 50 | */ 51 | /* VARARGS1 */ 52 | void 53 | addmsg(char *fmt, ...) 54 | { 55 | va_list args; 56 | 57 | va_start(args, fmt); 58 | doadd(fmt, args); 59 | va_end(args); 60 | } 61 | 62 | /* 63 | * endmsg: 64 | * Display a new msg (giving him a chance to see the previous one 65 | * if it is up there with the --More--) 66 | */ 67 | int 68 | endmsg() 69 | { 70 | char ch; 71 | 72 | if (save_msg) 73 | strcpy(huh, msgbuf); 74 | if (mpos) 75 | { 76 | look(FALSE); 77 | mvaddstr(0, mpos, "--More--"); 78 | refresh(); 79 | if (!msg_esc) 80 | wait_for(' '); 81 | else 82 | { 83 | while ((ch = readchar()) != ' ') 84 | if (ch == ESCAPE) 85 | { 86 | msgbuf[0] = '\0'; 87 | mpos = 0; 88 | newpos = 0; 89 | msgbuf[0] = '\0'; 90 | return ESCAPE; 91 | } 92 | } 93 | } 94 | /* 95 | * All messages should start with uppercase, except ones that 96 | * start with a pack addressing character 97 | */ 98 | if (islower(msgbuf[0]) && !lower_msg && msgbuf[1] != ')') 99 | msgbuf[0] = (char) toupper(msgbuf[0]); 100 | mvaddstr(0, 0, msgbuf); 101 | clrtoeol(); 102 | mpos = newpos; 103 | newpos = 0; 104 | msgbuf[0] = '\0'; 105 | refresh(); 106 | return ~ESCAPE; 107 | } 108 | 109 | /* 110 | * doadd: 111 | * Perform an add onto the message buffer 112 | */ 113 | void 114 | doadd(char *fmt, va_list args) 115 | { 116 | static char buf[MAXSTR]; 117 | 118 | /* 119 | * Do the printf into buf 120 | */ 121 | vsprintf(buf, fmt, args); 122 | if (strlen(buf) + newpos >= MAXMSG) 123 | endmsg(); 124 | strcat(msgbuf, buf); 125 | newpos = (int) strlen(msgbuf); 126 | } 127 | 128 | /* 129 | * step_ok: 130 | * Returns true if it is ok to step on ch 131 | */ 132 | int 133 | step_ok(int ch) 134 | { 135 | switch (ch) 136 | { 137 | case ' ': 138 | case '|': 139 | case '-': 140 | return FALSE; 141 | default: 142 | return (!isalpha(ch)); 143 | } 144 | } 145 | 146 | /* 147 | * readchar: 148 | * Reads and returns a character, checking for gross input errors 149 | */ 150 | char 151 | readchar() 152 | { 153 | char ch; 154 | 155 | ch = (char) md_readchar(); 156 | 157 | if (ch == 3) 158 | { 159 | quit(0); 160 | return(27); 161 | } 162 | 163 | return(ch); 164 | } 165 | 166 | /* 167 | * status: 168 | * Display the important stats line. Keep the cursor where it was. 169 | */ 170 | void 171 | status() 172 | { 173 | register int oy, ox, temp; 174 | static int hpwidth = 0; 175 | static int s_hungry = 0; 176 | static int s_lvl = 0; 177 | static int s_pur = -1; 178 | static int s_hp = 0; 179 | static int s_arm = 0; 180 | static str_t s_str = 0; 181 | static int s_exp = 0; 182 | static char *state_name[] = 183 | { 184 | "", "Hungry", "Weak", "Faint" 185 | }; 186 | 187 | /* 188 | * If nothing has changed since the last status, don't 189 | * bother. 190 | */ 191 | temp = (cur_armor != NULL ? cur_armor->o_arm : pstats.s_arm); 192 | if (s_hp == pstats.s_hpt && s_exp == pstats.s_exp && s_pur == purse 193 | && s_arm == temp && s_str == pstats.s_str && s_lvl == level 194 | && s_hungry == hungry_state 195 | && !stat_msg 196 | ) 197 | return; 198 | 199 | s_arm = temp; 200 | 201 | getyx(stdscr, oy, ox); 202 | if (s_hp != max_hp) 203 | { 204 | temp = max_hp; 205 | s_hp = max_hp; 206 | for (hpwidth = 0; temp; hpwidth++) 207 | temp /= 10; 208 | } 209 | 210 | /* 211 | * Save current status 212 | */ 213 | s_lvl = level; 214 | s_pur = purse; 215 | s_hp = pstats.s_hpt; 216 | s_str = pstats.s_str; 217 | s_exp = pstats.s_exp; 218 | s_hungry = hungry_state; 219 | 220 | if (stat_msg) 221 | { 222 | move(0, 0); 223 | msg("Level: %d Gold: %-5d Hp: %*d(%*d) Str: %2d(%d) Arm: %-2d Exp: %d/%ld %s", 224 | level, purse, hpwidth, pstats.s_hpt, hpwidth, max_hp, pstats.s_str, 225 | max_stats.s_str, 10 - s_arm, pstats.s_lvl, pstats.s_exp, 226 | state_name[hungry_state]); 227 | } 228 | else 229 | { 230 | move(STATLINE, 0); 231 | 232 | printw("Level: %d Gold: %-5d Hp: %*d(%*d) Str: %2d(%d) Arm: %-2d Exp: %d/%d %s", 233 | level, purse, hpwidth, pstats.s_hpt, hpwidth, max_hp, pstats.s_str, 234 | max_stats.s_str, 10 - s_arm, pstats.s_lvl, pstats.s_exp, 235 | state_name[hungry_state]); 236 | } 237 | 238 | clrtoeol(); 239 | move(oy, ox); 240 | } 241 | 242 | /* 243 | * wait_for 244 | * Sit around until the guy types the right key 245 | */ 246 | void 247 | wait_for(int ch) 248 | { 249 | register char c; 250 | 251 | if (ch == '\n') 252 | while ((c = readchar()) != '\n' && c != '\r') 253 | continue; 254 | else 255 | while (readchar() != ch) 256 | continue; 257 | } 258 | 259 | /* 260 | * show_win: 261 | * Function used to display a window and wait before returning 262 | */ 263 | void 264 | show_win(char *message) 265 | { 266 | WINDOW *win; 267 | 268 | win = hw; 269 | wmove(win, 0, 0); 270 | waddstr(win, message); 271 | touchwin(win); 272 | wmove(win, hero.y, hero.x); 273 | wrefresh(win); 274 | wait_for(' '); 275 | clearok(curscr, TRUE); 276 | touchwin(stdscr); 277 | } 278 | -------------------------------------------------------------------------------- /list.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Functions for dealing with linked lists of goodies 3 | * 4 | * @(#)list.c 4.12 (Berkeley) 02/05/99 5 | * 6 | * Rogue: Exploring the Dungeons of Doom 7 | * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman 8 | * All rights reserved. 9 | * 10 | * See the file LICENSE.TXT for full copyright and licensing information. 11 | */ 12 | 13 | #include 14 | #include 15 | #include "rogue.h" 16 | 17 | #ifdef MASTER 18 | int total = 0; /* total dynamic memory bytes */ 19 | #endif 20 | 21 | /* 22 | * detach: 23 | * takes an item out of whatever linked list it might be in 24 | */ 25 | 26 | void 27 | _detach(THING **list, THING *item) 28 | { 29 | if (*list == item) 30 | *list = next(item); 31 | if (prev(item) != NULL) 32 | item->l_prev->l_next = next(item); 33 | if (next(item) != NULL) 34 | item->l_next->l_prev = prev(item); 35 | item->l_next = NULL; 36 | item->l_prev = NULL; 37 | } 38 | 39 | /* 40 | * _attach: 41 | * add an item to the head of a list 42 | */ 43 | 44 | void 45 | _attach(THING **list, THING *item) 46 | { 47 | if (*list != NULL) 48 | { 49 | item->l_next = *list; 50 | (*list)->l_prev = item; 51 | item->l_prev = NULL; 52 | } 53 | else 54 | { 55 | item->l_next = NULL; 56 | item->l_prev = NULL; 57 | } 58 | *list = item; 59 | } 60 | 61 | /* 62 | * _free_list: 63 | * Throw the whole blamed thing away 64 | */ 65 | 66 | void 67 | _free_list(THING **ptr) 68 | { 69 | THING *item; 70 | 71 | while (*ptr != NULL) 72 | { 73 | item = *ptr; 74 | *ptr = next(item); 75 | discard(item); 76 | } 77 | } 78 | 79 | /* 80 | * discard: 81 | * Free up an item 82 | */ 83 | 84 | void 85 | discard(THING *item) 86 | { 87 | #ifdef MASTER 88 | total--; 89 | #endif 90 | free((char *) item); 91 | } 92 | 93 | /* 94 | * new_item 95 | * Get a new item with a specified size 96 | */ 97 | THING * 98 | new_item() 99 | { 100 | THING *item; 101 | 102 | #ifdef MASTER 103 | if ((item = calloc(1, sizeof *item)) == NULL) 104 | msg("ran out of memory after %d items", total); 105 | else 106 | total++; 107 | #else 108 | item = calloc(1, sizeof *item); 109 | #endif 110 | item->l_next = NULL; 111 | item->l_prev = NULL; 112 | return item; 113 | } 114 | -------------------------------------------------------------------------------- /mach_dep.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Various installation dependent routines 3 | * 4 | * @(#)mach_dep.c 4.37 (Berkeley) 05/23/83 5 | * 6 | * Rogue: Exploring the Dungeons of Doom 7 | * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman 8 | * All rights reserved. 9 | * 10 | * See the file LICENSE.TXT for full copyright and licensing information. 11 | */ 12 | 13 | /* 14 | * The various tuneable defines are: 15 | * 16 | * SCOREFILE Where/if the score file should live. 17 | * ALLSCORES Score file is top ten scores, not top ten 18 | * players. This is only useful when only a few 19 | * people will be playing; otherwise the score file 20 | * gets hogged by just a few people. 21 | * NUMSCORES Number of scores in the score file (default 10). 22 | * NUMNAME String version of NUMSCORES (first character 23 | * should be capitalized) (default "Ten"). 24 | * MAXLOAD What (if any) the maximum load average should be 25 | * when people are playing. Since it is divided 26 | * by 10, to specify a load limit of 4.0, MAXLOAD 27 | * should be "40". If defined, then 28 | * LOADAV Should it use it's own routine to get 29 | * the load average? 30 | * NAMELIST If so, where does the system namelist 31 | * hide? 32 | * MAXUSERS What (if any) the maximum user count should be 33 | * when people are playing. If defined, then 34 | * UCOUNT Should it use it's own routine to count 35 | * users? 36 | * UTMP If so, where does the user list hide? 37 | * CHECKTIME How often/if it should check during the game 38 | * for high load average. 39 | */ 40 | 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include "extern.h" 51 | 52 | #define NOOP(x) (x += 0) 53 | 54 | # ifndef NUMSCORES 55 | # define NUMSCORES 10 56 | # define NUMNAME "Ten" 57 | # endif 58 | 59 | unsigned int numscores = NUMSCORES; 60 | char *Numname = NUMNAME; 61 | 62 | # ifdef ALLSCORES 63 | bool allscore = TRUE; 64 | # else /* ALLSCORES */ 65 | bool allscore = FALSE; 66 | # endif /* ALLSCORES */ 67 | 68 | #ifdef CHECKTIME 69 | static int num_checks; /* times we've gone over in checkout() */ 70 | #endif /* CHECKTIME */ 71 | 72 | /* 73 | * init_check: 74 | * Check out too see if it is proper to play the game now 75 | */ 76 | 77 | void 78 | init_check() 79 | { 80 | #if defined(MAXLOAD) || defined(MAXUSERS) 81 | if (too_much()) 82 | { 83 | printf("Sorry, %s, but the system is too loaded now.\n", whoami); 84 | printf("Try again later. Meanwhile, why not enjoy a%s %s?\n", 85 | vowelstr(fruit), fruit); 86 | if (author()) 87 | printf("However, since you're a good guy, it's up to you\n"); 88 | else 89 | exit(1); 90 | } 91 | #endif 92 | } 93 | 94 | /* 95 | * open_score: 96 | * Open up the score file for future use 97 | */ 98 | 99 | void 100 | open_score() 101 | { 102 | #ifdef SCOREFILE 103 | char *scorefile = SCOREFILE; 104 | /* 105 | * We drop setgid privileges after opening the score file, so subsequent 106 | * open()'s will fail. Just reuse the earlier filehandle. 107 | */ 108 | 109 | if (scoreboard != NULL) { 110 | rewind(scoreboard); 111 | return; 112 | } 113 | 114 | scoreboard = fopen(scorefile, "r+"); 115 | 116 | if ((scoreboard == NULL) && (errno == ENOENT)) 117 | { 118 | scoreboard = fopen(scorefile, "w+"); 119 | md_chmod(scorefile,0664); 120 | } 121 | 122 | if (scoreboard == NULL) { 123 | fprintf(stderr, "Could not open %s for writing: %s\n", scorefile, strerror(errno)); 124 | fflush(stderr); 125 | } 126 | #else 127 | scoreboard = NULL; 128 | #endif 129 | } 130 | 131 | /* 132 | * setup: 133 | * Get starting setup for all games 134 | */ 135 | 136 | void 137 | setup() 138 | { 139 | #ifdef CHECKTIME 140 | int checkout(); 141 | #endif 142 | 143 | #ifdef DUMP 144 | md_onsignal_autosave(); 145 | #else 146 | md_onsignal_default(); 147 | #endif 148 | 149 | #ifdef CHECKTIME 150 | md_start_checkout_timer(CHECKTIME*60); 151 | num_checks = 0; 152 | #endif 153 | 154 | raw(); /* Raw mode */ 155 | noecho(); /* Echo off */ 156 | keypad(stdscr,1); 157 | getltchars(); /* get the local tty chars */ 158 | } 159 | 160 | /* 161 | * getltchars: 162 | * Get the local tty chars for later use 163 | */ 164 | 165 | void 166 | getltchars() 167 | { 168 | got_ltc = TRUE; 169 | orig_dsusp = md_dsuspchar(); 170 | md_setdsuspchar( md_suspchar() ); 171 | } 172 | 173 | /* 174 | * resetltchars: 175 | * Reset the local tty chars to original values. 176 | */ 177 | void 178 | resetltchars(void) 179 | { 180 | if (got_ltc) { 181 | md_setdsuspchar(orig_dsusp); 182 | } 183 | } 184 | 185 | /* 186 | * playltchars: 187 | * Set local tty chars to the values we use when playing. 188 | */ 189 | void 190 | playltchars(void) 191 | { 192 | if (got_ltc) { 193 | md_setdsuspchar( md_suspchar() ); 194 | } 195 | } 196 | 197 | /* 198 | * start_score: 199 | * Start the scoring sequence 200 | */ 201 | 202 | void 203 | start_score() 204 | { 205 | #ifdef CHECKTIME 206 | md_stop_checkout_timer(); 207 | #endif 208 | } 209 | 210 | /* 211 | * is_symlink: 212 | * See if the file has a symbolic link 213 | */ 214 | bool 215 | is_symlink(char *sp) 216 | { 217 | #ifdef S_IFLNK 218 | struct stat sbuf2; 219 | 220 | if (lstat(sp, &sbuf2) < 0) 221 | return FALSE; 222 | else 223 | return ((sbuf2.st_mode & S_IFMT) != S_IFREG); 224 | #else 225 | NOOP(sp); 226 | return FALSE; 227 | #endif 228 | } 229 | 230 | #if defined(MAXLOAD) || defined(MAXUSERS) 231 | /* 232 | * too_much: 233 | * See if the system is being used too much for this game 234 | */ 235 | bool 236 | too_much() 237 | { 238 | #ifdef MAXLOAD 239 | double avec[3]; 240 | #else 241 | int cnt; 242 | #endif 243 | 244 | #ifdef MAXLOAD 245 | md_loadav(avec); 246 | if (avec[1] > (MAXLOAD / 10.0)) 247 | return TRUE; 248 | #endif 249 | #ifdef MAXUSERS 250 | if (ucount() > MAXUSERS) 251 | return TRUE; 252 | #endif 253 | return FALSE; 254 | } 255 | 256 | /* 257 | * author: 258 | * See if a user is an author of the program 259 | */ 260 | bool 261 | author() 262 | { 263 | #ifdef MASTER 264 | if (wizard) 265 | return TRUE; 266 | #endif 267 | switch (md_getuid()) 268 | { 269 | case -1: 270 | return TRUE; 271 | default: 272 | return FALSE; 273 | } 274 | } 275 | #endif 276 | 277 | #ifdef CHECKTIME 278 | /* 279 | * checkout: 280 | * Check each CHECKTIME seconds to see if the load is too high 281 | */ 282 | 283 | checkout(int sig) 284 | { 285 | static char *msgs[] = { 286 | "The load is too high to be playing. Please leave in %0.1f minutes", 287 | "Please save your game. You have %0.1f minutes", 288 | "Last warning. You have %0.1f minutes to leave", 289 | }; 290 | int checktime; 291 | 292 | if (too_much()) 293 | { 294 | if (author()) 295 | { 296 | num_checks = 1; 297 | chmsg("The load is rather high, O exaulted one"); 298 | } 299 | else if (num_checks++ == 3) 300 | fatal("Sorry. You took too long. You are dead\n"); 301 | checktime = (CHECKTIME * 60) / num_checks; 302 | chmsg(msgs[num_checks - 1], ((double) checktime / 60.0)); 303 | } 304 | else 305 | { 306 | if (num_checks) 307 | { 308 | num_checks = 0; 309 | chmsg("The load has dropped back down. You have a reprieve"); 310 | } 311 | checktime = (CHECKTIME * 60); 312 | } 313 | 314 | md_start_checkout_timer(checktime); 315 | } 316 | 317 | /* 318 | * chmsg: 319 | * checkout()'s version of msg. If we are in the middle of a 320 | * shell, do a printf instead of a msg to a the refresh. 321 | */ 322 | /* VARARGS1 */ 323 | 324 | chmsg(char *fmt, int arg) 325 | { 326 | if (!in_shell) 327 | msg(fmt, arg); 328 | else 329 | { 330 | printf(fmt, arg); 331 | putchar('\n'); 332 | fflush(stdout); 333 | } 334 | } 335 | #endif 336 | 337 | #ifdef UCOUNT 338 | /* 339 | * ucount: 340 | * count number of users on the system 341 | */ 342 | #include 343 | 344 | struct utmp buf; 345 | 346 | int 347 | ucount() 348 | { 349 | struct utmp *up; 350 | FILE *utmp; 351 | int count; 352 | 353 | if ((utmp = fopen(UTMP, "r")) == NULL) 354 | return 0; 355 | 356 | up = &buf; 357 | count = 0; 358 | 359 | while (fread(up, 1, sizeof (*up), utmp) > 0) 360 | if (buf.ut_name[0] != '\0') 361 | count++; 362 | fclose(utmp); 363 | return count; 364 | } 365 | #endif 366 | 367 | /* 368 | * lock_sc: 369 | * lock the score file. If it takes too long, ask the user if 370 | * they care to wait. Return TRUE if the lock is successful. 371 | */ 372 | static FILE *lfd = NULL; 373 | bool 374 | lock_sc() 375 | { 376 | #if defined(SCOREFILE) && defined(LOCKFILE) 377 | int cnt; 378 | static struct stat sbuf; 379 | char *lockfile = LOCKFILE; 380 | 381 | over: 382 | if ((lfd=fopen(lockfile, "w+")) != NULL) 383 | return TRUE; 384 | for (cnt = 0; cnt < 5; cnt++) 385 | { 386 | md_sleep(1); 387 | if ((lfd=fopen(lockfile, "w+")) != NULL) 388 | return TRUE; 389 | } 390 | if (stat(lockfile, &sbuf) < 0) 391 | { 392 | lfd=fopen(lockfile, "w+"); 393 | return TRUE; 394 | } 395 | if (time(NULL) - sbuf.st_mtime > 10) 396 | { 397 | if (md_unlink(lockfile) < 0) 398 | return FALSE; 399 | goto over; 400 | } 401 | else 402 | { 403 | printf("The score file is very busy. Do you want to wait longer\n"); 404 | printf("for it to become free so your score can get posted?\n"); 405 | printf("If so, type \"y\"\n"); 406 | (void) fgets(prbuf, MAXSTR, stdin); 407 | if (prbuf[0] == 'y') 408 | for (;;) 409 | { 410 | if ((lfd=fopen(lockfile, "w+")) != 0) 411 | return TRUE; 412 | if (stat(lockfile, &sbuf) < 0) 413 | { 414 | lfd=fopen(lockfile, "w+"); 415 | return TRUE; 416 | } 417 | if (time(NULL) - sbuf.st_mtime > 10) 418 | { 419 | if (md_unlink(lockfile) < 0) 420 | return FALSE; 421 | } 422 | md_sleep(1); 423 | } 424 | else 425 | return FALSE; 426 | } 427 | #else 428 | return TRUE; 429 | #endif 430 | } 431 | 432 | /* 433 | * unlock_sc: 434 | * Unlock the score file 435 | */ 436 | 437 | void 438 | unlock_sc() 439 | { 440 | #if defined(SCOREFILE) && defined(LOCKFILE) 441 | if (lfd != NULL) 442 | fclose(lfd); 443 | lfd = NULL; 444 | md_unlink(LOCKFILE); 445 | #endif 446 | } 447 | 448 | /* 449 | * flush_type: 450 | * Flush typeahead for traps, etc. 451 | */ 452 | 453 | void 454 | flush_type() 455 | { 456 | flushinp(); 457 | } 458 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Rogue: Exploring the Dungeons of Doom 3 | * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman 4 | * All rights reserved. 5 | * 6 | * See the file LICENSE.TXT for full copyright and licensing information. 7 | * 8 | * @(#)main.c 4.22 (Berkeley) 02/05/99 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include "rogue.h" 17 | 18 | /* 19 | * main: 20 | * The main program, of course 21 | */ 22 | int 23 | main(int argc, char **argv, char **envp) 24 | { 25 | char *env; 26 | int lowtime; 27 | 28 | md_init(); 29 | 30 | #ifdef MASTER 31 | /* 32 | * Check to see if he is a wizard 33 | */ 34 | if (argc >= 2 && argv[1][0] == '\0') 35 | if (strcmp(PASSWD, md_crypt(md_getpass("wizard's password: "), "mT")) == 0) 36 | { 37 | wizard = TRUE; 38 | player.t_flags |= SEEMONST; 39 | argv++; 40 | argc--; 41 | } 42 | 43 | #endif 44 | 45 | /* 46 | * get home and options from environment 47 | */ 48 | 49 | strncpy(home, md_gethomedir(), MAXSTR); 50 | 51 | strcpy(file_name, home); 52 | strcat(file_name, "rogue.save"); 53 | 54 | if ((env = getenv("ROGUEOPTS")) != NULL) 55 | parse_opts(env); 56 | if (env == NULL || whoami[0] == '\0') 57 | strucpy(whoami, md_getusername(), (int) strlen(md_getusername())); 58 | lowtime = (int) time(NULL); 59 | #ifdef MASTER 60 | if (wizard && getenv("SEED") != NULL) 61 | dnum = atoi(getenv("SEED")); 62 | else 63 | #endif 64 | dnum = lowtime + md_getpid(); 65 | seed = dnum; 66 | 67 | open_score(); 68 | 69 | /* 70 | * Drop setuid/setgid after opening the scoreboard file. 71 | */ 72 | 73 | md_normaluser(); 74 | 75 | /* 76 | * check for print-score option 77 | */ 78 | 79 | md_normaluser(); /* we drop any setgid/setuid priveldges here */ 80 | 81 | if (argc == 2) 82 | { 83 | if (strcmp(argv[1], "-s") == 0) 84 | { 85 | noscore = TRUE; 86 | score(0, -1, 0); 87 | exit(0); 88 | } 89 | else if (strcmp(argv[1], "-d") == 0) 90 | { 91 | dnum = rnd(100); /* throw away some rnd()s to break patterns */ 92 | while (--dnum) 93 | rnd(100); 94 | purse = rnd(100) + 1; 95 | level = rnd(100) + 1; 96 | initscr(); 97 | getltchars(); 98 | death(death_monst()); 99 | exit(0); 100 | } 101 | } 102 | 103 | init_check(); /* check for legal startup */ 104 | if (argc == 2) 105 | if (!restore(argv[1], envp)) /* Note: restore will never return */ 106 | my_exit(1); 107 | #ifdef MASTER 108 | if (wizard) 109 | printf("Hello %s, welcome to dungeon #%d", whoami, dnum); 110 | else 111 | #endif 112 | printf("Hello %s, just a moment while I dig the dungeon...", whoami); 113 | fflush(stdout); 114 | 115 | initscr(); /* Start up cursor package */ 116 | init_probs(); /* Set up prob tables for objects */ 117 | init_player(); /* Set up initial player stats */ 118 | init_names(); /* Set up names of scrolls */ 119 | init_colors(); /* Set up colors of potions */ 120 | init_stones(); /* Set up stone settings of rings */ 121 | init_materials(); /* Set up materials of wands */ 122 | setup(); 123 | 124 | /* 125 | * The screen must be at least NUMLINES x NUMCOLS 126 | */ 127 | if (LINES < NUMLINES || COLS < NUMCOLS) 128 | { 129 | printf("\nSorry, the screen must be at least %dx%d\n", NUMLINES, NUMCOLS); 130 | endwin(); 131 | my_exit(1); 132 | } 133 | 134 | /* 135 | * Set up windows 136 | */ 137 | hw = newwin(LINES, COLS, 0, 0); 138 | idlok(stdscr, TRUE); 139 | idlok(hw, TRUE); 140 | #ifdef MASTER 141 | noscore = wizard; 142 | #endif 143 | new_level(); /* Draw current level */ 144 | /* 145 | * Start up daemons and fuses 146 | */ 147 | start_daemon(runners, 0, AFTER); 148 | start_daemon(doctor, 0, AFTER); 149 | fuse(swander, 0, WANDERTIME, AFTER); 150 | start_daemon(stomach, 0, AFTER); 151 | playit(); 152 | return(0); 153 | } 154 | 155 | /* 156 | * endit: 157 | * Exit the program abnormally. 158 | */ 159 | 160 | void 161 | endit(int sig) 162 | { 163 | NOOP(sig); 164 | fatal("Okay, bye bye!\n"); 165 | } 166 | 167 | /* 168 | * fatal: 169 | * Exit the program, printing a message. 170 | */ 171 | 172 | void 173 | fatal(char *s) 174 | { 175 | mvaddstr(LINES - 2, 0, s); 176 | refresh(); 177 | endwin(); 178 | my_exit(0); 179 | } 180 | 181 | /* 182 | * rnd: 183 | * Pick a very random number. 184 | */ 185 | int 186 | rnd(int range) 187 | { 188 | return range == 0 ? 0 : abs((int) RN) % range; 189 | } 190 | 191 | /* 192 | * roll: 193 | * Roll a number of dice 194 | */ 195 | int 196 | roll(int number, int sides) 197 | { 198 | int dtotal = 0; 199 | 200 | while (number--) 201 | dtotal += rnd(sides)+1; 202 | return dtotal; 203 | } 204 | 205 | /* 206 | * tstp: 207 | * Handle stop and start signals 208 | */ 209 | 210 | void 211 | tstp(int ignored) 212 | { 213 | int y, x; 214 | int oy, ox; 215 | 216 | NOOP(ignored); 217 | 218 | /* 219 | * leave nicely 220 | */ 221 | getyx(curscr, oy, ox); 222 | mvcur(0, COLS - 1, LINES - 1, 0); 223 | endwin(); 224 | resetltchars(); 225 | fflush(stdout); 226 | md_tstpsignal(); 227 | 228 | /* 229 | * start back up again 230 | */ 231 | md_tstpresume(); 232 | raw(); 233 | noecho(); 234 | keypad(stdscr,1); 235 | playltchars(); 236 | clearok(curscr, TRUE); 237 | wrefresh(curscr); 238 | getyx(curscr, y, x); 239 | mvcur(y, x, oy, ox); 240 | fflush(stdout); 241 | curscr->_cury = oy; 242 | curscr->_curx = ox; 243 | } 244 | 245 | /* 246 | * playit: 247 | * The main loop of the program. Loop until the game is over, 248 | * refreshing things and looking at the proper times. 249 | */ 250 | 251 | void 252 | playit() 253 | { 254 | char *opts; 255 | 256 | /* 257 | * set up defaults for slow terminals 258 | */ 259 | 260 | if (baudrate() <= 1200) 261 | { 262 | terse = TRUE; 263 | jump = TRUE; 264 | see_floor = FALSE; 265 | } 266 | 267 | if (md_hasclreol()) 268 | inv_type = INV_CLEAR; 269 | 270 | /* 271 | * parse environment declaration of options 272 | */ 273 | if ((opts = getenv("ROGUEOPTS")) != NULL) 274 | parse_opts(opts); 275 | 276 | 277 | oldpos = hero; 278 | oldrp = roomin(&hero); 279 | while (playing) 280 | command(); /* Command execution */ 281 | endit(0); 282 | } 283 | 284 | /* 285 | * quit: 286 | * Have player make certain, then exit. 287 | */ 288 | 289 | void 290 | quit(int sig) 291 | { 292 | int oy, ox; 293 | 294 | NOOP(sig); 295 | 296 | /* 297 | * Reset the signal in case we got here via an interrupt 298 | */ 299 | if (!q_comm) 300 | mpos = 0; 301 | getyx(curscr, oy, ox); 302 | msg("really quit?"); 303 | if (readchar() == 'y') 304 | { 305 | signal(SIGINT, leave); 306 | clear(); 307 | mvprintw(LINES - 2, 0, "You quit with %d gold pieces", purse); 308 | move(LINES - 1, 0); 309 | refresh(); 310 | score(purse, 1, 0); 311 | my_exit(0); 312 | } 313 | else 314 | { 315 | move(0, 0); 316 | clrtoeol(); 317 | status(); 318 | move(oy, ox); 319 | refresh(); 320 | mpos = 0; 321 | count = 0; 322 | to_death = FALSE; 323 | } 324 | } 325 | 326 | /* 327 | * leave: 328 | * Leave quickly, but curteously 329 | */ 330 | 331 | void 332 | leave(int sig) 333 | { 334 | static char buf[BUFSIZ]; 335 | 336 | NOOP(sig); 337 | 338 | setbuf(stdout, buf); /* throw away pending output */ 339 | 340 | if (!isendwin()) 341 | { 342 | mvcur(0, COLS - 1, LINES - 1, 0); 343 | endwin(); 344 | } 345 | 346 | putchar('\n'); 347 | my_exit(0); 348 | } 349 | 350 | /* 351 | * shell: 352 | * Let them escape for a while 353 | */ 354 | 355 | void 356 | shell() 357 | { 358 | /* 359 | * Set the terminal back to original mode 360 | */ 361 | move(LINES-1, 0); 362 | refresh(); 363 | endwin(); 364 | resetltchars(); 365 | putchar('\n'); 366 | in_shell = TRUE; 367 | after = FALSE; 368 | fflush(stdout); 369 | /* 370 | * Fork and do a shell 371 | */ 372 | md_shellescape(); 373 | 374 | printf("\n[Press return to continue]"); 375 | fflush(stdout); 376 | noecho(); 377 | raw(); 378 | keypad(stdscr,1); 379 | playltchars(); 380 | in_shell = FALSE; 381 | wait_for('\n'); 382 | clearok(stdscr, TRUE); 383 | } 384 | 385 | /* 386 | * my_exit: 387 | * Leave the process properly 388 | */ 389 | 390 | void 391 | my_exit(int st) 392 | { 393 | resetltchars(); 394 | exit(st); 395 | } 396 | 397 | -------------------------------------------------------------------------------- /monsters.c: -------------------------------------------------------------------------------- 1 | /* 2 | * File with various monster functions in it 3 | * 4 | * @(#)monsters.c 4.46 (Berkeley) 02/05/99 5 | * 6 | * Rogue: Exploring the Dungeons of Doom 7 | * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman 8 | * All rights reserved. 9 | * 10 | * See the file LICENSE.TXT for full copyright and licensing information. 11 | */ 12 | 13 | #include 14 | #include 15 | #include "rogue.h" 16 | #include 17 | 18 | /* 19 | * List of monsters in rough order of vorpalness 20 | */ 21 | static char lvl_mons[] = { 22 | 'K', 'E', 'B', 'S', 'H', 'I', 'R', 'O', 'Z', 'L', 'C', 'Q', 'A', 23 | 'N', 'Y', 'F', 'T', 'W', 'P', 'X', 'U', 'M', 'V', 'G', 'J', 'D' 24 | }; 25 | 26 | static char wand_mons[] = { 27 | 'K', 'E', 'B', 'S', 'H', 0, 'R', 'O', 'Z', 0, 'C', 'Q', 'A', 28 | 0, 'Y', 0, 'T', 'W', 'P', 0, 'U', 'M', 'V', 'G', 'J', 0 29 | }; 30 | 31 | /* 32 | * randmonster: 33 | * Pick a monster to show up. The lower the level, 34 | * the meaner the monster. 35 | */ 36 | char 37 | randmonster(bool wander) 38 | { 39 | int d; 40 | char *mons; 41 | 42 | mons = (wander ? wand_mons : lvl_mons); 43 | do 44 | { 45 | d = level + (rnd(10) - 6); 46 | if (d < 0) 47 | d = rnd(5); 48 | if (d > 25) 49 | d = rnd(5) + 21; 50 | } while (mons[d] == 0); 51 | return mons[d]; 52 | } 53 | 54 | /* 55 | * new_monster: 56 | * Pick a new monster and add it to the list 57 | */ 58 | 59 | void 60 | new_monster(THING *tp, char type, coord *cp) 61 | { 62 | struct monster *mp; 63 | int lev_add; 64 | 65 | if ((lev_add = level - AMULETLEVEL) < 0) 66 | lev_add = 0; 67 | attach(mlist, tp); 68 | tp->t_type = type; 69 | tp->t_disguise = type; 70 | tp->t_pos = *cp; 71 | move(cp->y, cp->x); 72 | tp->t_oldch = CCHAR( inch() ); 73 | tp->t_room = roomin(cp); 74 | moat(cp->y, cp->x) = tp; 75 | mp = &monsters[tp->t_type-'A']; 76 | tp->t_stats.s_lvl = mp->m_stats.s_lvl + lev_add; 77 | tp->t_stats.s_maxhp = tp->t_stats.s_hpt = roll(tp->t_stats.s_lvl, 8); 78 | tp->t_stats.s_arm = mp->m_stats.s_arm - lev_add; 79 | strcpy(tp->t_stats.s_dmg,mp->m_stats.s_dmg); 80 | tp->t_stats.s_str = mp->m_stats.s_str; 81 | tp->t_stats.s_exp = mp->m_stats.s_exp + lev_add * 10 + exp_add(tp); 82 | tp->t_flags = mp->m_flags; 83 | if (level > 29) 84 | tp->t_flags |= ISHASTE; 85 | tp->t_turn = TRUE; 86 | tp->t_pack = NULL; 87 | if (ISWEARING(R_AGGR)) 88 | runto(cp); 89 | if (type == 'X') 90 | tp->t_disguise = rnd_thing(); 91 | } 92 | 93 | /* 94 | * expadd: 95 | * Experience to add for this monster's level/hit points 96 | */ 97 | int 98 | exp_add(THING *tp) 99 | { 100 | int mod; 101 | 102 | if (tp->t_stats.s_lvl == 1) 103 | mod = tp->t_stats.s_maxhp / 8; 104 | else 105 | mod = tp->t_stats.s_maxhp / 6; 106 | if (tp->t_stats.s_lvl > 9) 107 | mod *= 20; 108 | else if (tp->t_stats.s_lvl > 6) 109 | mod *= 4; 110 | return mod; 111 | } 112 | 113 | /* 114 | * wanderer: 115 | * Create a new wandering monster and aim it at the player 116 | */ 117 | 118 | void 119 | wanderer() 120 | { 121 | THING *tp; 122 | static coord cp; 123 | 124 | tp = new_item(); 125 | do 126 | { 127 | find_floor((struct room *) NULL, &cp, FALSE, TRUE); 128 | } while (roomin(&cp) == proom); 129 | new_monster(tp, randmonster(TRUE), &cp); 130 | if (on(player, SEEMONST)) 131 | { 132 | standout(); 133 | if (!on(player, ISHALU)) 134 | addch(tp->t_type); 135 | else 136 | addch(rnd(26) + 'A'); 137 | standend(); 138 | } 139 | runto(&tp->t_pos); 140 | #ifdef MASTER 141 | if (wizard) 142 | msg("started a wandering %s", monsters[tp->t_type-'A'].m_name); 143 | #endif 144 | } 145 | 146 | /* 147 | * wake_monster: 148 | * What to do when the hero steps next to a monster 149 | */ 150 | THING * 151 | wake_monster(int y, int x) 152 | { 153 | THING *tp; 154 | struct room *rp; 155 | char ch, *mname; 156 | 157 | #ifdef MASTER 158 | if ((tp = moat(y, x)) == NULL) 159 | msg("can't find monster in wake_monster"); 160 | #else 161 | tp = moat(y, x); 162 | if (tp == NULL) 163 | endwin(), abort(); 164 | #endif 165 | ch = tp->t_type; 166 | /* 167 | * Every time he sees mean monster, it might start chasing him 168 | */ 169 | if (!on(*tp, ISRUN) && rnd(3) != 0 && on(*tp, ISMEAN) && !on(*tp, ISHELD) 170 | && !ISWEARING(R_STEALTH) && !on(player, ISLEVIT)) 171 | { 172 | tp->t_dest = &hero; 173 | tp->t_flags |= ISRUN; 174 | } 175 | if (ch == 'M' && !on(player, ISBLIND) && !on(player, ISHALU) 176 | && !on(*tp, ISFOUND) && !on(*tp, ISCANC) && on(*tp, ISRUN)) 177 | { 178 | rp = proom; 179 | if ((rp != NULL && !(rp->r_flags & ISDARK)) 180 | || dist(y, x, hero.y, hero.x) < LAMPDIST) 181 | { 182 | tp->t_flags |= ISFOUND; 183 | if (!save(VS_MAGIC)) 184 | { 185 | if (on(player, ISHUH)) 186 | lengthen(unconfuse, spread(HUHDURATION)); 187 | else 188 | fuse(unconfuse, 0, spread(HUHDURATION), AFTER); 189 | player.t_flags |= ISHUH; 190 | mname = set_mname(tp); 191 | addmsg("%s", mname); 192 | if (strcmp(mname, "it") != 0) 193 | addmsg("'"); 194 | msg("s gaze has confused you"); 195 | } 196 | } 197 | } 198 | /* 199 | * Let greedy ones guard gold 200 | */ 201 | if (on(*tp, ISGREED) && !on(*tp, ISRUN)) 202 | { 203 | tp->t_flags |= ISRUN; 204 | if (proom->r_goldval) 205 | tp->t_dest = &proom->r_gold; 206 | else 207 | tp->t_dest = &hero; 208 | } 209 | return tp; 210 | } 211 | 212 | /* 213 | * give_pack: 214 | * Give a pack to a monster if it deserves one 215 | */ 216 | 217 | void 218 | give_pack(THING *tp) 219 | { 220 | if (level >= max_level && rnd(100) < monsters[tp->t_type-'A'].m_carry) 221 | attach(tp->t_pack, new_thing()); 222 | } 223 | 224 | /* 225 | * save_throw: 226 | * See if a creature save against something 227 | */ 228 | int 229 | save_throw(int which, THING *tp) 230 | { 231 | int need; 232 | 233 | need = 14 + which - tp->t_stats.s_lvl / 2; 234 | return (roll(1, 20) >= need); 235 | } 236 | 237 | /* 238 | * save: 239 | * See if he saves against various nasty things 240 | */ 241 | int 242 | save(int which) 243 | { 244 | if (which == VS_MAGIC) 245 | { 246 | if (ISRING(LEFT, R_PROTECT)) 247 | which -= cur_ring[LEFT]->o_arm; 248 | if (ISRING(RIGHT, R_PROTECT)) 249 | which -= cur_ring[RIGHT]->o_arm; 250 | } 251 | return save_throw(which, &player); 252 | } 253 | -------------------------------------------------------------------------------- /move.c: -------------------------------------------------------------------------------- 1 | /* 2 | * hero movement commands 3 | * 4 | * @(#)move.c 4.49 (Berkeley) 02/05/99 5 | * 6 | * Rogue: Exploring the Dungeons of Doom 7 | * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman 8 | * All rights reserved. 9 | * 10 | * See the file LICENSE.TXT for full copyright and licensing information. 11 | */ 12 | 13 | #include 14 | #include 15 | #include "rogue.h" 16 | 17 | /* 18 | * used to hold the new hero position 19 | */ 20 | 21 | coord nh; 22 | 23 | /* 24 | * do_run: 25 | * Start the hero running 26 | */ 27 | 28 | void 29 | do_run(char ch) 30 | { 31 | running = TRUE; 32 | after = FALSE; 33 | runch = ch; 34 | } 35 | 36 | /* 37 | * do_move: 38 | * Check to see that a move is legal. If it is handle the 39 | * consequences (fighting, picking up, etc.) 40 | */ 41 | 42 | void 43 | do_move(int dy, int dx) 44 | { 45 | char ch, fl; 46 | 47 | firstmove = FALSE; 48 | if (no_move) 49 | { 50 | no_move--; 51 | msg("you are still stuck in the bear trap"); 52 | return; 53 | } 54 | /* 55 | * Do a confused move (maybe) 56 | */ 57 | if (on(player, ISHUH) && rnd(5) != 0) 58 | { 59 | nh = *rndmove(&player); 60 | if (ce(nh, hero)) 61 | { 62 | after = FALSE; 63 | running = FALSE; 64 | to_death = FALSE; 65 | return; 66 | } 67 | } 68 | else 69 | { 70 | over: 71 | nh.y = hero.y + dy; 72 | nh.x = hero.x + dx; 73 | } 74 | 75 | /* 76 | * Check if he tried to move off the screen or make an illegal 77 | * diagonal move, and stop him if he did. 78 | */ 79 | if (nh.x < 0 || nh.x >= NUMCOLS || nh.y <= 0 || nh.y >= NUMLINES - 1) 80 | goto hit_bound; 81 | if (!diag_ok(&hero, &nh)) 82 | { 83 | after = FALSE; 84 | running = FALSE; 85 | return; 86 | } 87 | if (running && ce(hero, nh)) 88 | after = running = FALSE; 89 | fl = flat(nh.y, nh.x); 90 | ch = winat(nh.y, nh.x); 91 | if (!(fl & F_REAL) && ch == FLOOR) 92 | { 93 | if (!on(player, ISLEVIT)) 94 | { 95 | chat(nh.y, nh.x) = ch = TRAP; 96 | flat(nh.y, nh.x) |= F_REAL; 97 | } 98 | } 99 | else if (on(player, ISHELD) && ch != 'F') 100 | { 101 | msg("you are being held"); 102 | return; 103 | } 104 | switch (ch) 105 | { 106 | case ' ': 107 | case '|': 108 | case '-': 109 | hit_bound: 110 | if (passgo && running && (proom->r_flags & ISGONE) 111 | && !on(player, ISBLIND)) 112 | { 113 | bool b1, b2; 114 | 115 | switch (runch) 116 | { 117 | case 'h': 118 | case 'l': 119 | b1 = (bool)(hero.y != 1 && turn_ok(hero.y - 1, hero.x)); 120 | b2 = (bool)(hero.y != NUMLINES - 2 && turn_ok(hero.y + 1, hero.x)); 121 | if (!(b1 ^ b2)) 122 | break; 123 | if (b1) 124 | { 125 | runch = 'k'; 126 | dy = -1; 127 | } 128 | else 129 | { 130 | runch = 'j'; 131 | dy = 1; 132 | } 133 | dx = 0; 134 | turnref(); 135 | goto over; 136 | case 'j': 137 | case 'k': 138 | b1 = (bool)(hero.x != 0 && turn_ok(hero.y, hero.x - 1)); 139 | b2 = (bool)(hero.x != NUMCOLS - 1 && turn_ok(hero.y, hero.x + 1)); 140 | if (!(b1 ^ b2)) 141 | break; 142 | if (b1) 143 | { 144 | runch = 'h'; 145 | dx = -1; 146 | } 147 | else 148 | { 149 | runch = 'l'; 150 | dx = 1; 151 | } 152 | dy = 0; 153 | turnref(); 154 | goto over; 155 | } 156 | } 157 | running = FALSE; 158 | after = FALSE; 159 | break; 160 | case DOOR: 161 | running = FALSE; 162 | if (flat(hero.y, hero.x) & F_PASS) 163 | enter_room(&nh); 164 | goto move_stuff; 165 | case TRAP: 166 | ch = be_trapped(&nh); 167 | if (ch == T_DOOR || ch == T_TELEP) 168 | return; 169 | goto move_stuff; 170 | case PASSAGE: 171 | /* 172 | * when you're in a corridor, you don't know if you're in 173 | * a maze room or not, and there ain't no way to find out 174 | * if you're leaving a maze room, so it is necessary to 175 | * always recalculate proom. 176 | */ 177 | proom = roomin(&hero); 178 | goto move_stuff; 179 | case FLOOR: 180 | if (!(fl & F_REAL)) 181 | be_trapped(&hero); 182 | goto move_stuff; 183 | case STAIRS: 184 | seenstairs = TRUE; 185 | /* FALLTHROUGH */ 186 | default: 187 | running = FALSE; 188 | if (isupper(ch) || moat(nh.y, nh.x)) 189 | fight(&nh, cur_weapon, FALSE); 190 | else 191 | { 192 | if (ch != STAIRS) 193 | take = ch; 194 | move_stuff: 195 | mvaddch(hero.y, hero.x, floor_at()); 196 | if ((fl & F_PASS) && chat(oldpos.y, oldpos.x) == DOOR) 197 | leave_room(&nh); 198 | hero = nh; 199 | } 200 | } 201 | } 202 | 203 | /* 204 | * turn_ok: 205 | * Decide whether it is legal to turn onto the given space 206 | */ 207 | bool 208 | turn_ok(int y, int x) 209 | { 210 | PLACE *pp; 211 | 212 | pp = INDEX(y, x); 213 | return (pp->p_ch == DOOR 214 | || (pp->p_flags & (F_REAL|F_PASS)) == (F_REAL|F_PASS)); 215 | } 216 | 217 | /* 218 | * turnref: 219 | * Decide whether to refresh at a passage turning or not 220 | */ 221 | 222 | void 223 | turnref() 224 | { 225 | PLACE *pp; 226 | 227 | pp = INDEX(hero.y, hero.x); 228 | if (!(pp->p_flags & F_SEEN)) 229 | { 230 | if (jump) 231 | { 232 | leaveok(stdscr, TRUE); 233 | refresh(); 234 | leaveok(stdscr, FALSE); 235 | } 236 | pp->p_flags |= F_SEEN; 237 | } 238 | } 239 | 240 | /* 241 | * door_open: 242 | * Called to illuminate a room. If it is dark, remove anything 243 | * that might move. 244 | */ 245 | 246 | void 247 | door_open(struct room *rp) 248 | { 249 | int y, x; 250 | 251 | if (!(rp->r_flags & ISGONE)) 252 | for (y = rp->r_pos.y; y < rp->r_pos.y + rp->r_max.y; y++) 253 | for (x = rp->r_pos.x; x < rp->r_pos.x + rp->r_max.x; x++) 254 | if (isupper(winat(y, x))) 255 | wake_monster(y, x); 256 | } 257 | 258 | /* 259 | * be_trapped: 260 | * The guy stepped on a trap.... Make him pay. 261 | */ 262 | char 263 | be_trapped(coord *tc) 264 | { 265 | PLACE *pp; 266 | THING *arrow; 267 | char tr; 268 | 269 | if (on(player, ISLEVIT)) 270 | return T_RUST; /* anything that's not a door or teleport */ 271 | running = FALSE; 272 | count = FALSE; 273 | pp = INDEX(tc->y, tc->x); 274 | pp->p_ch = TRAP; 275 | tr = pp->p_flags & F_TMASK; 276 | pp->p_flags |= F_SEEN; 277 | switch (tr) 278 | { 279 | case T_DOOR: 280 | level++; 281 | new_level(); 282 | msg("you fell into a trap!"); 283 | when T_BEAR: 284 | no_move += BEARTIME; 285 | msg("you are caught in a bear trap"); 286 | when T_MYST: 287 | switch(rnd(11)) 288 | { 289 | case 0: msg("you are suddenly in a parallel dimension"); 290 | when 1: msg("the light in here suddenly seems %s", rainbow[rnd(cNCOLORS)]); 291 | when 2: msg("you feel a sting in the side of your neck"); 292 | when 3: msg("multi-colored lines swirl around you, then fade"); 293 | when 4: msg("a %s light flashes in your eyes", rainbow[rnd(cNCOLORS)]); 294 | when 5: msg("a spike shoots past your ear!"); 295 | when 6: msg("%s sparks dance across your armor", rainbow[rnd(cNCOLORS)]); 296 | when 7: msg("you suddenly feel very thirsty"); 297 | when 8: msg("you feel time speed up suddenly"); 298 | when 9: msg("time now seems to be going slower"); 299 | when 10: msg("you pack turns %s!", rainbow[rnd(cNCOLORS)]); 300 | } 301 | when T_SLEEP: 302 | no_command += SLEEPTIME; 303 | player.t_flags &= ~ISRUN; 304 | msg("a strange white mist envelops you and you fall asleep"); 305 | when T_ARROW: 306 | if (swing(pstats.s_lvl - 1, pstats.s_arm, 1)) 307 | { 308 | pstats.s_hpt -= roll(1, 6); 309 | if (pstats.s_hpt <= 0) 310 | { 311 | msg("an arrow killed you"); 312 | death('a'); 313 | } 314 | else 315 | msg("oh no! An arrow shot you"); 316 | } 317 | else 318 | { 319 | arrow = new_item(); 320 | init_weapon(arrow, ARROW); 321 | arrow->o_count = 1; 322 | arrow->o_pos = hero; 323 | fall(arrow, FALSE); 324 | msg("an arrow shoots past you"); 325 | } 326 | when T_TELEP: 327 | /* 328 | * since the hero's leaving, look() won't put a TRAP 329 | * down for us, so we have to do it ourself 330 | */ 331 | teleport(); 332 | mvaddch(tc->y, tc->x, TRAP); 333 | when T_DART: 334 | if (!swing(pstats.s_lvl+1, pstats.s_arm, 1)) 335 | msg("a small dart whizzes by your ear and vanishes"); 336 | else 337 | { 338 | pstats.s_hpt -= roll(1, 4); 339 | if (pstats.s_hpt <= 0) 340 | { 341 | msg("a poisoned dart killed you"); 342 | death('d'); 343 | } 344 | if (!ISWEARING(R_SUSTSTR) && !save(VS_POISON)) 345 | chg_str(-1); 346 | msg("a small dart just hit you in the shoulder"); 347 | } 348 | when T_RUST: 349 | msg("a gush of water hits you on the head"); 350 | rust_armor(cur_armor); 351 | } 352 | flush_type(); 353 | return tr; 354 | } 355 | 356 | /* 357 | * rndmove: 358 | * Move in a random direction if the monster/person is confused 359 | */ 360 | coord * 361 | rndmove(THING *who) 362 | { 363 | THING *obj; 364 | int x, y; 365 | char ch; 366 | static coord ret; /* what we will be returning */ 367 | 368 | y = ret.y = who->t_pos.y + rnd(3) - 1; 369 | x = ret.x = who->t_pos.x + rnd(3) - 1; 370 | /* 371 | * Now check to see if that's a legal move. If not, don't move. 372 | * (I.e., bump into the wall or whatever) 373 | */ 374 | if (y == who->t_pos.y && x == who->t_pos.x) 375 | return &ret; 376 | if (!diag_ok(&who->t_pos, &ret)) 377 | goto bad; 378 | else 379 | { 380 | ch = winat(y, x); 381 | if (!step_ok(ch)) 382 | goto bad; 383 | if (ch == SCROLL) 384 | { 385 | for (obj = lvl_obj; obj != NULL; obj = next(obj)) 386 | if (y == obj->o_pos.y && x == obj->o_pos.x) 387 | break; 388 | if (obj != NULL && obj->o_which == S_SCARE) 389 | goto bad; 390 | } 391 | } 392 | return &ret; 393 | 394 | bad: 395 | ret = who->t_pos; 396 | return &ret; 397 | } 398 | 399 | /* 400 | * rust_armor: 401 | * Rust the given armor, if it is a legal kind to rust, and we 402 | * aren't wearing a magic ring. 403 | */ 404 | 405 | void 406 | rust_armor(THING *arm) 407 | { 408 | if (arm == NULL || arm->o_type != ARMOR || arm->o_which == LEATHER || 409 | arm->o_arm >= 9) 410 | return; 411 | 412 | if ((arm->o_flags & ISPROT) || ISWEARING(R_SUSTARM)) 413 | { 414 | if (!to_death) 415 | msg("the rust vanishes instantly"); 416 | } 417 | else 418 | { 419 | arm->o_arm++; 420 | if (!terse) 421 | msg("your armor appears to be weaker now. Oh my!"); 422 | else 423 | msg("your armor weakens"); 424 | } 425 | } 426 | -------------------------------------------------------------------------------- /new_level.c: -------------------------------------------------------------------------------- 1 | /* 2 | * new_level: 3 | * Dig and draw a new level 4 | * 5 | * @(#)new_level.c 4.38 (Berkeley) 02/05/99 6 | * 7 | * Rogue: Exploring the Dungeons of Doom 8 | * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman 9 | * All rights reserved. 10 | * 11 | * See the file LICENSE.TXT for full copyright and licensing information. 12 | */ 13 | 14 | #include 15 | #include 16 | #include "rogue.h" 17 | 18 | #define TREAS_ROOM 20 /* one chance in TREAS_ROOM for a treasure room */ 19 | #define MAXTREAS 10 /* maximum number of treasures in a treasure room */ 20 | #define MINTREAS 2 /* minimum number of treasures in a treasure room */ 21 | 22 | void 23 | new_level() 24 | { 25 | THING *tp; 26 | PLACE *pp; 27 | char *sp; 28 | int i; 29 | 30 | player.t_flags &= ~ISHELD; /* unhold when you go down just in case */ 31 | if (level > max_level) 32 | max_level = level; 33 | /* 34 | * Clean things off from last level 35 | */ 36 | for (pp = places; pp < &places[MAXCOLS*MAXLINES]; pp++) 37 | { 38 | pp->p_ch = ' '; 39 | pp->p_flags = F_REAL; 40 | pp->p_monst = NULL; 41 | } 42 | clear(); 43 | /* 44 | * Free up the monsters on the last level 45 | */ 46 | for (tp = mlist; tp != NULL; tp = next(tp)) 47 | free_list(tp->t_pack); 48 | free_list(mlist); 49 | /* 50 | * Throw away stuff left on the previous level (if anything) 51 | */ 52 | free_list(lvl_obj); 53 | do_rooms(); /* Draw rooms */ 54 | do_passages(); /* Draw passages */ 55 | no_food++; 56 | put_things(); /* Place objects (if any) */ 57 | /* 58 | * Place the traps 59 | */ 60 | if (rnd(10) < level) 61 | { 62 | ntraps = rnd(level / 4) + 1; 63 | if (ntraps > MAXTRAPS) 64 | ntraps = MAXTRAPS; 65 | i = ntraps; 66 | while (i--) 67 | { 68 | /* 69 | * not only wouldn't it be NICE to have traps in mazes 70 | * (not that we care about being nice), since the trap 71 | * number is stored where the passage number is, we 72 | * can't actually do it. 73 | */ 74 | do 75 | { 76 | find_floor((struct room *) NULL, &stairs, FALSE, FALSE); 77 | } while (chat(stairs.y, stairs.x) != FLOOR); 78 | sp = &flat(stairs.y, stairs.x); 79 | *sp &= ~F_REAL; 80 | *sp |= rnd(NTRAPS); 81 | } 82 | } 83 | /* 84 | * Place the staircase down. 85 | */ 86 | find_floor((struct room *) NULL, &stairs, FALSE, FALSE); 87 | chat(stairs.y, stairs.x) = STAIRS; 88 | seenstairs = FALSE; 89 | 90 | for (tp = mlist; tp != NULL; tp = next(tp)) 91 | tp->t_room = roomin(&tp->t_pos); 92 | 93 | find_floor((struct room *) NULL, &hero, FALSE, TRUE); 94 | enter_room(&hero); 95 | mvaddch(hero.y, hero.x, PLAYER); 96 | if (on(player, SEEMONST)) 97 | turn_see(FALSE); 98 | if (on(player, ISHALU)) 99 | visuals(); 100 | } 101 | 102 | /* 103 | * rnd_room: 104 | * Pick a room that is really there 105 | */ 106 | int 107 | rnd_room() 108 | { 109 | int rm; 110 | 111 | do 112 | { 113 | rm = rnd(MAXROOMS); 114 | } while (rooms[rm].r_flags & ISGONE); 115 | return rm; 116 | } 117 | 118 | /* 119 | * put_things: 120 | * Put potions and scrolls on this level 121 | */ 122 | 123 | void 124 | put_things() 125 | { 126 | int i; 127 | THING *obj; 128 | 129 | /* 130 | * Once you have found the amulet, the only way to get new stuff is 131 | * go down into the dungeon. 132 | */ 133 | if (amulet && level < max_level) 134 | return; 135 | /* 136 | * check for treasure rooms, and if so, put it in. 137 | */ 138 | if (rnd(TREAS_ROOM) == 0) 139 | treas_room(); 140 | /* 141 | * Do MAXOBJ attempts to put things on a level 142 | */ 143 | for (i = 0; i < MAXOBJ; i++) 144 | if (rnd(100) < 36) 145 | { 146 | /* 147 | * Pick a new object and link it in the list 148 | */ 149 | obj = new_thing(); 150 | attach(lvl_obj, obj); 151 | /* 152 | * Put it somewhere 153 | */ 154 | find_floor((struct room *) NULL, &obj->o_pos, FALSE, FALSE); 155 | chat(obj->o_pos.y, obj->o_pos.x) = (char) obj->o_type; 156 | } 157 | /* 158 | * If he is really deep in the dungeon and he hasn't found the 159 | * amulet yet, put it somewhere on the ground 160 | */ 161 | if (level >= AMULETLEVEL && !amulet) 162 | { 163 | obj = new_item(); 164 | attach(lvl_obj, obj); 165 | obj->o_hplus = 0; 166 | obj->o_dplus = 0; 167 | strncpy(obj->o_damage,"0x0",sizeof(obj->o_damage)); 168 | strncpy(obj->o_hurldmg,"0x0",sizeof(obj->o_hurldmg)); 169 | obj->o_arm = 11; 170 | obj->o_type = AMULET; 171 | /* 172 | * Put it somewhere 173 | */ 174 | find_floor((struct room *) NULL, &obj->o_pos, FALSE, FALSE); 175 | chat(obj->o_pos.y, obj->o_pos.x) = AMULET; 176 | } 177 | } 178 | 179 | /* 180 | * treas_room: 181 | * Add a treasure room 182 | */ 183 | #define MAXTRIES 10 /* max number of tries to put down a monster */ 184 | 185 | 186 | void 187 | treas_room() 188 | { 189 | int nm; 190 | THING *tp; 191 | struct room *rp; 192 | int spots, num_monst; 193 | static coord mp; 194 | 195 | rp = &rooms[rnd_room()]; 196 | spots = (rp->r_max.y - 2) * (rp->r_max.x - 2) - MINTREAS; 197 | if (spots > (MAXTREAS - MINTREAS)) 198 | spots = (MAXTREAS - MINTREAS); 199 | num_monst = nm = rnd(spots) + MINTREAS; 200 | while (nm--) 201 | { 202 | find_floor(rp, &mp, 2 * MAXTRIES, FALSE); 203 | tp = new_thing(); 204 | tp->o_pos = mp; 205 | attach(lvl_obj, tp); 206 | chat(mp.y, mp.x) = (char) tp->o_type; 207 | } 208 | 209 | /* 210 | * fill up room with monsters from the next level down 211 | */ 212 | 213 | if ((nm = rnd(spots) + MINTREAS) < num_monst + 2) 214 | nm = num_monst + 2; 215 | spots = (rp->r_max.y - 2) * (rp->r_max.x - 2); 216 | if (nm > spots) 217 | nm = spots; 218 | level++; 219 | while (nm--) 220 | { 221 | spots = 0; 222 | if (find_floor(rp, &mp, MAXTRIES, TRUE)) 223 | { 224 | tp = new_item(); 225 | new_monster(tp, randmonster(FALSE), &mp); 226 | tp->t_flags |= ISMEAN; /* no sloughers in THIS room */ 227 | give_pack(tp); 228 | } 229 | } 230 | level--; 231 | } 232 | -------------------------------------------------------------------------------- /passages.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Draw the connecting passages 3 | * 4 | * @(#)passages.c 4.22 (Berkeley) 02/05/99 5 | * 6 | * Rogue: Exploring the Dungeons of Doom 7 | * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman 8 | * All rights reserved. 9 | * 10 | * See the file LICENSE.TXT for full copyright and licensing information. 11 | */ 12 | 13 | #include 14 | #include 15 | #include "rogue.h" 16 | 17 | /* 18 | * do_passages: 19 | * Draw all the passages on a level. 20 | */ 21 | 22 | void 23 | do_passages() 24 | { 25 | struct rdes *r1, *r2 = NULL; 26 | int i, j; 27 | int roomcount; 28 | static struct rdes 29 | { 30 | bool conn[MAXROOMS]; /* possible to connect to room i? */ 31 | bool isconn[MAXROOMS]; /* connection been made to room i? */ 32 | bool ingraph; /* this room in graph already? */ 33 | } rdes[MAXROOMS] = { 34 | { { 0, 1, 0, 1, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, 35 | { { 1, 0, 1, 0, 1, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, 36 | { { 0, 1, 0, 0, 0, 1, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, 37 | { { 1, 0, 0, 0, 1, 0, 1, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, 38 | { { 0, 1, 0, 1, 0, 1, 0, 1, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, 39 | { { 0, 0, 1, 0, 1, 0, 0, 0, 1 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, 40 | { { 0, 0, 0, 1, 0, 0, 0, 1, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, 41 | { { 0, 0, 0, 0, 1, 0, 1, 0, 1 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, 42 | { { 0, 0, 0, 0, 0, 1, 0, 1, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 }, 43 | }; 44 | 45 | /* 46 | * reinitialize room graph description 47 | */ 48 | for (r1 = rdes; r1 <= &rdes[MAXROOMS-1]; r1++) 49 | { 50 | for (j = 0; j < MAXROOMS; j++) 51 | r1->isconn[j] = FALSE; 52 | r1->ingraph = FALSE; 53 | } 54 | 55 | /* 56 | * starting with one room, connect it to a random adjacent room and 57 | * then pick a new room to start with. 58 | */ 59 | roomcount = 1; 60 | r1 = &rdes[rnd(MAXROOMS)]; 61 | r1->ingraph = TRUE; 62 | do 63 | { 64 | /* 65 | * find a room to connect with 66 | */ 67 | j = 0; 68 | for (i = 0; i < MAXROOMS; i++) 69 | if (r1->conn[i] && !rdes[i].ingraph && rnd(++j) == 0) 70 | r2 = &rdes[i]; 71 | /* 72 | * if no adjacent rooms are outside the graph, pick a new room 73 | * to look from 74 | */ 75 | if (j == 0) 76 | { 77 | do 78 | r1 = &rdes[rnd(MAXROOMS)]; 79 | until (r1->ingraph); 80 | } 81 | /* 82 | * otherwise, connect new room to the graph, and draw a tunnel 83 | * to it 84 | */ 85 | else 86 | { 87 | r2->ingraph = TRUE; 88 | i = (int)(r1 - rdes); 89 | j = (int)(r2 - rdes); 90 | conn(i, j); 91 | r1->isconn[j] = TRUE; 92 | r2->isconn[i] = TRUE; 93 | roomcount++; 94 | } 95 | } while (roomcount < MAXROOMS); 96 | 97 | /* 98 | * attempt to add passages to the graph a random number of times so 99 | * that there isn't always just one unique passage through it. 100 | */ 101 | for (roomcount = rnd(5); roomcount > 0; roomcount--) 102 | { 103 | r1 = &rdes[rnd(MAXROOMS)]; /* a random room to look from */ 104 | /* 105 | * find an adjacent room not already connected 106 | */ 107 | j = 0; 108 | for (i = 0; i < MAXROOMS; i++) 109 | if (r1->conn[i] && !r1->isconn[i] && rnd(++j) == 0) 110 | r2 = &rdes[i]; 111 | /* 112 | * if there is one, connect it and look for the next added 113 | * passage 114 | */ 115 | if (j != 0) 116 | { 117 | i = (int)(r1 - rdes); 118 | j = (int)(r2 - rdes); 119 | conn(i, j); 120 | r1->isconn[j] = TRUE; 121 | r2->isconn[i] = TRUE; 122 | } 123 | } 124 | passnum(); 125 | } 126 | 127 | /* 128 | * conn: 129 | * Draw a corridor from a room in a certain direction. 130 | */ 131 | 132 | void 133 | conn(int r1, int r2) 134 | { 135 | struct room *rpf, *rpt = NULL; 136 | int rmt; 137 | int distance = 0, turn_spot, turn_distance = 0; 138 | int rm; 139 | char direc; 140 | static coord del, curr, turn_delta, spos, epos; 141 | 142 | if (r1 < r2) 143 | { 144 | rm = r1; 145 | if (r1 + 1 == r2) 146 | direc = 'r'; 147 | else 148 | direc = 'd'; 149 | } 150 | else 151 | { 152 | rm = r2; 153 | if (r2 + 1 == r1) 154 | direc = 'r'; 155 | else 156 | direc = 'd'; 157 | } 158 | rpf = &rooms[rm]; 159 | /* 160 | * Set up the movement variables, in two cases: 161 | * first drawing one down. 162 | */ 163 | if (direc == 'd') 164 | { 165 | rmt = rm + 3; /* room # of dest */ 166 | rpt = &rooms[rmt]; /* room pointer of dest */ 167 | del.x = 0; /* direction of move */ 168 | del.y = 1; 169 | spos.x = rpf->r_pos.x; /* start of move */ 170 | spos.y = rpf->r_pos.y; 171 | epos.x = rpt->r_pos.x; /* end of move */ 172 | epos.y = rpt->r_pos.y; 173 | if (!(rpf->r_flags & ISGONE)) /* if not gone pick door pos */ 174 | do 175 | { 176 | spos.x = rpf->r_pos.x + rnd(rpf->r_max.x - 2) + 1; 177 | spos.y = rpf->r_pos.y + rpf->r_max.y - 1; 178 | } while ((rpf->r_flags&ISMAZE) && !(flat(spos.y, spos.x)&F_PASS)); 179 | if (!(rpt->r_flags & ISGONE)) 180 | do 181 | { 182 | epos.x = rpt->r_pos.x + rnd(rpt->r_max.x - 2) + 1; 183 | } while ((rpt->r_flags&ISMAZE) && !(flat(epos.y, epos.x)&F_PASS)); 184 | distance = abs(spos.y - epos.y) - 1; /* distance to move */ 185 | turn_delta.y = 0; /* direction to turn */ 186 | turn_delta.x = (spos.x < epos.x ? 1 : -1); 187 | turn_distance = abs(spos.x - epos.x); /* how far to turn */ 188 | } 189 | else if (direc == 'r') /* setup for moving right */ 190 | { 191 | rmt = rm + 1; 192 | rpt = &rooms[rmt]; 193 | del.x = 1; 194 | del.y = 0; 195 | spos.x = rpf->r_pos.x; 196 | spos.y = rpf->r_pos.y; 197 | epos.x = rpt->r_pos.x; 198 | epos.y = rpt->r_pos.y; 199 | if (!(rpf->r_flags & ISGONE)) 200 | do 201 | { 202 | spos.x = rpf->r_pos.x + rpf->r_max.x - 1; 203 | spos.y = rpf->r_pos.y + rnd(rpf->r_max.y - 2) + 1; 204 | } while ((rpf->r_flags&ISMAZE) && !(flat(spos.y, spos.x)&F_PASS)); 205 | if (!(rpt->r_flags & ISGONE)) 206 | do 207 | { 208 | epos.y = rpt->r_pos.y + rnd(rpt->r_max.y - 2) + 1; 209 | } while ((rpt->r_flags&ISMAZE) && !(flat(epos.y, epos.x)&F_PASS)); 210 | distance = abs(spos.x - epos.x) - 1; 211 | turn_delta.y = (spos.y < epos.y ? 1 : -1); 212 | turn_delta.x = 0; 213 | turn_distance = abs(spos.y - epos.y); 214 | } 215 | #ifdef MASTER 216 | else 217 | debug("error in connection tables"); 218 | #endif 219 | 220 | turn_spot = rnd(distance - 1) + 1; /* where turn starts */ 221 | 222 | /* 223 | * Draw in the doors on either side of the passage or just put #'s 224 | * if the rooms are gone. 225 | */ 226 | if (!(rpf->r_flags & ISGONE)) 227 | door(rpf, &spos); 228 | else 229 | putpass(&spos); 230 | if (!(rpt->r_flags & ISGONE)) 231 | door(rpt, &epos); 232 | else 233 | putpass(&epos); 234 | /* 235 | * Get ready to move... 236 | */ 237 | curr.x = spos.x; 238 | curr.y = spos.y; 239 | while (distance > 0) 240 | { 241 | /* 242 | * Move to new position 243 | */ 244 | curr.x += del.x; 245 | curr.y += del.y; 246 | /* 247 | * Check if we are at the turn place, if so do the turn 248 | */ 249 | if (distance == turn_spot) 250 | while (turn_distance--) 251 | { 252 | putpass(&curr); 253 | curr.x += turn_delta.x; 254 | curr.y += turn_delta.y; 255 | } 256 | /* 257 | * Continue digging along 258 | */ 259 | putpass(&curr); 260 | distance--; 261 | } 262 | curr.x += del.x; 263 | curr.y += del.y; 264 | if (!ce(curr, epos)) 265 | msg("warning, connectivity problem on this level"); 266 | } 267 | 268 | /* 269 | * putpass: 270 | * add a passage character or secret passage here 271 | */ 272 | 273 | void 274 | putpass(coord *cp) 275 | { 276 | PLACE *pp; 277 | 278 | pp = INDEX(cp->y, cp->x); 279 | pp->p_flags |= F_PASS; 280 | if (rnd(10) + 1 < level && rnd(40) == 0) 281 | pp->p_flags &= ~F_REAL; 282 | else 283 | pp->p_ch = PASSAGE; 284 | } 285 | 286 | /* 287 | * door: 288 | * Add a door or possibly a secret door. Also enters the door in 289 | * the exits array of the room. 290 | */ 291 | 292 | void 293 | door(struct room *rm, coord *cp) 294 | { 295 | PLACE *pp; 296 | 297 | rm->r_exit[rm->r_nexits++] = *cp; 298 | 299 | if (rm->r_flags & ISMAZE) 300 | return; 301 | 302 | pp = INDEX(cp->y, cp->x); 303 | if (rnd(10) + 1 < level && rnd(5) == 0) 304 | { 305 | if (cp->y == rm->r_pos.y || cp->y == rm->r_pos.y + rm->r_max.y - 1) 306 | pp->p_ch = '-'; 307 | else 308 | pp->p_ch = '|'; 309 | pp->p_flags &= ~F_REAL; 310 | } 311 | else 312 | pp->p_ch = DOOR; 313 | } 314 | 315 | #ifdef MASTER 316 | /* 317 | * add_pass: 318 | * Add the passages to the current window (wizard command) 319 | */ 320 | 321 | void 322 | add_pass() 323 | { 324 | PLACE *pp; 325 | int y, x; 326 | char ch; 327 | 328 | for (y = 1; y < NUMLINES - 1; y++) 329 | for (x = 0; x < NUMCOLS; x++) 330 | { 331 | pp = INDEX(y, x); 332 | if ((pp->p_flags & F_PASS) || pp->p_ch == DOOR || 333 | (!(pp->p_flags&F_REAL) && (pp->p_ch == '|' || pp->p_ch == '-'))) 334 | { 335 | ch = pp->p_ch; 336 | if (pp->p_flags & F_PASS) 337 | ch = PASSAGE; 338 | pp->p_flags |= F_SEEN; 339 | move(y, x); 340 | if (pp->p_monst != NULL) 341 | pp->p_monst->t_oldch = pp->p_ch; 342 | else if (pp->p_flags & F_REAL) 343 | addch(ch); 344 | else 345 | { 346 | standout(); 347 | addch((pp->p_flags & F_PASS) ? PASSAGE : DOOR); 348 | standend(); 349 | } 350 | } 351 | } 352 | } 353 | #endif 354 | 355 | /* 356 | * passnum: 357 | * Assign a number to each passageway 358 | */ 359 | static int pnum; 360 | static bool newpnum; 361 | 362 | 363 | void 364 | passnum() 365 | { 366 | struct room *rp; 367 | int i; 368 | 369 | pnum = 0; 370 | newpnum = FALSE; 371 | for (rp = passages; rp < &passages[MAXPASS]; rp++) 372 | rp->r_nexits = 0; 373 | for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) 374 | for (i = 0; i < rp->r_nexits; i++) 375 | { 376 | newpnum++; 377 | numpass(rp->r_exit[i].y, rp->r_exit[i].x); 378 | } 379 | } 380 | 381 | /* 382 | * numpass: 383 | * Number a passageway square and its brethren 384 | */ 385 | 386 | void 387 | numpass(int y, int x) 388 | { 389 | char *fp; 390 | struct room *rp; 391 | char ch; 392 | 393 | if (x >= NUMCOLS || x < 0 || y >= NUMLINES || y <= 0) 394 | return; 395 | fp = &flat(y, x); 396 | if (*fp & F_PNUM) 397 | return; 398 | if (newpnum) 399 | { 400 | pnum++; 401 | newpnum = FALSE; 402 | } 403 | /* 404 | * check to see if it is a door or secret door, i.e., a new exit, 405 | * or a numerable type of place 406 | */ 407 | if ((ch = chat(y, x)) == DOOR || 408 | (!(*fp & F_REAL) && (ch == '|' || ch == '-'))) 409 | { 410 | rp = &passages[pnum]; 411 | rp->r_exit[rp->r_nexits].y = y; 412 | rp->r_exit[rp->r_nexits++].x = x; 413 | } 414 | else if (!(*fp & F_PASS)) 415 | return; 416 | *fp |= pnum; 417 | /* 418 | * recurse on the surrounding places 419 | */ 420 | numpass(y + 1, x); 421 | numpass(y - 1, x); 422 | numpass(y, x + 1); 423 | numpass(y, x - 1); 424 | } 425 | -------------------------------------------------------------------------------- /potions.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Function(s) for dealing with potions 3 | * 4 | * @(#)potions.c 4.46 (Berkeley) 06/07/83 5 | * 6 | * Rogue: Exploring the Dungeons of Doom 7 | * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman 8 | * All rights reserved. 9 | * 10 | * See the file LICENSE.TXT for full copyright and licensing information. 11 | */ 12 | 13 | #include 14 | #include 15 | #include "rogue.h" 16 | 17 | typedef struct 18 | { 19 | int pa_flags; 20 | void (*pa_daemon)(); 21 | int pa_time; 22 | char *pa_high, *pa_straight; 23 | } PACT; 24 | 25 | static PACT p_actions[] = 26 | { 27 | { ISHUH, unconfuse, HUHDURATION, /* P_CONFUSE */ 28 | "what a tripy feeling!", 29 | "wait, what's going on here. Huh? What? Who?" }, 30 | { ISHALU, come_down, SEEDURATION, /* P_LSD */ 31 | "Oh, wow! Everything seems so cosmic!", 32 | "Oh, wow! Everything seems so cosmic!" }, 33 | { 0, NULL, 0 }, /* P_POISON */ 34 | { 0, NULL, 0 }, /* P_STRENGTH */ 35 | { CANSEE, unsee, SEEDURATION, /* P_SEEINVIS */ 36 | prbuf, 37 | prbuf }, 38 | { 0, NULL, 0 }, /* P_HEALING */ 39 | { 0, NULL, 0 }, /* P_MFIND */ 40 | { 0, NULL, 0 }, /* P_TFIND */ 41 | { 0, NULL, 0 }, /* P_RAISE */ 42 | { 0, NULL, 0 }, /* P_XHEAL */ 43 | { 0, NULL, 0 }, /* P_HASTE */ 44 | { 0, NULL, 0 }, /* P_RESTORE */ 45 | { ISBLIND, sight, SEEDURATION, /* P_BLIND */ 46 | "oh, bummer! Everything is dark! Help!", 47 | "a cloak of darkness falls around you" }, 48 | { ISLEVIT, land, HEALTIME, /* P_LEVIT */ 49 | "oh, wow! You're floating in the air!", 50 | "you start to float in the air" } 51 | }; 52 | 53 | /* 54 | * quaff: 55 | * Quaff a potion from the pack 56 | */ 57 | 58 | void 59 | quaff() 60 | { 61 | THING *obj, *tp, *mp; 62 | bool discardit = FALSE; 63 | bool show, trip; 64 | 65 | obj = get_item("quaff", POTION); 66 | /* 67 | * Make certain that it is somethings that we want to drink 68 | */ 69 | if (obj == NULL) 70 | return; 71 | if (obj->o_type != POTION) 72 | { 73 | if (!terse) 74 | msg("yuk! Why would you want to drink that?"); 75 | else 76 | msg("that's undrinkable"); 77 | return; 78 | } 79 | if (obj == cur_weapon) 80 | cur_weapon = NULL; 81 | 82 | /* 83 | * Calculate the effect it has on the poor guy. 84 | */ 85 | trip = on(player, ISHALU); 86 | discardit = (bool)(obj->o_count == 1); 87 | leave_pack(obj, FALSE, FALSE); 88 | switch (obj->o_which) 89 | { 90 | case P_CONFUSE: 91 | do_pot(P_CONFUSE, !trip); 92 | when P_POISON: 93 | pot_info[P_POISON].oi_know = TRUE; 94 | if (ISWEARING(R_SUSTSTR)) 95 | msg("you feel momentarily sick"); 96 | else 97 | { 98 | chg_str(-(rnd(3) + 1)); 99 | msg("you feel very sick now"); 100 | come_down(); 101 | } 102 | when P_HEALING: 103 | pot_info[P_HEALING].oi_know = TRUE; 104 | if ((pstats.s_hpt += roll(pstats.s_lvl, 4)) > max_hp) 105 | pstats.s_hpt = ++max_hp; 106 | sight(); 107 | msg("you begin to feel better"); 108 | when P_STRENGTH: 109 | pot_info[P_STRENGTH].oi_know = TRUE; 110 | chg_str(1); 111 | msg("you feel stronger, now. What bulging muscles!"); 112 | when P_MFIND: 113 | player.t_flags |= SEEMONST; 114 | fuse((void(*)())turn_see, TRUE, HUHDURATION, AFTER); 115 | if (!turn_see(FALSE)) 116 | msg("you have a %s feeling for a moment, then it passes", 117 | choose_str("normal", "strange")); 118 | when P_TFIND: 119 | /* 120 | * Potion of magic detection. Show the potions and scrolls 121 | */ 122 | show = FALSE; 123 | if (lvl_obj != NULL) 124 | { 125 | wclear(hw); 126 | for (tp = lvl_obj; tp != NULL; tp = next(tp)) 127 | { 128 | if (is_magic(tp)) 129 | { 130 | show = TRUE; 131 | wmove(hw, tp->o_pos.y, tp->o_pos.x); 132 | waddch(hw, MAGIC); 133 | pot_info[P_TFIND].oi_know = TRUE; 134 | } 135 | } 136 | for (mp = mlist; mp != NULL; mp = next(mp)) 137 | { 138 | for (tp = mp->t_pack; tp != NULL; tp = next(tp)) 139 | { 140 | if (is_magic(tp)) 141 | { 142 | show = TRUE; 143 | wmove(hw, mp->t_pos.y, mp->t_pos.x); 144 | waddch(hw, MAGIC); 145 | } 146 | } 147 | } 148 | } 149 | if (show) 150 | { 151 | pot_info[P_TFIND].oi_know = TRUE; 152 | show_win("You sense the presence of magic on this level.--More--"); 153 | } 154 | else 155 | msg("you have a %s feeling for a moment, then it passes", 156 | choose_str("normal", "strange")); 157 | when P_LSD: 158 | if (!trip) 159 | { 160 | if (on(player, SEEMONST)) 161 | turn_see(FALSE); 162 | start_daemon(visuals, 0, BEFORE); 163 | seenstairs = seen_stairs(); 164 | } 165 | do_pot(P_LSD, TRUE); 166 | when P_SEEINVIS: 167 | sprintf(prbuf, "this potion tastes like %s juice", fruit); 168 | show = on(player, CANSEE); 169 | do_pot(P_SEEINVIS, FALSE); 170 | if (!show) 171 | invis_on(); 172 | sight(); 173 | when P_RAISE: 174 | pot_info[P_RAISE].oi_know = TRUE; 175 | msg("you suddenly feel much more skillful"); 176 | raise_level(); 177 | when P_XHEAL: 178 | pot_info[P_XHEAL].oi_know = TRUE; 179 | if ((pstats.s_hpt += roll(pstats.s_lvl, 8)) > max_hp) 180 | { 181 | if (pstats.s_hpt > max_hp + pstats.s_lvl + 1) 182 | ++max_hp; 183 | pstats.s_hpt = ++max_hp; 184 | } 185 | sight(); 186 | come_down(); 187 | msg("you begin to feel much better"); 188 | when P_HASTE: 189 | pot_info[P_HASTE].oi_know = TRUE; 190 | after = FALSE; 191 | if (add_haste(TRUE)) 192 | msg("you feel yourself moving much faster"); 193 | when P_RESTORE: 194 | if (ISRING(LEFT, R_ADDSTR)) 195 | add_str(&pstats.s_str, -cur_ring[LEFT]->o_arm); 196 | if (ISRING(RIGHT, R_ADDSTR)) 197 | add_str(&pstats.s_str, -cur_ring[RIGHT]->o_arm); 198 | if (pstats.s_str < max_stats.s_str) 199 | pstats.s_str = max_stats.s_str; 200 | if (ISRING(LEFT, R_ADDSTR)) 201 | add_str(&pstats.s_str, cur_ring[LEFT]->o_arm); 202 | if (ISRING(RIGHT, R_ADDSTR)) 203 | add_str(&pstats.s_str, cur_ring[RIGHT]->o_arm); 204 | msg("hey, this tastes great. It make you feel warm all over"); 205 | when P_BLIND: 206 | do_pot(P_BLIND, TRUE); 207 | when P_LEVIT: 208 | do_pot(P_LEVIT, TRUE); 209 | #ifdef MASTER 210 | otherwise: 211 | msg("what an odd tasting potion!"); 212 | return; 213 | #endif 214 | } 215 | status(); 216 | /* 217 | * Throw the item away 218 | */ 219 | 220 | call_it(&pot_info[obj->o_which]); 221 | 222 | if (discardit) 223 | discard(obj); 224 | return; 225 | } 226 | 227 | /* 228 | * is_magic: 229 | * Returns true if an object radiates magic 230 | */ 231 | bool 232 | is_magic(THING *obj) 233 | { 234 | switch (obj->o_type) 235 | { 236 | case ARMOR: 237 | return (bool)((obj->o_flags&ISPROT) || obj->o_arm != a_class[obj->o_which]); 238 | case WEAPON: 239 | return (bool)(obj->o_hplus != 0 || obj->o_dplus != 0); 240 | case POTION: 241 | case SCROLL: 242 | case STICK: 243 | case RING: 244 | case AMULET: 245 | return TRUE; 246 | } 247 | return FALSE; 248 | } 249 | 250 | /* 251 | * invis_on: 252 | * Turn on the ability to see invisible 253 | */ 254 | 255 | void 256 | invis_on() 257 | { 258 | THING *mp; 259 | 260 | player.t_flags |= CANSEE; 261 | for (mp = mlist; mp != NULL; mp = next(mp)) 262 | if (on(*mp, ISINVIS) && see_monst(mp) && !on(player, ISHALU)) 263 | mvaddch(mp->t_pos.y, mp->t_pos.x, mp->t_disguise); 264 | } 265 | 266 | /* 267 | * turn_see: 268 | * Put on or off seeing monsters on this level 269 | */ 270 | bool 271 | turn_see(bool turn_off) 272 | { 273 | THING *mp; 274 | bool can_see, add_new; 275 | 276 | add_new = FALSE; 277 | for (mp = mlist; mp != NULL; mp = next(mp)) 278 | { 279 | move(mp->t_pos.y, mp->t_pos.x); 280 | can_see = see_monst(mp); 281 | if (turn_off) 282 | { 283 | if (!can_see) 284 | addch(mp->t_oldch); 285 | } 286 | else 287 | { 288 | if (!can_see) 289 | standout(); 290 | if (!on(player, ISHALU)) 291 | addch(mp->t_type); 292 | else 293 | addch(rnd(26) + 'A'); 294 | if (!can_see) 295 | { 296 | standend(); 297 | add_new++; 298 | } 299 | } 300 | } 301 | if (turn_off) 302 | player.t_flags &= ~SEEMONST; 303 | else 304 | player.t_flags |= SEEMONST; 305 | return add_new; 306 | } 307 | 308 | /* 309 | * seen_stairs: 310 | * Return TRUE if the player has seen the stairs 311 | */ 312 | bool 313 | seen_stairs() 314 | { 315 | THING *tp; 316 | 317 | move(stairs.y, stairs.x); 318 | if (inch() == STAIRS) /* it's on the map */ 319 | return TRUE; 320 | if (ce(hero, stairs)) /* It's under him */ 321 | return TRUE; 322 | 323 | /* 324 | * if a monster is on the stairs, this gets hairy 325 | */ 326 | if ((tp = moat(stairs.y, stairs.x)) != NULL) 327 | { 328 | if (see_monst(tp) && on(*tp, ISRUN)) /* if it's visible and awake */ 329 | return TRUE; /* it must have moved there */ 330 | 331 | if (on(player, SEEMONST) /* if she can detect monster */ 332 | && tp->t_oldch == STAIRS) /* and there once were stairs */ 333 | return TRUE; /* it must have moved there */ 334 | } 335 | return FALSE; 336 | } 337 | 338 | /* 339 | * raise_level: 340 | * The guy just magically went up a level. 341 | */ 342 | 343 | void 344 | raise_level() 345 | { 346 | pstats.s_exp = e_levels[pstats.s_lvl-1] + 1L; 347 | check_level(); 348 | } 349 | 350 | /* 351 | * do_pot: 352 | * Do a potion with standard setup. This means it uses a fuse and 353 | * turns on a flag 354 | */ 355 | 356 | void 357 | do_pot(int type, bool knowit) 358 | { 359 | PACT *pp; 360 | int t; 361 | 362 | pp = &p_actions[type]; 363 | if (!pot_info[type].oi_know) 364 | pot_info[type].oi_know = knowit; 365 | t = spread(pp->pa_time); 366 | if (!on(player, pp->pa_flags)) 367 | { 368 | player.t_flags |= pp->pa_flags; 369 | fuse(pp->pa_daemon, 0, t, AFTER); 370 | look(FALSE); 371 | } 372 | else 373 | lengthen(pp->pa_daemon, t); 374 | msg(choose_str(pp->pa_high, pp->pa_straight)); 375 | } 376 | -------------------------------------------------------------------------------- /rings.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Routines dealing specifically with rings 3 | * 4 | * @(#)rings.c 4.19 (Berkeley) 05/29/83 5 | * 6 | * Rogue: Exploring the Dungeons of Doom 7 | * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman 8 | * All rights reserved. 9 | * 10 | * See the file LICENSE.TXT for full copyright and licensing information. 11 | */ 12 | 13 | #include 14 | #include "rogue.h" 15 | 16 | /* 17 | * ring_on: 18 | * Put a ring on a hand 19 | */ 20 | 21 | void 22 | ring_on() 23 | { 24 | THING *obj; 25 | int ring; 26 | 27 | obj = get_item("put on", RING); 28 | /* 29 | * Make certain that it is somethings that we want to wear 30 | */ 31 | if (obj == NULL) 32 | return; 33 | if (obj->o_type != RING) 34 | { 35 | if (!terse) 36 | msg("it would be difficult to wrap that around a finger"); 37 | else 38 | msg("not a ring"); 39 | return; 40 | } 41 | 42 | /* 43 | * find out which hand to put it on 44 | */ 45 | if (is_current(obj)) 46 | return; 47 | 48 | if (cur_ring[LEFT] == NULL && cur_ring[RIGHT] == NULL) 49 | { 50 | if ((ring = gethand()) < 0) 51 | return; 52 | } 53 | else if (cur_ring[LEFT] == NULL) 54 | ring = LEFT; 55 | else if (cur_ring[RIGHT] == NULL) 56 | ring = RIGHT; 57 | else 58 | { 59 | if (!terse) 60 | msg("you already have a ring on each hand"); 61 | else 62 | msg("wearing two"); 63 | return; 64 | } 65 | cur_ring[ring] = obj; 66 | 67 | /* 68 | * Calculate the effect it has on the poor guy. 69 | */ 70 | switch (obj->o_which) 71 | { 72 | case R_ADDSTR: 73 | chg_str(obj->o_arm); 74 | break; 75 | case R_SEEINVIS: 76 | invis_on(); 77 | break; 78 | case R_AGGR: 79 | aggravate(); 80 | break; 81 | } 82 | 83 | if (!terse) 84 | addmsg("you are now wearing "); 85 | msg("%s (%c)", inv_name(obj, TRUE), obj->o_packch); 86 | } 87 | 88 | /* 89 | * ring_off: 90 | * take off a ring 91 | */ 92 | 93 | void 94 | ring_off() 95 | { 96 | int ring; 97 | THING *obj; 98 | 99 | if (cur_ring[LEFT] == NULL && cur_ring[RIGHT] == NULL) 100 | { 101 | if (terse) 102 | msg("no rings"); 103 | else 104 | msg("you aren't wearing any rings"); 105 | return; 106 | } 107 | else if (cur_ring[LEFT] == NULL) 108 | ring = RIGHT; 109 | else if (cur_ring[RIGHT] == NULL) 110 | ring = LEFT; 111 | else 112 | if ((ring = gethand()) < 0) 113 | return; 114 | mpos = 0; 115 | obj = cur_ring[ring]; 116 | if (obj == NULL) 117 | { 118 | msg("not wearing such a ring"); 119 | return; 120 | } 121 | if (dropcheck(obj)) 122 | msg("was wearing %s(%c)", inv_name(obj, TRUE), obj->o_packch); 123 | } 124 | 125 | /* 126 | * gethand: 127 | * Which hand is the hero interested in? 128 | */ 129 | int 130 | gethand() 131 | { 132 | int c; 133 | 134 | for (;;) 135 | { 136 | if (terse) 137 | msg("left or right ring? "); 138 | else 139 | msg("left hand or right hand? "); 140 | if ((c = readchar()) == ESCAPE) 141 | return -1; 142 | mpos = 0; 143 | if (c == 'l' || c == 'L') 144 | return LEFT; 145 | else if (c == 'r' || c == 'R') 146 | return RIGHT; 147 | if (terse) 148 | msg("L or R"); 149 | else 150 | msg("please type L or R"); 151 | } 152 | } 153 | 154 | /* 155 | * ring_eat: 156 | * How much food does this ring use up? 157 | */ 158 | int 159 | ring_eat(int hand) 160 | { 161 | THING *ring; 162 | int eat; 163 | static int uses[] = { 164 | 1, /* R_PROTECT */ 1, /* R_ADDSTR */ 165 | 1, /* R_SUSTSTR */ -3, /* R_SEARCH */ 166 | -5, /* R_SEEINVIS */ 0, /* R_NOP */ 167 | 0, /* R_AGGR */ -3, /* R_ADDHIT */ 168 | -3, /* R_ADDDAM */ 2, /* R_REGEN */ 169 | -2, /* R_DIGEST */ 0, /* R_TELEPORT */ 170 | 1, /* R_STEALTH */ 1 /* R_SUSTARM */ 171 | }; 172 | 173 | if ((ring = cur_ring[hand]) == NULL) 174 | return 0; 175 | if ((eat = uses[ring->o_which]) < 0) 176 | eat = (rnd(-eat) == 0); 177 | if (ring->o_which == R_DIGEST) 178 | eat = -eat; 179 | return eat; 180 | } 181 | 182 | /* 183 | * ring_num: 184 | * Print ring bonuses 185 | */ 186 | char * 187 | ring_num(THING *obj) 188 | { 189 | static char buf[10]; 190 | 191 | if (!(obj->o_flags & ISKNOW)) 192 | return ""; 193 | switch (obj->o_which) 194 | { 195 | case R_PROTECT: 196 | case R_ADDSTR: 197 | case R_ADDDAM: 198 | case R_ADDHIT: 199 | sprintf(buf, " [%s]", num(obj->o_arm, 0, RING)); 200 | otherwise: 201 | return ""; 202 | } 203 | return buf; 204 | } 205 | -------------------------------------------------------------------------------- /rogue.6.in: -------------------------------------------------------------------------------- 1 | .\" 2 | .\" @(#)rogue.6 6.2 (Berkeley) 5/6/86 3 | .\" 4 | .\" Rogue: Exploring the Dungeons of Doom 5 | .\" Copyright (C) 1980-1983, 1985, 1986 Michael Toy, Ken Arnold and Glenn Wichman 6 | .\" All rights reserved. 7 | .\" 8 | .\" See the file LICENSE.TXT for full copyright and licensing information. 9 | .\" 10 | .TH ROGUE 6 "May 6, 1986" 11 | .UC 4 12 | .SH NAME 13 | rogue \- Exploring The Dungeons of Doom 14 | .SH SYNOPSIS 15 | .B @PROGRAM@ 16 | [ 17 | .B \-r 18 | ] 19 | [ 20 | .I save_file 21 | ] 22 | [ 23 | .B \-s 24 | ] 25 | [ 26 | .B \-d 27 | ] 28 | .SH DESCRIPTION 29 | .PP 30 | .I Rogue 31 | is a computer fantasy game with a new twist. It is crt oriented and the 32 | object of the game is to survive the attacks of various monsters and get 33 | a lot of gold, rather than the puzzle solving orientation of most computer 34 | fantasy games. 35 | .PP 36 | To get started you really only need to know two commands. The command 37 | .B ? 38 | will give you a list of the available commands and the command 39 | .B / 40 | will identify the things you see on the screen. 41 | .PP 42 | To win the game (as opposed to merely playing to beat other people's high 43 | scores) you must locate the Amulet of Yendor which is somewhere below 44 | the 20th level of the dungeon and get it out. Nobody has achieved this 45 | yet and if somebody does, they will probably go down in history as a hero 46 | among heroes. 47 | .PP 48 | When the game ends, either by your death, when you quit, or if you (by 49 | some miracle) manage to win, 50 | .I rogue 51 | will give you a list of the top-ten scorers. The scoring is based entirely 52 | upon how much gold you get. There is a 10% penalty for getting yourself 53 | killed. 54 | .PP 55 | If 56 | .I save_file 57 | is specified, 58 | rogue will be restored from the specified saved game file. 59 | If the 60 | .B \-r 61 | option is used, the save game file is presumed to be the default. 62 | .PP 63 | The 64 | .B \-s 65 | option will print out the list of scores. 66 | .PP 67 | The 68 | .B \-d 69 | option will kill you and try to add you to the score file. 70 | .PP 71 | For more detailed directions, read the document 72 | .I "A Guide to the Dungeons of Doom." 73 | .SH AUTHORS 74 | Michael C. Toy, 75 | Kenneth C. R. C. Arnold, 76 | Glenn Wichman 77 | .SH FILES 78 | .DT 79 | .ta \w'@SCOREFILE@\ \ \ 'u 80 | @SCOREFILE@ Score file 81 | .br 82 | \fB~\fP/rogue.save Default save file 83 | .SH SEE ALSO 84 | Michael C. Toy 85 | and 86 | Kenneth C. R. C. Arnold, 87 | .I "A guide to the Dungeons of Doom" 88 | .SH BUGS 89 | .PP 90 | Probably infinite 91 | (although countably infinite). 92 | However, 93 | that Ice Monsters sometimes transfix you permanently is 94 | .I not 95 | a bug. 96 | It's a feature. 97 | -------------------------------------------------------------------------------- /rogue.cat.in: -------------------------------------------------------------------------------- 1 | ROGUE(6) ROGUE(6) 2 | 3 | 4 | 5 | NAME 6 | rogue - Exploring The Dungeons of Doom 7 | 8 | SYNOPSIS 9 | @PROGRAM@ [ -r ] [ save_file ] [ -s ] [ -d ] 10 | 11 | DESCRIPTION 12 | Rogue is a computer fantasy game with a new twist. It is crt oriented 13 | and the object of the game is to survive the attacks of various mon- 14 | sters and get a lot of gold, rather than the puzzle solving orientation 15 | of most computer fantasy games. 16 | 17 | To get started you really only need to know two commands. The command 18 | ? will give you a list of the available commands and the command / 19 | will identify the things you see on the screen. 20 | 21 | To win the game (as opposed to merely playing to beat other people's 22 | high scores) you must locate the Amulet of Yendor which is somewhere 23 | below the 20th level of the dungeon and get it out. Nobody has 24 | achieved this yet and if somebody does, they will probably go down in 25 | history as a hero among heroes. 26 | 27 | When the game ends, either by your death, when you quit, or if you (by 28 | some miracle) manage to win, rogue will give you a list of the top-ten 29 | scorers. The scoring is based entirely upon how much gold you get. 30 | There is a 10% penalty for getting yourself killed. 31 | 32 | If save_file is specified, rogue will be restored from the specified 33 | saved game file. If the -r option is used, the save game file is pre- 34 | sumed to be the default. 35 | 36 | The -s option will print out the list of scores. 37 | 38 | The -d option will kill you and try to add you to the score file. 39 | 40 | For more detailed directions, read the document A Guide to the Dungeons 41 | of Doom. 42 | 43 | AUTHORS 44 | Michael C. Toy, Kenneth C. R. C. Arnold, Glenn Wichman 45 | 46 | FILES 47 | @SCOREFILE@ Score file 48 | ~/rogue.save Default save file 49 | 50 | SEE ALSO 51 | Michael C. Toy and Kenneth C. R. C. Arnold, A guide to the Dungeons of 52 | Doom 53 | 54 | BUGS 55 | Probably infinite (although countably infinite). However, that Ice 56 | Monsters sometimes transfix you permanently is not a bug. It's a fea- 57 | ture. 58 | 59 | 60 | 61 | 4th Berkeley Distribution May 6, 1986 ROGUE(6) 62 | -------------------------------------------------------------------------------- /rogue.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Encoding=UTF-8 3 | Name=Rogue 4 | GenericName=Rogue 5 | Comment=The original curses-based adventure game 6 | Exec=rogue 7 | Icon=rogue.png 8 | Terminal=true 9 | Type=Application 10 | Categories=Game;RolePlaying; 11 | Version=1.0 12 | -------------------------------------------------------------------------------- /rogue.html.in: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Davidslv/rogue/cf9bd26d564a72fac4cf56b55c96c2435270d29a/rogue.html.in -------------------------------------------------------------------------------- /rogue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Davidslv/rogue/cf9bd26d564a72fac4cf56b55c96c2435270d29a/rogue.png -------------------------------------------------------------------------------- /rogue.spec: -------------------------------------------------------------------------------- 1 | Name: rogue 2 | Version: 5.4.4 3 | Release: 1%{?dist} 4 | Summary: The original graphical adventure game 5 | 6 | Group: Amusements/Games 7 | License: BSD 8 | URL: http://rogue.rogueforge.net/ 9 | Source0: http://rogue.rogueforge.net/files/rogue5.4/rogue5.4.4-src.tar.gz 10 | Source1: rogue.desktop 11 | Source2: rogue.png 12 | BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) 13 | 14 | BuildRequires: desktop-file-utils 15 | BuildRequires: ncurses-devel 16 | 17 | %description 18 | The one, the only, the original graphical adventure game that spawned 19 | an entire genre. 20 | 21 | %prep 22 | %setup -q -n %{name}%{version} 23 | 24 | 25 | %build 26 | %configure --enable-setgid=games --enable-scorefile=%{_var}/games/roguelike/rogue54.scr --enable-lockfile=%{_var}/games/roguelike/rogue54.lck 27 | make %{_smp_mflags} 28 | 29 | 30 | %install 31 | rm -rf $RPM_BUILD_ROOT 32 | 33 | make install DESTDIR=$RPM_BUILD_ROOT 34 | 35 | desktop-file-install --vendor fedora \ 36 | --dir ${RPM_BUILD_ROOT}%{_datadir}/applications \ 37 | %{SOURCE1} 38 | mkdir -p $RPM_BUILD_ROOT/%{_datadir}/icons/hicolor/32x32/apps/ 39 | install -p -m 644 %{SOURCE2} $RPM_BUILD_ROOT/%{_datadir}/icons/hicolor/32x32/apps/ 40 | 41 | 42 | %clean 43 | rm -rf $RPM_BUILD_ROOT 44 | 45 | %post 46 | touch --no-create %{_datadir}/icons/hicolor || : 47 | if [ -x %{_bindir}/gtk-update-icon-cache ]; then 48 | %{_bindir}/gtk-update-icon-cache --quiet %{_datadir}/icons/hicolor || : 49 | fi 50 | 51 | %postun 52 | touch --no-create %{_datadir}/icons/hicolor || : 53 | if [ -x %{_bindir}/gtk-update-icon-cache ]; then 54 | %{_bindir}/gtk-update-icon-cache --quiet %{_datadir}/icons/hicolor || : 55 | fi 56 | 57 | 58 | %files 59 | %defattr(-,root,root,-) 60 | %attr(2755,games,games) %{_bindir}/rogue 61 | %{_mandir}/man6/rogue.6.gz 62 | %{_datadir}/applications/fedora-%{name}.desktop 63 | %{_datadir}/icons/hicolor/32x32/apps/rogue.png 64 | %dir %attr(0775,games,games) %{_var}/games/roguelike 65 | %config(noreplace) %attr(0664,games,games) %{_var}/games/roguelike/rogue54.scr 66 | %doc %{_docdir}/%{name}-%{version} 67 | 68 | 69 | %changelog 70 | * Sun Sep 2 2007 Wart 5.4.4-1 71 | - Update to 5.4.4 72 | 73 | * Mon Aug 20 2007 Wart 5.4.3-1 74 | - Update to 5.4.3 75 | 76 | * Sun Jul 15 2007 Wart 5.4.2-9 77 | - New upstream home page and download URL 78 | - Add patch when reading long values from the save file on 64-bit arch 79 | (BZ #248283) 80 | - Add patch removing many compiler warnings 81 | - Use proper version in the .desktop file 82 | 83 | * Sat Mar 3 2007 Wart 5.4.2-8 84 | - Use better sourceforge download url 85 | - Use more precise desktop file categories 86 | 87 | * Mon Aug 28 2006 Wart 5.4.2-7 88 | - Rebuild for Fedora Extras 89 | 90 | * Tue May 16 2006 Wart 5.4.2-6 91 | - Added empty initial scoreboard file. 92 | 93 | * Mon May 15 2006 Wart 5.4.2-5 94 | - Better setuid/setgid handling (again) (BZ #187392) 95 | 96 | * Thu Mar 30 2006 Wart 5.4.2-4 97 | - Better setuid/setgid handling (BZ #187392) 98 | - Resize desktop icon to match directory name 99 | 100 | * Mon Mar 13 2006 Wart 5.4.2-3 101 | - Added icon for .desktop file. 102 | 103 | * Sun Mar 12 2006 Wart 5.4.2-2 104 | - Added missing BR: ncurses-devel, desktop-file-utils 105 | 106 | * Sat Feb 25 2006 Wart 5.4.2-1 107 | - Initial spec file. 108 | -------------------------------------------------------------------------------- /rogue54.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 9.00 2 | # Visual C++ Express 2005 3 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rogue54", "rogue54.vcproj", "{9EA0D326-8097-4ADA-82EA-4DB1F5CAA8F6}" 4 | EndProject 5 | Global 6 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 7 | Debug|Win32 = Debug|Win32 8 | Release|Win32 = Release|Win32 9 | EndGlobalSection 10 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 11 | {9EA0D326-8097-4ADA-82EA-4DB1F5CAA8F6}.Debug|Win32.ActiveCfg = Debug|Win32 12 | {9EA0D326-8097-4ADA-82EA-4DB1F5CAA8F6}.Debug|Win32.Build.0 = Debug|Win32 13 | {9EA0D326-8097-4ADA-82EA-4DB1F5CAA8F6}.Release|Win32.ActiveCfg = Release|Win32 14 | {9EA0D326-8097-4ADA-82EA-4DB1F5CAA8F6}.Release|Win32.Build.0 = Release|Win32 15 | EndGlobalSection 16 | GlobalSection(SolutionProperties) = preSolution 17 | HideSolutionNode = FALSE 18 | EndGlobalSection 19 | EndGlobal 20 | -------------------------------------------------------------------------------- /rogue54.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 13 | 14 | 15 | 16 | 17 | 25 | 28 | 31 | 34 | 37 | 40 | 62 | 65 | 68 | 71 | 84 | 87 | 90 | 93 | 96 | 99 | 102 | 105 | 108 | 109 | 117 | 120 | 123 | 126 | 129 | 132 | 146 | 149 | 152 | 155 | 165 | 168 | 171 | 174 | 177 | 180 | 183 | 186 | 189 | 190 | 191 | 192 | 193 | 194 | 198 | 201 | 202 | 205 | 206 | 209 | 210 | 213 | 214 | 217 | 218 | 221 | 222 | 225 | 226 | 229 | 233 | 236 | 237 | 238 | 241 | 242 | 245 | 246 | 249 | 250 | 253 | 254 | 257 | 258 | 261 | 262 | 265 | 266 | 269 | 270 | 273 | 274 | 277 | 278 | 281 | 282 | 285 | 286 | 289 | 290 | 293 | 294 | 297 | 298 | 301 | 302 | 305 | 306 | 309 | 310 | 313 | 317 | 320 | 321 | 322 | 325 | 329 | 332 | 333 | 334 | 337 | 338 | 341 | 342 | 345 | 346 | 349 | 350 | 353 | 354 | 357 | 358 | 361 | 362 | 365 | 366 | 367 | 371 | 374 | 375 | 378 | 379 | 382 | 383 | 384 | 388 | 389 | 392 | 393 | 394 | 395 | 396 | 397 | -------------------------------------------------------------------------------- /rooms.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Create the layout for the new level 3 | * 4 | * @(#)rooms.c 4.45 (Berkeley) 02/05/99 5 | * 6 | * Rogue: Exploring the Dungeons of Doom 7 | * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman 8 | * All rights reserved. 9 | * 10 | * See the file LICENSE.TXT for full copyright and licensing information. 11 | */ 12 | 13 | #include 14 | #include 15 | #include "rogue.h" 16 | 17 | typedef struct spot { /* position matrix for maze positions */ 18 | int nexits; 19 | coord exits[4]; 20 | int used; 21 | } SPOT; 22 | 23 | #define GOLDGRP 1 24 | 25 | /* 26 | * do_rooms: 27 | * Create rooms and corridors with a connectivity graph 28 | */ 29 | 30 | void 31 | do_rooms() 32 | { 33 | int i; 34 | struct room *rp; 35 | THING *tp; 36 | int left_out; 37 | static coord top; 38 | coord bsze; /* maximum room size */ 39 | coord mp; 40 | 41 | bsze.x = NUMCOLS / 3; 42 | bsze.y = NUMLINES / 3; 43 | /* 44 | * Clear things for a new level 45 | */ 46 | for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) 47 | { 48 | rp->r_goldval = 0; 49 | rp->r_nexits = 0; 50 | rp->r_flags = 0; 51 | } 52 | /* 53 | * Put the gone rooms, if any, on the level 54 | */ 55 | left_out = rnd(4); 56 | for (i = 0; i < left_out; i++) 57 | rooms[rnd_room()].r_flags |= ISGONE; 58 | /* 59 | * dig and populate all the rooms on the level 60 | */ 61 | for (i = 0, rp = rooms; i < MAXROOMS; rp++, i++) 62 | { 63 | /* 64 | * Find upper left corner of box that this room goes in 65 | */ 66 | top.x = (i % 3) * bsze.x + 1; 67 | top.y = (i / 3) * bsze.y; 68 | if (rp->r_flags & ISGONE) 69 | { 70 | /* 71 | * Place a gone room. Make certain that there is a blank line 72 | * for passage drawing. 73 | */ 74 | do 75 | { 76 | rp->r_pos.x = top.x + rnd(bsze.x - 2) + 1; 77 | rp->r_pos.y = top.y + rnd(bsze.y - 2) + 1; 78 | rp->r_max.x = -NUMCOLS; 79 | rp->r_max.y = -NUMLINES; 80 | } until (rp->r_pos.y > 0 && rp->r_pos.y < NUMLINES-1); 81 | continue; 82 | } 83 | /* 84 | * set room type 85 | */ 86 | if (rnd(10) < level - 1) 87 | { 88 | rp->r_flags |= ISDARK; /* dark room */ 89 | if (rnd(15) == 0) 90 | rp->r_flags = ISMAZE; /* maze room */ 91 | } 92 | /* 93 | * Find a place and size for a random room 94 | */ 95 | if (rp->r_flags & ISMAZE) 96 | { 97 | rp->r_max.x = bsze.x - 1; 98 | rp->r_max.y = bsze.y - 1; 99 | if ((rp->r_pos.x = top.x) == 1) 100 | rp->r_pos.x = 0; 101 | if ((rp->r_pos.y = top.y) == 0) 102 | { 103 | rp->r_pos.y++; 104 | rp->r_max.y--; 105 | } 106 | } 107 | else 108 | do 109 | { 110 | rp->r_max.x = rnd(bsze.x - 4) + 4; 111 | rp->r_max.y = rnd(bsze.y - 4) + 4; 112 | rp->r_pos.x = top.x + rnd(bsze.x - rp->r_max.x); 113 | rp->r_pos.y = top.y + rnd(bsze.y - rp->r_max.y); 114 | } until (rp->r_pos.y != 0); 115 | draw_room(rp); 116 | /* 117 | * Put the gold in 118 | */ 119 | if (rnd(2) == 0 && (!amulet || level >= max_level)) 120 | { 121 | THING *gold; 122 | 123 | gold = new_item(); 124 | gold->o_goldval = rp->r_goldval = GOLDCALC; 125 | find_floor(rp, &rp->r_gold, FALSE, FALSE); 126 | gold->o_pos = rp->r_gold; 127 | chat(rp->r_gold.y, rp->r_gold.x) = GOLD; 128 | gold->o_flags = ISMANY; 129 | gold->o_group = GOLDGRP; 130 | gold->o_type = GOLD; 131 | attach(lvl_obj, gold); 132 | } 133 | /* 134 | * Put the monster in 135 | */ 136 | if (rnd(100) < (rp->r_goldval > 0 ? 80 : 25)) 137 | { 138 | tp = new_item(); 139 | find_floor(rp, &mp, FALSE, TRUE); 140 | new_monster(tp, randmonster(FALSE), &mp); 141 | give_pack(tp); 142 | } 143 | } 144 | } 145 | 146 | /* 147 | * draw_room: 148 | * Draw a box around a room and lay down the floor for normal 149 | * rooms; for maze rooms, draw maze. 150 | */ 151 | 152 | void 153 | draw_room(struct room *rp) 154 | { 155 | int y, x; 156 | 157 | if (rp->r_flags & ISMAZE) 158 | do_maze(rp); 159 | else 160 | { 161 | vert(rp, rp->r_pos.x); /* Draw left side */ 162 | vert(rp, rp->r_pos.x + rp->r_max.x - 1); /* Draw right side */ 163 | horiz(rp, rp->r_pos.y); /* Draw top */ 164 | horiz(rp, rp->r_pos.y + rp->r_max.y - 1); /* Draw bottom */ 165 | 166 | /* 167 | * Put the floor down 168 | */ 169 | for (y = rp->r_pos.y + 1; y < rp->r_pos.y + rp->r_max.y - 1; y++) 170 | for (x = rp->r_pos.x + 1; x < rp->r_pos.x + rp->r_max.x - 1; x++) 171 | chat(y, x) = FLOOR; 172 | } 173 | } 174 | 175 | /* 176 | * vert: 177 | * Draw a vertical line 178 | */ 179 | 180 | void 181 | vert(struct room *rp, int startx) 182 | { 183 | int y; 184 | 185 | for (y = rp->r_pos.y + 1; y <= rp->r_max.y + rp->r_pos.y - 1; y++) 186 | chat(y, startx) = '|'; 187 | } 188 | 189 | /* 190 | * horiz: 191 | * Draw a horizontal line 192 | */ 193 | 194 | void 195 | horiz(struct room *rp, int starty) 196 | { 197 | int x; 198 | 199 | for (x = rp->r_pos.x; x <= rp->r_pos.x + rp->r_max.x - 1; x++) 200 | chat(starty, x) = '-'; 201 | } 202 | 203 | /* 204 | * do_maze: 205 | * Dig a maze 206 | */ 207 | 208 | static int Maxy, Maxx, Starty, Startx; 209 | 210 | static SPOT maze[NUMLINES/3+1][NUMCOLS/3+1]; 211 | 212 | 213 | void 214 | do_maze(struct room *rp) 215 | { 216 | SPOT *sp; 217 | int starty, startx; 218 | static coord pos; 219 | 220 | for (sp = &maze[0][0]; sp <= &maze[NUMLINES / 3][NUMCOLS / 3]; sp++) 221 | { 222 | sp->used = FALSE; 223 | sp->nexits = 0; 224 | } 225 | 226 | Maxy = rp->r_max.y; 227 | Maxx = rp->r_max.x; 228 | Starty = rp->r_pos.y; 229 | Startx = rp->r_pos.x; 230 | starty = (rnd(rp->r_max.y) / 2) * 2; 231 | startx = (rnd(rp->r_max.x) / 2) * 2; 232 | pos.y = starty + Starty; 233 | pos.x = startx + Startx; 234 | putpass(&pos); 235 | dig(starty, startx); 236 | } 237 | 238 | /* 239 | * dig: 240 | * Dig out from around where we are now, if possible 241 | */ 242 | 243 | void 244 | dig(int y, int x) 245 | { 246 | coord *cp; 247 | int cnt, newy, newx, nexty = 0, nextx = 0; 248 | static coord pos; 249 | static coord del[4] = { 250 | {2, 0}, {-2, 0}, {0, 2}, {0, -2} 251 | }; 252 | 253 | for (;;) 254 | { 255 | cnt = 0; 256 | for (cp = del; cp <= &del[3]; cp++) 257 | { 258 | newy = y + cp->y; 259 | newx = x + cp->x; 260 | if (newy < 0 || newy > Maxy || newx < 0 || newx > Maxx) 261 | continue; 262 | if (flat(newy + Starty, newx + Startx) & F_PASS) 263 | continue; 264 | if (rnd(++cnt) == 0) 265 | { 266 | nexty = newy; 267 | nextx = newx; 268 | } 269 | } 270 | if (cnt == 0) 271 | return; 272 | accnt_maze(y, x, nexty, nextx); 273 | accnt_maze(nexty, nextx, y, x); 274 | if (nexty == y) 275 | { 276 | pos.y = y + Starty; 277 | if (nextx - x < 0) 278 | pos.x = nextx + Startx + 1; 279 | else 280 | pos.x = nextx + Startx - 1; 281 | } 282 | else 283 | { 284 | pos.x = x + Startx; 285 | if (nexty - y < 0) 286 | pos.y = nexty + Starty + 1; 287 | else 288 | pos.y = nexty + Starty - 1; 289 | } 290 | putpass(&pos); 291 | pos.y = nexty + Starty; 292 | pos.x = nextx + Startx; 293 | putpass(&pos); 294 | dig(nexty, nextx); 295 | } 296 | } 297 | 298 | /* 299 | * accnt_maze: 300 | * Account for maze exits 301 | */ 302 | 303 | void 304 | accnt_maze(int y, int x, int ny, int nx) 305 | { 306 | SPOT *sp; 307 | coord *cp; 308 | 309 | sp = &maze[y][x]; 310 | for (cp = sp->exits; cp < &sp->exits[sp->nexits]; cp++) 311 | if (cp->y == ny && cp->x == nx) 312 | return; 313 | cp->y = ny; 314 | cp->x = nx; 315 | } 316 | 317 | /* 318 | * rnd_pos: 319 | * Pick a random spot in a room 320 | */ 321 | 322 | void 323 | rnd_pos(struct room *rp, coord *cp) 324 | { 325 | cp->x = rp->r_pos.x + rnd(rp->r_max.x - 2) + 1; 326 | cp->y = rp->r_pos.y + rnd(rp->r_max.y - 2) + 1; 327 | } 328 | 329 | /* 330 | * find_floor: 331 | * Find a valid floor spot in this room. If rp is NULL, then 332 | * pick a new room each time around the loop. 333 | */ 334 | bool 335 | find_floor(struct room *rp, coord *cp, int limit, bool monst) 336 | { 337 | PLACE *pp; 338 | int cnt; 339 | char compchar = 0; 340 | bool pickroom; 341 | 342 | pickroom = (bool)(rp == NULL); 343 | 344 | if (!pickroom) 345 | compchar = ((rp->r_flags & ISMAZE) ? PASSAGE : FLOOR); 346 | cnt = limit; 347 | for (;;) 348 | { 349 | if (limit && cnt-- == 0) 350 | return FALSE; 351 | if (pickroom) 352 | { 353 | rp = &rooms[rnd_room()]; 354 | compchar = ((rp->r_flags & ISMAZE) ? PASSAGE : FLOOR); 355 | } 356 | rnd_pos(rp, cp); 357 | pp = INDEX(cp->y, cp->x); 358 | if (monst) 359 | { 360 | if (pp->p_monst == NULL && step_ok(pp->p_ch)) 361 | return TRUE; 362 | } 363 | else if (pp->p_ch == compchar) 364 | return TRUE; 365 | } 366 | } 367 | 368 | /* 369 | * enter_room: 370 | * Code that is executed whenver you appear in a room 371 | */ 372 | 373 | void 374 | enter_room(coord *cp) 375 | { 376 | struct room *rp; 377 | THING *tp; 378 | int y, x; 379 | char ch; 380 | 381 | rp = proom = roomin(cp); 382 | door_open(rp); 383 | if (!(rp->r_flags & ISDARK) && !on(player, ISBLIND)) 384 | for (y = rp->r_pos.y; y < rp->r_max.y + rp->r_pos.y; y++) 385 | { 386 | move(y, rp->r_pos.x); 387 | for (x = rp->r_pos.x; x < rp->r_max.x + rp->r_pos.x; x++) 388 | { 389 | tp = moat(y, x); 390 | ch = chat(y, x); 391 | if (tp == NULL) 392 | if (CCHAR(inch()) != ch) 393 | addch(ch); 394 | else 395 | move(y, x + 1); 396 | else 397 | { 398 | tp->t_oldch = ch; 399 | if (!see_monst(tp)) 400 | if (on(player, SEEMONST)) 401 | { 402 | standout(); 403 | addch(tp->t_disguise); 404 | standend(); 405 | } 406 | else 407 | addch(ch); 408 | else 409 | addch(tp->t_disguise); 410 | } 411 | } 412 | } 413 | } 414 | 415 | /* 416 | * leave_room: 417 | * Code for when we exit a room 418 | */ 419 | 420 | void 421 | leave_room(coord *cp) 422 | { 423 | PLACE *pp; 424 | struct room *rp; 425 | int y, x; 426 | char floor; 427 | char ch; 428 | 429 | rp = proom; 430 | 431 | if (rp->r_flags & ISMAZE) 432 | return; 433 | 434 | if (rp->r_flags & ISGONE) 435 | floor = PASSAGE; 436 | else if (!(rp->r_flags & ISDARK) || on(player, ISBLIND)) 437 | floor = FLOOR; 438 | else 439 | floor = ' '; 440 | 441 | proom = &passages[flat(cp->y, cp->x) & F_PNUM]; 442 | for (y = rp->r_pos.y; y < rp->r_max.y + rp->r_pos.y; y++) 443 | for (x = rp->r_pos.x; x < rp->r_max.x + rp->r_pos.x; x++) 444 | { 445 | move(y, x); 446 | switch ( ch = CCHAR(inch()) ) 447 | { 448 | case FLOOR: 449 | if (floor == ' ' && ch != ' ') 450 | addch(' '); 451 | break; 452 | default: 453 | /* 454 | * to check for monster, we have to strip out 455 | * standout bit 456 | */ 457 | if (isupper(toascii(ch))) 458 | { 459 | if (on(player, SEEMONST)) 460 | { 461 | standout(); 462 | addch(ch); 463 | standend(); 464 | break; 465 | } 466 | pp = INDEX(y,x); 467 | addch(pp->p_ch == DOOR ? DOOR : floor); 468 | } 469 | } 470 | } 471 | door_open(rp); 472 | } 473 | -------------------------------------------------------------------------------- /save.c: -------------------------------------------------------------------------------- 1 | /* 2 | * save and restore routines 3 | * 4 | * @(#)save.c 4.33 (Berkeley) 06/01/83 5 | * 6 | * Rogue: Exploring the Dungeons of Doom 7 | * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman 8 | * All rights reserved. 9 | * 10 | * See the file LICENSE.TXT for full copyright and licensing information. 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include "rogue.h" 21 | #include "score.h" 22 | 23 | typedef struct stat STAT; 24 | 25 | extern char version[], encstr[]; 26 | 27 | static STAT sbuf; 28 | 29 | /* 30 | * save_game: 31 | * Implement the "save game" command 32 | */ 33 | 34 | void 35 | save_game() 36 | { 37 | FILE *savef; 38 | int c; 39 | auto char buf[MAXSTR]; 40 | 41 | /* 42 | * get file name 43 | */ 44 | mpos = 0; 45 | over: 46 | if (file_name[0] != '\0') 47 | { 48 | for (;;) 49 | { 50 | msg("save file (%s)? ", file_name); 51 | c = readchar(); 52 | mpos = 0; 53 | if (c == ESCAPE) 54 | { 55 | msg(""); 56 | return; 57 | } 58 | else if (c == 'n' || c == 'N' || c == 'y' || c == 'Y') 59 | break; 60 | else 61 | msg("please answer Y or N"); 62 | } 63 | if (c == 'y' || c == 'Y') 64 | { 65 | addstr("Yes\n"); 66 | refresh(); 67 | strcpy(buf, file_name); 68 | goto gotfile; 69 | } 70 | } 71 | 72 | do 73 | { 74 | mpos = 0; 75 | msg("file name: "); 76 | buf[0] = '\0'; 77 | if (get_str(buf, stdscr) == QUIT) 78 | { 79 | quit_it: 80 | msg(""); 81 | return; 82 | } 83 | mpos = 0; 84 | gotfile: 85 | /* 86 | * test to see if the file exists 87 | */ 88 | if (stat(buf, &sbuf) >= 0) 89 | { 90 | for (;;) 91 | { 92 | msg("File exists. Do you wish to overwrite it?"); 93 | mpos = 0; 94 | if ((c = readchar()) == ESCAPE) 95 | goto quit_it; 96 | if (c == 'y' || c == 'Y') 97 | break; 98 | else if (c == 'n' || c == 'N') 99 | goto over; 100 | else 101 | msg("Please answer Y or N"); 102 | } 103 | msg("file name: %s", buf); 104 | md_unlink(file_name); 105 | } 106 | strcpy(file_name, buf); 107 | if ((savef = fopen(file_name, "w")) == NULL) 108 | msg(strerror(errno)); 109 | } while (savef == NULL); 110 | 111 | save_file(savef); 112 | /* NOTREACHED */ 113 | } 114 | 115 | /* 116 | * auto_save: 117 | * Automatically save a file. This is used if a HUP signal is 118 | * recieved 119 | */ 120 | 121 | void 122 | auto_save(int sig) 123 | { 124 | FILE *savef; 125 | NOOP(sig); 126 | 127 | md_ignoreallsignals(); 128 | if (file_name[0] != '\0' && ((savef = fopen(file_name, "w")) != NULL || 129 | (md_unlink_open_file(file_name, savef) >= 0 && (savef = fopen(file_name, "w")) != NULL))) 130 | save_file(savef); 131 | exit(0); 132 | } 133 | 134 | /* 135 | * save_file: 136 | * Write the saved game on the file 137 | */ 138 | 139 | void 140 | save_file(FILE *savef) 141 | { 142 | char buf[80]; 143 | mvcur(0, COLS - 1, LINES - 1, 0); 144 | putchar('\n'); 145 | endwin(); 146 | resetltchars(); 147 | md_chmod(file_name, 0400); 148 | encwrite(version, strlen(version)+1, savef); 149 | sprintf(buf,"%d x %d\n", LINES, COLS); 150 | encwrite(buf,80,savef); 151 | rs_save_file(savef); 152 | fflush(savef); 153 | fclose(savef); 154 | exit(0); 155 | } 156 | 157 | /* 158 | * restore: 159 | * Restore a saved game from a file with elaborate checks for file 160 | * integrity from cheaters 161 | */ 162 | bool 163 | restore(char *file, char **envp) 164 | { 165 | FILE *inf; 166 | int syml; 167 | extern char **environ; 168 | auto char buf[MAXSTR]; 169 | auto STAT sbuf2; 170 | int lines, cols; 171 | 172 | if (strcmp(file, "-r") == 0) 173 | file = file_name; 174 | 175 | md_tstphold(); 176 | 177 | if ((inf = fopen(file,"r")) == NULL) 178 | { 179 | perror(file); 180 | return FALSE; 181 | } 182 | stat(file, &sbuf2); 183 | syml = is_symlink(file); 184 | 185 | fflush(stdout); 186 | encread(buf, (unsigned) strlen(version) + 1, inf); 187 | if (strcmp(buf, version) != 0) 188 | { 189 | printf("Sorry, saved game is out of date.\n"); 190 | return FALSE; 191 | } 192 | encread(buf,80,inf); 193 | sscanf(buf,"%d x %d\n", &lines, &cols); 194 | 195 | initscr(); /* Start up cursor package */ 196 | keypad(stdscr, 1); 197 | 198 | if (lines > LINES) 199 | { 200 | endwin(); 201 | printf("Sorry, original game was played on a screen with %d lines.\n",lines); 202 | printf("Current screen only has %d lines. Unable to restore game\n",LINES); 203 | return(FALSE); 204 | } 205 | if (cols > COLS) 206 | { 207 | endwin(); 208 | printf("Sorry, original game was played on a screen with %d columns.\n",cols); 209 | printf("Current screen only has %d columns. Unable to restore game\n",COLS); 210 | return(FALSE); 211 | } 212 | 213 | hw = newwin(LINES, COLS, 0, 0); 214 | setup(); 215 | 216 | rs_restore_file(inf); 217 | /* 218 | * we do not close the file so that we will have a hold of the 219 | * inode for as long as possible 220 | */ 221 | 222 | if ( 223 | #ifdef MASTER 224 | !wizard && 225 | #endif 226 | md_unlink_open_file(file, inf) < 0) 227 | { 228 | printf("Cannot unlink file\n"); 229 | return FALSE; 230 | } 231 | mpos = 0; 232 | /* printw(0, 0, "%s: %s", file, ctime(&sbuf2.st_mtime)); */ 233 | /* 234 | printw("%s: %s", file, ctime(&sbuf2.st_mtime)); 235 | */ 236 | clearok(stdscr,TRUE); 237 | /* 238 | * defeat multiple restarting from the same place 239 | */ 240 | #ifdef MASTER 241 | if (!wizard) 242 | #endif 243 | if (sbuf2.st_nlink != 1 || syml) 244 | { 245 | endwin(); 246 | printf("\nCannot restore from a linked file\n"); 247 | return FALSE; 248 | } 249 | 250 | if (pstats.s_hpt <= 0) 251 | { 252 | endwin(); 253 | printf("\n\"He's dead, Jim\"\n"); 254 | return FALSE; 255 | } 256 | 257 | md_tstpresume(); 258 | 259 | environ = envp; 260 | strcpy(file_name, file); 261 | clearok(curscr, TRUE); 262 | srand(md_getpid()); 263 | msg("file name: %s", file); 264 | playit(); 265 | /*NOTREACHED*/ 266 | return(0); 267 | } 268 | 269 | /* 270 | * encwrite: 271 | * Perform an encrypted write 272 | */ 273 | 274 | size_t 275 | encwrite(char *start, size_t size, FILE *outf) 276 | { 277 | char *e1, *e2, fb; 278 | int temp; 279 | extern char statlist[]; 280 | size_t o_size = size; 281 | e1 = encstr; 282 | e2 = statlist; 283 | fb = 0; 284 | 285 | while(size) 286 | { 287 | if (putc(*start++ ^ *e1 ^ *e2 ^ fb, outf) == EOF) 288 | break; 289 | 290 | temp = *e1++; 291 | fb = fb + ((char) (temp * *e2++)); 292 | if (*e1 == '\0') 293 | e1 = encstr; 294 | if (*e2 == '\0') 295 | e2 = statlist; 296 | size--; 297 | } 298 | 299 | return(o_size - size); 300 | } 301 | 302 | /* 303 | * encread: 304 | * Perform an encrypted read 305 | */ 306 | size_t 307 | encread(char *start, size_t size, FILE *inf) 308 | { 309 | char *e1, *e2, fb; 310 | int temp; 311 | size_t read_size; 312 | extern char statlist[]; 313 | 314 | fb = 0; 315 | 316 | if ((read_size = fread(start,1,size,inf)) == 0 || read_size == -1) 317 | return(read_size); 318 | 319 | e1 = encstr; 320 | e2 = statlist; 321 | 322 | while (size--) 323 | { 324 | *start++ ^= *e1 ^ *e2 ^ fb; 325 | temp = *e1++; 326 | fb = fb + (char)(temp * *e2++); 327 | if (*e1 == '\0') 328 | e1 = encstr; 329 | if (*e2 == '\0') 330 | e2 = statlist; 331 | } 332 | 333 | return(read_size); 334 | } 335 | 336 | static char scoreline[100]; 337 | /* 338 | * read_scrore 339 | * Read in the score file 340 | */ 341 | void 342 | rd_score(SCORE *top_ten) 343 | { 344 | unsigned int i; 345 | 346 | if (scoreboard == NULL) 347 | return; 348 | 349 | rewind(scoreboard); 350 | 351 | for(i = 0; i < numscores; i++) 352 | { 353 | encread(top_ten[i].sc_name, MAXSTR, scoreboard); 354 | encread(scoreline, 100, scoreboard); 355 | sscanf(scoreline, " %u %d %u %hu %d %x \n", 356 | &top_ten[i].sc_uid, &top_ten[i].sc_score, 357 | &top_ten[i].sc_flags, &top_ten[i].sc_monster, 358 | &top_ten[i].sc_level, &top_ten[i].sc_time); 359 | } 360 | 361 | rewind(scoreboard); 362 | } 363 | 364 | /* 365 | * write_scrore 366 | * Read in the score file 367 | */ 368 | void 369 | wr_score(SCORE *top_ten) 370 | { 371 | unsigned int i; 372 | 373 | if (scoreboard == NULL) 374 | return; 375 | 376 | rewind(scoreboard); 377 | 378 | for(i = 0; i < numscores; i++) 379 | { 380 | memset(scoreline,0,100); 381 | encwrite(top_ten[i].sc_name, MAXSTR, scoreboard); 382 | sprintf(scoreline, " %u %d %u %hu %d %x \n", 383 | top_ten[i].sc_uid, top_ten[i].sc_score, 384 | top_ten[i].sc_flags, top_ten[i].sc_monster, 385 | top_ten[i].sc_level, top_ten[i].sc_time); 386 | encwrite(scoreline,100,scoreboard); 387 | } 388 | 389 | rewind(scoreboard); 390 | } 391 | -------------------------------------------------------------------------------- /score.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Score file structure 3 | * 4 | * @(#)score.h 4.6 (Berkeley) 02/05/99 5 | * 6 | * Rogue: Exploring the Dungeons of Doom 7 | * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman 8 | * All rights reserved. 9 | * 10 | * See the file LICENSE.TXT for full copyright and licensing information. 11 | */ 12 | 13 | struct sc_ent { 14 | unsigned int sc_uid; 15 | int sc_score; 16 | unsigned int sc_flags; 17 | unsigned short sc_monster; 18 | char sc_name[MAXSTR]; 19 | int sc_level; 20 | unsigned int sc_time; 21 | }; 22 | 23 | typedef struct sc_ent SCORE; 24 | 25 | void rd_score(SCORE *top_ten); 26 | void wr_score(SCORE *top_ten); 27 | -------------------------------------------------------------------------------- /scrolls.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Read a scroll and let it happen 3 | * 4 | * @(#)scrolls.c 4.44 (Berkeley) 02/05/99 5 | * 6 | * Rogue: Exploring the Dungeons of Doom 7 | * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman 8 | * All rights reserved. 9 | * 10 | * See the file LICENSE.TXT for full copyright and licensing information. 11 | */ 12 | 13 | #include 14 | #include 15 | #include "rogue.h" 16 | 17 | /* 18 | * read_scroll: 19 | * Read a scroll from the pack and do the appropriate thing 20 | */ 21 | 22 | void 23 | read_scroll() 24 | { 25 | THING *obj; 26 | PLACE *pp; 27 | int y, x; 28 | char ch; 29 | int i; 30 | bool discardit = FALSE; 31 | struct room *cur_room; 32 | THING *orig_obj; 33 | static coord mp; 34 | 35 | obj = get_item("read", SCROLL); 36 | if (obj == NULL) 37 | return; 38 | if (obj->o_type != SCROLL) 39 | { 40 | if (!terse) 41 | msg("there is nothing on it to read"); 42 | else 43 | msg("nothing to read"); 44 | return; 45 | } 46 | /* 47 | * Calculate the effect it has on the poor guy. 48 | */ 49 | if (obj == cur_weapon) 50 | cur_weapon = NULL; 51 | /* 52 | * Get rid of the thing 53 | */ 54 | discardit = (bool)(obj->o_count == 1); 55 | leave_pack(obj, FALSE, FALSE); 56 | orig_obj = obj; 57 | 58 | switch (obj->o_which) 59 | { 60 | case S_CONFUSE: 61 | /* 62 | * Scroll of monster confusion. Give him that power. 63 | */ 64 | player.t_flags |= CANHUH; 65 | msg("your hands begin to glow %s", pick_color("red")); 66 | when S_ARMOR: 67 | if (cur_armor != NULL) 68 | { 69 | cur_armor->o_arm--; 70 | cur_armor->o_flags &= ~ISCURSED; 71 | msg("your armor glows %s for a moment", pick_color("silver")); 72 | } 73 | when S_HOLD: 74 | /* 75 | * Hold monster scroll. Stop all monsters within two spaces 76 | * from chasing after the hero. 77 | */ 78 | 79 | ch = 0; 80 | for (x = hero.x - 2; x <= hero.x + 2; x++) 81 | if (x >= 0 && x < NUMCOLS) 82 | for (y = hero.y - 2; y <= hero.y + 2; y++) 83 | if (y >= 0 && y <= NUMLINES - 1) 84 | if ((obj = moat(y, x)) != NULL && on(*obj, ISRUN)) 85 | { 86 | obj->t_flags &= ~ISRUN; 87 | obj->t_flags |= ISHELD; 88 | ch++; 89 | } 90 | if (ch) 91 | { 92 | addmsg("the monster"); 93 | if (ch > 1) 94 | addmsg("s around you"); 95 | addmsg(" freeze"); 96 | if (ch == 1) 97 | addmsg("s"); 98 | endmsg(); 99 | scr_info[S_HOLD].oi_know = TRUE; 100 | } 101 | else 102 | msg("you feel a strange sense of loss"); 103 | when S_SLEEP: 104 | /* 105 | * Scroll which makes you fall asleep 106 | */ 107 | scr_info[S_SLEEP].oi_know = TRUE; 108 | no_command += rnd(SLEEPTIME) + 4; 109 | player.t_flags &= ~ISRUN; 110 | msg("you fall asleep"); 111 | when S_CREATE: 112 | /* 113 | * Create a monster: 114 | * First look in a circle around him, next try his room 115 | * otherwise give up 116 | */ 117 | i = 0; 118 | for (y = hero.y - 1; y <= hero.y + 1; y++) 119 | for (x = hero.x - 1; x <= hero.x + 1; x++) 120 | /* 121 | * Don't put a monster in top of the player. 122 | */ 123 | if (y == hero.y && x == hero.x) 124 | continue; 125 | /* 126 | * Or anything else nasty 127 | */ 128 | else if (step_ok(ch = winat(y, x))) 129 | { 130 | if (ch == SCROLL 131 | && find_obj(y, x)->o_which == S_SCARE) 132 | continue; 133 | else if (rnd(++i) == 0) 134 | { 135 | mp.y = y; 136 | mp.x = x; 137 | } 138 | } 139 | if (i == 0) 140 | msg("you hear a faint cry of anguish in the distance"); 141 | else 142 | { 143 | obj = new_item(); 144 | new_monster(obj, randmonster(FALSE), &mp); 145 | } 146 | when S_ID_POTION: 147 | case S_ID_SCROLL: 148 | case S_ID_WEAPON: 149 | case S_ID_ARMOR: 150 | case S_ID_R_OR_S: 151 | { 152 | static char id_type[S_ID_R_OR_S + 1] = 153 | { 0, 0, 0, 0, 0, POTION, SCROLL, WEAPON, ARMOR, R_OR_S }; 154 | /* 155 | * Identify, let him figure something out 156 | */ 157 | scr_info[obj->o_which].oi_know = TRUE; 158 | msg("this scroll is an %s scroll", scr_info[obj->o_which].oi_name); 159 | whatis(TRUE, id_type[obj->o_which]); 160 | } 161 | when S_MAP: 162 | /* 163 | * Scroll of magic mapping. 164 | */ 165 | scr_info[S_MAP].oi_know = TRUE; 166 | msg("oh, now this scroll has a map on it"); 167 | /* 168 | * take all the things we want to keep hidden out of the window 169 | */ 170 | for (y = 1; y < NUMLINES - 1; y++) 171 | for (x = 0; x < NUMCOLS; x++) 172 | { 173 | pp = INDEX(y, x); 174 | switch (ch = pp->p_ch) 175 | { 176 | case DOOR: 177 | case STAIRS: 178 | break; 179 | 180 | case '-': 181 | case '|': 182 | if (!(pp->p_flags & F_REAL)) 183 | { 184 | ch = pp->p_ch = DOOR; 185 | pp->p_flags |= F_REAL; 186 | } 187 | break; 188 | 189 | case ' ': 190 | if (pp->p_flags & F_REAL) 191 | goto def; 192 | pp->p_flags |= F_REAL; 193 | ch = pp->p_ch = PASSAGE; 194 | /* FALLTHROUGH */ 195 | 196 | case PASSAGE: 197 | pass: 198 | if (!(pp->p_flags & F_REAL)) 199 | pp->p_ch = PASSAGE; 200 | pp->p_flags |= (F_SEEN|F_REAL); 201 | ch = PASSAGE; 202 | break; 203 | 204 | case FLOOR: 205 | if (pp->p_flags & F_REAL) 206 | ch = ' '; 207 | else 208 | { 209 | ch = TRAP; 210 | pp->p_ch = TRAP; 211 | pp->p_flags |= (F_SEEN|F_REAL); 212 | } 213 | break; 214 | 215 | default: 216 | def: 217 | if (pp->p_flags & F_PASS) 218 | goto pass; 219 | ch = ' '; 220 | break; 221 | } 222 | if (ch != ' ') 223 | { 224 | if ((obj = pp->p_monst) != NULL) 225 | obj->t_oldch = ch; 226 | if (obj == NULL || !on(player, SEEMONST)) 227 | mvaddch(y, x, ch); 228 | } 229 | } 230 | when S_FDET: 231 | /* 232 | * Potion of gold detection 233 | */ 234 | ch = FALSE; 235 | wclear(hw); 236 | for (obj = lvl_obj; obj != NULL; obj = next(obj)) 237 | if (obj->o_type == FOOD) 238 | { 239 | ch = TRUE; 240 | wmove(hw, obj->o_pos.y, obj->o_pos.x); 241 | waddch(hw, FOOD); 242 | } 243 | if (ch) 244 | { 245 | scr_info[S_FDET].oi_know = TRUE; 246 | show_win("Your nose tingles and you smell food.--More--"); 247 | } 248 | else 249 | msg("your nose tingles"); 250 | when S_TELEP: 251 | /* 252 | * Scroll of teleportation: 253 | * Make him dissapear and reappear 254 | */ 255 | { 256 | cur_room = proom; 257 | teleport(); 258 | if (cur_room != proom) 259 | scr_info[S_TELEP].oi_know = TRUE; 260 | } 261 | when S_ENCH: 262 | if (cur_weapon == NULL || cur_weapon->o_type != WEAPON) 263 | msg("you feel a strange sense of loss"); 264 | else 265 | { 266 | cur_weapon->o_flags &= ~ISCURSED; 267 | if (rnd(2) == 0) 268 | cur_weapon->o_hplus++; 269 | else 270 | cur_weapon->o_dplus++; 271 | msg("your %s glows %s for a moment", 272 | weap_info[cur_weapon->o_which].oi_name, pick_color("blue")); 273 | } 274 | when S_SCARE: 275 | /* 276 | * Reading it is a mistake and produces laughter at her 277 | * poor boo boo. 278 | */ 279 | msg("you hear maniacal laughter in the distance"); 280 | when S_REMOVE: 281 | uncurse(cur_armor); 282 | uncurse(cur_weapon); 283 | uncurse(cur_ring[LEFT]); 284 | uncurse(cur_ring[RIGHT]); 285 | msg(choose_str("you feel in touch with the Universal Onenes", 286 | "you feel as if somebody is watching over you")); 287 | when S_AGGR: 288 | /* 289 | * This scroll aggravates all the monsters on the current 290 | * level and sets them running towards the hero 291 | */ 292 | aggravate(); 293 | msg("you hear a high pitched humming noise"); 294 | when S_PROTECT: 295 | if (cur_armor != NULL) 296 | { 297 | cur_armor->o_flags |= ISPROT; 298 | msg("your armor is covered by a shimmering %s shield", 299 | pick_color("gold")); 300 | } 301 | else 302 | msg("you feel a strange sense of loss"); 303 | #ifdef MASTER 304 | otherwise: 305 | msg("what a puzzling scroll!"); 306 | return; 307 | #endif 308 | } 309 | obj = orig_obj; 310 | look(TRUE); /* put the result of the scroll on the screen */ 311 | status(); 312 | 313 | call_it(&scr_info[obj->o_which]); 314 | 315 | if (discardit) 316 | discard(obj); 317 | } 318 | 319 | /* 320 | * uncurse: 321 | * Uncurse an item 322 | */ 323 | 324 | void 325 | uncurse(THING *obj) 326 | { 327 | if (obj != NULL) 328 | obj->o_flags &= ~ISCURSED; 329 | } 330 | -------------------------------------------------------------------------------- /sticks.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Functions to implement the various sticks one might find 3 | * while wandering around the dungeon. 4 | * 5 | * @(#)sticks.c 4.39 (Berkeley) 02/05/99 6 | * 7 | * Rogue: Exploring the Dungeons of Doom 8 | * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman 9 | * All rights reserved. 10 | * 11 | * See the file LICENSE.TXT for full copyright and licensing information. 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include "rogue.h" 18 | 19 | /* 20 | * fix_stick: 21 | * Set up a new stick 22 | */ 23 | 24 | void 25 | fix_stick(THING *cur) 26 | { 27 | if (strcmp(ws_type[cur->o_which], "staff") == 0) 28 | strncpy(cur->o_damage,"2x3",sizeof(cur->o_damage)); 29 | else 30 | strncpy(cur->o_damage,"1x1",sizeof(cur->o_damage)); 31 | strncpy(cur->o_hurldmg,"1x1",sizeof(cur->o_hurldmg)); 32 | 33 | switch (cur->o_which) 34 | { 35 | case WS_LIGHT: 36 | cur->o_charges = rnd(10) + 10; 37 | otherwise: 38 | cur->o_charges = rnd(5) + 3; 39 | } 40 | } 41 | 42 | /* 43 | * do_zap: 44 | * Perform a zap with a wand 45 | */ 46 | 47 | void 48 | do_zap() 49 | { 50 | THING *obj, *tp; 51 | int y, x; 52 | char *name; 53 | char monster, oldch; 54 | static THING bolt; 55 | 56 | if ((obj = get_item("zap with", STICK)) == NULL) 57 | return; 58 | if (obj->o_type != STICK) 59 | { 60 | after = FALSE; 61 | msg("you can't zap with that!"); 62 | return; 63 | } 64 | if (obj->o_charges == 0) 65 | { 66 | msg("nothing happens"); 67 | return; 68 | } 69 | switch (obj->o_which) 70 | { 71 | case WS_LIGHT: 72 | /* 73 | * Reddy Kilowat wand. Light up the room 74 | */ 75 | ws_info[WS_LIGHT].oi_know = TRUE; 76 | if (proom->r_flags & ISGONE) 77 | msg("the corridor glows and then fades"); 78 | else 79 | { 80 | proom->r_flags &= ~ISDARK; 81 | /* 82 | * Light the room and put the player back up 83 | */ 84 | enter_room(&hero); 85 | addmsg("the room is lit"); 86 | if (!terse) 87 | addmsg(" by a shimmering %s light", pick_color("blue")); 88 | endmsg(); 89 | } 90 | when WS_DRAIN: 91 | /* 92 | * take away 1/2 of hero's hit points, then take it away 93 | * evenly from the monsters in the room (or next to hero 94 | * if he is in a passage) 95 | */ 96 | if (pstats.s_hpt < 2) 97 | { 98 | msg("you are too weak to use it"); 99 | return; 100 | } 101 | else 102 | drain(); 103 | when WS_INVIS: 104 | case WS_POLYMORPH: 105 | case WS_TELAWAY: 106 | case WS_TELTO: 107 | case WS_CANCEL: 108 | y = hero.y; 109 | x = hero.x; 110 | while (step_ok(winat(y, x))) 111 | { 112 | y += delta.y; 113 | x += delta.x; 114 | } 115 | if ((tp = moat(y, x)) != NULL) 116 | { 117 | monster = tp->t_type; 118 | if (monster == 'F') 119 | player.t_flags &= ~ISHELD; 120 | switch (obj->o_which) { 121 | case WS_INVIS: 122 | tp->t_flags |= ISINVIS; 123 | if (cansee(y, x)) 124 | mvaddch(y, x, tp->t_oldch); 125 | break; 126 | case WS_POLYMORPH: 127 | { 128 | THING *pp; 129 | 130 | pp = tp->t_pack; 131 | detach(mlist, tp); 132 | if (see_monst(tp)) 133 | mvaddch(y, x, chat(y, x)); 134 | oldch = tp->t_oldch; 135 | delta.y = y; 136 | delta.x = x; 137 | new_monster(tp, monster = (char)(rnd(26) + 'A'), &delta); 138 | if (see_monst(tp)) 139 | mvaddch(y, x, monster); 140 | tp->t_oldch = oldch; 141 | tp->t_pack = pp; 142 | ws_info[WS_POLYMORPH].oi_know |= see_monst(tp); 143 | break; 144 | } 145 | case WS_CANCEL: 146 | tp->t_flags |= ISCANC; 147 | tp->t_flags &= ~(ISINVIS|CANHUH); 148 | tp->t_disguise = tp->t_type; 149 | if (see_monst(tp)) 150 | mvaddch(y, x, tp->t_disguise); 151 | break; 152 | case WS_TELAWAY: 153 | case WS_TELTO: 154 | { 155 | coord new_pos; 156 | 157 | if (obj->o_which == WS_TELAWAY) 158 | { 159 | do 160 | { 161 | find_floor(NULL, &new_pos, FALSE, TRUE); 162 | } while (ce(new_pos, hero)); 163 | } 164 | else 165 | { 166 | new_pos.y = hero.y + delta.y; 167 | new_pos.x = hero.x + delta.x; 168 | } 169 | tp->t_dest = &hero; 170 | tp->t_flags |= ISRUN; 171 | relocate(tp, &new_pos); 172 | } 173 | } 174 | } 175 | when WS_MISSILE: 176 | ws_info[WS_MISSILE].oi_know = TRUE; 177 | bolt.o_type = '*'; 178 | strncpy(bolt.o_hurldmg,"1x4",sizeof(bolt.o_hurldmg)); 179 | bolt.o_hplus = 100; 180 | bolt.o_dplus = 1; 181 | bolt.o_flags = ISMISL; 182 | if (cur_weapon != NULL) 183 | bolt.o_launch = cur_weapon->o_which; 184 | do_motion(&bolt, delta.y, delta.x); 185 | if ((tp = moat(bolt.o_pos.y, bolt.o_pos.x)) != NULL 186 | && !save_throw(VS_MAGIC, tp)) 187 | hit_monster(unc(bolt.o_pos), &bolt); 188 | else if (terse) 189 | msg("missle vanishes"); 190 | else 191 | msg("the missle vanishes with a puff of smoke"); 192 | when WS_HASTE_M: 193 | case WS_SLOW_M: 194 | y = hero.y; 195 | x = hero.x; 196 | while (step_ok(winat(y, x))) 197 | { 198 | y += delta.y; 199 | x += delta.x; 200 | } 201 | if ((tp = moat(y, x)) != NULL) 202 | { 203 | if (obj->o_which == WS_HASTE_M) 204 | { 205 | if (on(*tp, ISSLOW)) 206 | tp->t_flags &= ~ISSLOW; 207 | else 208 | tp->t_flags |= ISHASTE; 209 | } 210 | else 211 | { 212 | if (on(*tp, ISHASTE)) 213 | tp->t_flags &= ~ISHASTE; 214 | else 215 | tp->t_flags |= ISSLOW; 216 | tp->t_turn = TRUE; 217 | } 218 | delta.y = y; 219 | delta.x = x; 220 | runto(&delta); 221 | } 222 | when WS_ELECT: 223 | case WS_FIRE: 224 | case WS_COLD: 225 | if (obj->o_which == WS_ELECT) 226 | name = "bolt"; 227 | else if (obj->o_which == WS_FIRE) 228 | name = "flame"; 229 | else 230 | name = "ice"; 231 | fire_bolt(&hero, &delta, name); 232 | ws_info[obj->o_which].oi_know = TRUE; 233 | when WS_NOP: 234 | break; 235 | #ifdef MASTER 236 | otherwise: 237 | msg("what a bizarre schtick!"); 238 | #endif 239 | } 240 | obj->o_charges--; 241 | } 242 | 243 | /* 244 | * drain: 245 | * Do drain hit points from player shtick 246 | */ 247 | 248 | void 249 | drain() 250 | { 251 | THING *mp; 252 | struct room *corp; 253 | THING **dp; 254 | int cnt; 255 | bool inpass; 256 | static THING *drainee[40]; 257 | 258 | /* 259 | * First cnt how many things we need to spread the hit points among 260 | */ 261 | cnt = 0; 262 | if (chat(hero.y, hero.x) == DOOR) 263 | corp = &passages[flat(hero.y, hero.x) & F_PNUM]; 264 | else 265 | corp = NULL; 266 | inpass = (bool)(proom->r_flags & ISGONE); 267 | dp = drainee; 268 | for (mp = mlist; mp != NULL; mp = next(mp)) 269 | if (mp->t_room == proom || mp->t_room == corp || 270 | (inpass && chat(mp->t_pos.y, mp->t_pos.x) == DOOR && 271 | &passages[flat(mp->t_pos.y, mp->t_pos.x) & F_PNUM] == proom)) 272 | *dp++ = mp; 273 | if ((cnt = (int)(dp - drainee)) == 0) 274 | { 275 | msg("you have a tingling feeling"); 276 | return; 277 | } 278 | *dp = NULL; 279 | pstats.s_hpt /= 2; 280 | cnt = pstats.s_hpt / cnt; 281 | /* 282 | * Now zot all of the monsters 283 | */ 284 | for (dp = drainee; *dp; dp++) 285 | { 286 | mp = *dp; 287 | if ((mp->t_stats.s_hpt -= cnt) <= 0) 288 | killed(mp, see_monst(mp)); 289 | else 290 | runto(&mp->t_pos); 291 | } 292 | } 293 | 294 | /* 295 | * fire_bolt: 296 | * Fire a bolt in a given direction from a specific starting place 297 | */ 298 | 299 | void 300 | fire_bolt(coord *start, coord *dir, char *name) 301 | { 302 | coord *c1, *c2; 303 | THING *tp; 304 | char dirch = 0, ch; 305 | bool hit_hero, used, changed; 306 | static coord pos; 307 | static coord spotpos[BOLT_LENGTH]; 308 | THING bolt; 309 | 310 | bolt.o_type = WEAPON; 311 | bolt.o_which = FLAME; 312 | strncpy(bolt.o_hurldmg,"6x6",sizeof(bolt.o_hurldmg)); 313 | bolt.o_hplus = 100; 314 | bolt.o_dplus = 0; 315 | weap_info[FLAME].oi_name = name; 316 | switch (dir->y + dir->x) 317 | { 318 | case 0: dirch = '/'; 319 | when 1: case -1: dirch = (dir->y == 0 ? '-' : '|'); 320 | when 2: case -2: dirch = '\\'; 321 | } 322 | pos = *start; 323 | hit_hero = (bool)(start != &hero); 324 | used = FALSE; 325 | changed = FALSE; 326 | for (c1 = spotpos; c1 <= &spotpos[BOLT_LENGTH-1] && !used; c1++) 327 | { 328 | pos.y += dir->y; 329 | pos.x += dir->x; 330 | *c1 = pos; 331 | ch = winat(pos.y, pos.x); 332 | switch (ch) 333 | { 334 | case DOOR: 335 | /* 336 | * this code is necessary if the hero is on a door 337 | * and he fires at the wall the door is in, it would 338 | * otherwise loop infinitely 339 | */ 340 | if (ce(hero, pos)) 341 | goto def; 342 | /* FALLTHROUGH */ 343 | case '|': 344 | case '-': 345 | case ' ': 346 | if (!changed) 347 | hit_hero = !hit_hero; 348 | changed = FALSE; 349 | dir->y = -dir->y; 350 | dir->x = -dir->x; 351 | c1--; 352 | msg("the %s bounces", name); 353 | break; 354 | default: 355 | def: 356 | if (!hit_hero && (tp = moat(pos.y, pos.x)) != NULL) 357 | { 358 | hit_hero = TRUE; 359 | changed = !changed; 360 | tp->t_oldch = chat(pos.y, pos.x); 361 | if (!save_throw(VS_MAGIC, tp)) 362 | { 363 | bolt.o_pos = pos; 364 | used = TRUE; 365 | if (tp->t_type == 'D' && strcmp(name, "flame") == 0) 366 | { 367 | addmsg("the flame bounces"); 368 | if (!terse) 369 | addmsg(" off the dragon"); 370 | endmsg(); 371 | } 372 | else 373 | hit_monster(unc(pos), &bolt); 374 | } 375 | else if (ch != 'M' || tp->t_disguise == 'M') 376 | { 377 | if (start == &hero) 378 | runto(&pos); 379 | if (terse) 380 | msg("%s misses", name); 381 | else 382 | msg("the %s whizzes past %s", name, set_mname(tp)); 383 | } 384 | } 385 | else if (hit_hero && ce(pos, hero)) 386 | { 387 | hit_hero = FALSE; 388 | changed = !changed; 389 | if (!save(VS_MAGIC)) 390 | { 391 | if ((pstats.s_hpt -= roll(6, 6)) <= 0) 392 | { 393 | if (start == &hero) 394 | death('b'); 395 | else 396 | death(moat(start->y, start->x)->t_type); 397 | } 398 | used = TRUE; 399 | if (terse) 400 | msg("the %s hits", name); 401 | else 402 | msg("you are hit by the %s", name); 403 | } 404 | else 405 | msg("the %s whizzes by you", name); 406 | } 407 | mvaddch(pos.y, pos.x, dirch); 408 | refresh(); 409 | } 410 | } 411 | for (c2 = spotpos; c2 < c1; c2++) 412 | mvaddch(c2->y, c2->x, chat(c2->y, c2->x)); 413 | } 414 | 415 | /* 416 | * charge_str: 417 | * Return an appropriate string for a wand charge 418 | */ 419 | char * 420 | charge_str(THING *obj) 421 | { 422 | static char buf[20]; 423 | 424 | if (!(obj->o_flags & ISKNOW)) 425 | buf[0] = '\0'; 426 | else if (terse) 427 | sprintf(buf, " [%d]", obj->o_charges); 428 | else 429 | sprintf(buf, " [%d charges]", obj->o_charges); 430 | return buf; 431 | } 432 | -------------------------------------------------------------------------------- /vers.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Version number. Whenever a new version number is desired, use sccs 3 | * to get vers.c. encstr is declared here to force it to be loaded 4 | * before the version number, and therefore not to be written in saved 5 | * games. 6 | * 7 | * Rogue: Exploring the Dungeons of Doom 8 | * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman 9 | * All rights reserved. 10 | * 11 | * See the file LICENSE.TXT for full copyright and licensing information. 12 | */ 13 | 14 | char *release = "5.4.4"; 15 | char encstr[] = "\300k||`\251Y.'\305\321\201+\277~r\"]\240_\223=1\341)\222\212\241t;\t$\270\314/<#\201\254"; 16 | char statlist[] = "\355kl{+\204\255\313idJ\361\214=4:\311\271\341wK<\312\321\213,,7\271/Rk%\b\312\f\246"; 17 | char version[] = "rogue (rogueforge) 09/05/07"; 18 | -------------------------------------------------------------------------------- /weapons.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Functions for dealing with problems brought about by weapons 3 | * 4 | * @(#)weapons.c 4.34 (Berkeley) 02/05/99 5 | * 6 | * Rogue: Exploring the Dungeons of Doom 7 | * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman 8 | * All rights reserved. 9 | * 10 | * See the file LICENSE.TXT for full copyright and licensing information. 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | #include "rogue.h" 17 | 18 | #define NO_WEAPON -1 19 | 20 | int group = 2; 21 | 22 | static struct init_weaps { 23 | char *iw_dam; /* Damage when wielded */ 24 | char *iw_hrl; /* Damage when thrown */ 25 | char iw_launch; /* Launching weapon */ 26 | int iw_flags; /* Miscellaneous flags */ 27 | } init_dam[MAXWEAPONS] = { 28 | { "2x4", "1x3", NO_WEAPON, 0, }, /* Mace */ 29 | { "3x4", "1x2", NO_WEAPON, 0, }, /* Long sword */ 30 | { "1x1", "1x1", NO_WEAPON, 0, }, /* Bow */ 31 | { "1x1", "2x3", BOW, ISMANY|ISMISL, }, /* Arrow */ 32 | { "1x6", "1x4", NO_WEAPON, ISMISL|ISMISL, }, /* Dagger */ 33 | { "4x4", "1x2", NO_WEAPON, 0, }, /* 2h sword */ 34 | { "1x1", "1x3", NO_WEAPON, ISMANY|ISMISL, }, /* Dart */ 35 | { "1x2", "2x4", NO_WEAPON, ISMANY|ISMISL, }, /* Shuriken */ 36 | { "2x3", "1x6", NO_WEAPON, ISMISL, }, /* Spear */ 37 | }; 38 | 39 | /* 40 | * missile: 41 | * Fire a missile in a given direction 42 | */ 43 | 44 | void 45 | missile(int ydelta, int xdelta) 46 | { 47 | THING *obj; 48 | 49 | /* 50 | * Get which thing we are hurling 51 | */ 52 | if ((obj = get_item("throw", WEAPON)) == NULL) 53 | return; 54 | if (!dropcheck(obj) || is_current(obj)) 55 | return; 56 | obj = leave_pack(obj, TRUE, FALSE); 57 | do_motion(obj, ydelta, xdelta); 58 | /* 59 | * AHA! Here it has hit something. If it is a wall or a door, 60 | * or if it misses (combat) the monster, put it on the floor 61 | */ 62 | if (moat(obj->o_pos.y, obj->o_pos.x) == NULL || 63 | !hit_monster(unc(obj->o_pos), obj)) 64 | fall(obj, TRUE); 65 | } 66 | 67 | /* 68 | * do_motion: 69 | * Do the actual motion on the screen done by an object traveling 70 | * across the room 71 | */ 72 | 73 | void 74 | do_motion(THING *obj, int ydelta, int xdelta) 75 | { 76 | int ch; 77 | 78 | /* 79 | * Come fly with us ... 80 | */ 81 | obj->o_pos = hero; 82 | for (;;) 83 | { 84 | /* 85 | * Erase the old one 86 | */ 87 | if (!ce(obj->o_pos, hero) && cansee(unc(obj->o_pos)) && !terse) 88 | { 89 | ch = chat(obj->o_pos.y, obj->o_pos.x); 90 | if (ch == FLOOR && !show_floor()) 91 | ch = ' '; 92 | mvaddch(obj->o_pos.y, obj->o_pos.x, ch); 93 | } 94 | /* 95 | * Get the new position 96 | */ 97 | obj->o_pos.y += ydelta; 98 | obj->o_pos.x += xdelta; 99 | if (step_ok(ch = winat(obj->o_pos.y, obj->o_pos.x)) && ch != DOOR) 100 | { 101 | /* 102 | * It hasn't hit anything yet, so display it 103 | * If it alright. 104 | */ 105 | if (cansee(unc(obj->o_pos)) && !terse) 106 | { 107 | mvaddch(obj->o_pos.y, obj->o_pos.x, obj->o_type); 108 | refresh(); 109 | } 110 | continue; 111 | } 112 | break; 113 | } 114 | } 115 | 116 | /* 117 | * fall: 118 | * Drop an item someplace around here. 119 | */ 120 | 121 | void 122 | fall(THING *obj, bool pr) 123 | { 124 | PLACE *pp; 125 | static coord fpos; 126 | 127 | if (fallpos(&obj->o_pos, &fpos)) 128 | { 129 | pp = INDEX(fpos.y, fpos.x); 130 | pp->p_ch = (char) obj->o_type; 131 | obj->o_pos = fpos; 132 | if (cansee(fpos.y, fpos.x)) 133 | { 134 | if (pp->p_monst != NULL) 135 | pp->p_monst->t_oldch = (char) obj->o_type; 136 | else 137 | mvaddch(fpos.y, fpos.x, obj->o_type); 138 | } 139 | attach(lvl_obj, obj); 140 | return; 141 | } 142 | if (pr) 143 | { 144 | if (has_hit) 145 | { 146 | endmsg(); 147 | has_hit = FALSE; 148 | } 149 | msg("the %s vanishes as it hits the ground", 150 | weap_info[obj->o_which].oi_name); 151 | } 152 | discard(obj); 153 | } 154 | 155 | /* 156 | * init_weapon: 157 | * Set up the initial goodies for a weapon 158 | */ 159 | 160 | void 161 | init_weapon(THING *weap, int which) 162 | { 163 | struct init_weaps *iwp; 164 | 165 | weap->o_type = WEAPON; 166 | weap->o_which = which; 167 | iwp = &init_dam[which]; 168 | strncpy(weap->o_damage, iwp->iw_dam, sizeof(weap->o_damage)); 169 | strncpy(weap->o_hurldmg,iwp->iw_hrl, sizeof(weap->o_hurldmg)); 170 | weap->o_launch = iwp->iw_launch; 171 | weap->o_flags = iwp->iw_flags; 172 | weap->o_hplus = 0; 173 | weap->o_dplus = 0; 174 | if (which == DAGGER) 175 | { 176 | weap->o_count = rnd(4) + 2; 177 | weap->o_group = group++; 178 | } 179 | else if (weap->o_flags & ISMANY) 180 | { 181 | weap->o_count = rnd(8) + 8; 182 | weap->o_group = group++; 183 | } 184 | else 185 | { 186 | weap->o_count = 1; 187 | weap->o_group = 0; 188 | } 189 | } 190 | 191 | /* 192 | * hit_monster: 193 | * Does the missile hit the monster? 194 | */ 195 | int 196 | hit_monster(int y, int x, THING *obj) 197 | { 198 | static coord mp; 199 | 200 | mp.y = y; 201 | mp.x = x; 202 | return fight(&mp, obj, TRUE); 203 | } 204 | 205 | /* 206 | * num: 207 | * Figure out the plus number for armor/weapons 208 | */ 209 | char * 210 | num(int n1, int n2, char type) 211 | { 212 | static char numbuf[10]; 213 | 214 | sprintf(numbuf, n1 < 0 ? "%d" : "+%d", n1); 215 | if (type == WEAPON) 216 | sprintf(&numbuf[strlen(numbuf)], n2 < 0 ? ",%d" : ",+%d", n2); 217 | return numbuf; 218 | } 219 | 220 | /* 221 | * wield: 222 | * Pull out a certain weapon 223 | */ 224 | 225 | void 226 | wield() 227 | { 228 | THING *obj, *oweapon; 229 | char *sp; 230 | 231 | oweapon = cur_weapon; 232 | if (!dropcheck(cur_weapon)) 233 | { 234 | cur_weapon = oweapon; 235 | return; 236 | } 237 | cur_weapon = oweapon; 238 | if ((obj = get_item("wield", WEAPON)) == NULL) 239 | { 240 | bad: 241 | after = FALSE; 242 | return; 243 | } 244 | 245 | if (obj->o_type == ARMOR) 246 | { 247 | msg("you can't wield armor"); 248 | goto bad; 249 | } 250 | if (is_current(obj)) 251 | goto bad; 252 | 253 | sp = inv_name(obj, TRUE); 254 | cur_weapon = obj; 255 | if (!terse) 256 | addmsg("you are now "); 257 | msg("wielding %s (%c)", sp, obj->o_packch); 258 | } 259 | 260 | /* 261 | * fallpos: 262 | * Pick a random position around the give (y, x) coordinates 263 | */ 264 | bool 265 | fallpos(coord *pos, coord *newpos) 266 | { 267 | int y, x, cnt, ch; 268 | 269 | cnt = 0; 270 | for (y = pos->y - 1; y <= pos->y + 1; y++) 271 | for (x = pos->x - 1; x <= pos->x + 1; x++) 272 | { 273 | /* 274 | * check to make certain the spot is empty, if it is, 275 | * put the object there, set it in the level list 276 | * and re-draw the room if he can see it 277 | */ 278 | if (y == hero.y && x == hero.x) 279 | continue; 280 | if (((ch = chat(y, x)) == FLOOR || ch == PASSAGE) 281 | && rnd(++cnt) == 0) 282 | { 283 | newpos->y = y; 284 | newpos->x = x; 285 | } 286 | } 287 | return (bool)(cnt != 0); 288 | } 289 | -------------------------------------------------------------------------------- /wizard.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Special wizard commands (some of which are also non-wizard commands 3 | * under strange circumstances) 4 | * 5 | * @(#)wizard.c 4.30 (Berkeley) 02/05/99 6 | * 7 | * Rogue: Exploring the Dungeons of Doom 8 | * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman 9 | * All rights reserved. 10 | * 11 | * See the file LICENSE.TXT for full copyright and licensing information. 12 | */ 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include "rogue.h" 19 | 20 | /* 21 | * whatis: 22 | * What a certin object is 23 | */ 24 | 25 | void 26 | whatis(bool insist, int type) 27 | { 28 | THING *obj; 29 | 30 | if (pack == NULL) 31 | { 32 | msg("you don't have anything in your pack to identify"); 33 | return; 34 | } 35 | 36 | for (;;) 37 | { 38 | obj = get_item("identify", type); 39 | if (insist) 40 | { 41 | if (n_objs == 0) 42 | return; 43 | else if (obj == NULL) 44 | msg("you must identify something"); 45 | else if (type && obj->o_type != type && 46 | !(type == R_OR_S && (obj->o_type == RING || obj->o_type == STICK)) ) 47 | msg("you must identify a %s", type_name(type)); 48 | else 49 | break; 50 | } 51 | else 52 | break; 53 | } 54 | 55 | if (obj == NULL) 56 | return; 57 | 58 | switch (obj->o_type) 59 | { 60 | case SCROLL: 61 | set_know(obj, scr_info); 62 | when POTION: 63 | set_know(obj, pot_info); 64 | when STICK: 65 | set_know(obj, ws_info); 66 | when WEAPON: 67 | case ARMOR: 68 | obj->o_flags |= ISKNOW; 69 | when RING: 70 | set_know(obj, ring_info); 71 | } 72 | msg(inv_name(obj, FALSE)); 73 | } 74 | 75 | /* 76 | * set_know: 77 | * Set things up when we really know what a thing is 78 | */ 79 | 80 | void 81 | set_know(THING *obj, struct obj_info *info) 82 | { 83 | char **guess; 84 | 85 | info[obj->o_which].oi_know = TRUE; 86 | obj->o_flags |= ISKNOW; 87 | guess = &info[obj->o_which].oi_guess; 88 | if (*guess) 89 | { 90 | free(*guess); 91 | *guess = NULL; 92 | } 93 | } 94 | 95 | /* 96 | * type_name: 97 | * Return a pointer to the name of the type 98 | */ 99 | char * 100 | type_name(int type) 101 | { 102 | struct h_list *hp; 103 | static struct h_list tlist[] = { 104 | {POTION, "potion", FALSE}, 105 | {SCROLL, "scroll", FALSE}, 106 | {FOOD, "food", FALSE}, 107 | {R_OR_S, "ring, wand or staff", FALSE}, 108 | {RING, "ring", FALSE}, 109 | {STICK, "wand or staff", FALSE}, 110 | {WEAPON, "weapon", FALSE}, 111 | {ARMOR, "suit of armor", FALSE}, 112 | }; 113 | 114 | for (hp = tlist; hp->h_ch; hp++) 115 | if (type == hp->h_ch) 116 | return hp->h_desc; 117 | /* NOTREACHED */ 118 | return(0); 119 | } 120 | 121 | #ifdef MASTER 122 | /* 123 | * create_obj: 124 | * wizard command for getting anything he wants 125 | */ 126 | 127 | void 128 | create_obj() 129 | { 130 | THING *obj; 131 | char ch, bless; 132 | 133 | obj = new_item(); 134 | msg("type of item: "); 135 | obj->o_type = readchar(); 136 | mpos = 0; 137 | msg("which %c do you want? (0-f)", obj->o_type); 138 | obj->o_which = (isdigit((ch = readchar())) ? ch - '0' : ch - 'a' + 10); 139 | obj->o_group = 0; 140 | obj->o_count = 1; 141 | mpos = 0; 142 | if (obj->o_type == WEAPON || obj->o_type == ARMOR) 143 | { 144 | msg("blessing? (+,-,n)"); 145 | bless = readchar(); 146 | mpos = 0; 147 | if (bless == '-') 148 | obj->o_flags |= ISCURSED; 149 | if (obj->o_type == WEAPON) 150 | { 151 | init_weapon(obj, obj->o_which); 152 | if (bless == '-') 153 | obj->o_hplus -= rnd(3)+1; 154 | if (bless == '+') 155 | obj->o_hplus += rnd(3)+1; 156 | } 157 | else 158 | { 159 | obj->o_arm = a_class[obj->o_which]; 160 | if (bless == '-') 161 | obj->o_arm += rnd(3)+1; 162 | if (bless == '+') 163 | obj->o_arm -= rnd(3)+1; 164 | } 165 | } 166 | else if (obj->o_type == RING) 167 | switch (obj->o_which) 168 | { 169 | case R_PROTECT: 170 | case R_ADDSTR: 171 | case R_ADDHIT: 172 | case R_ADDDAM: 173 | msg("blessing? (+,-,n)"); 174 | bless = readchar(); 175 | mpos = 0; 176 | if (bless == '-') 177 | obj->o_flags |= ISCURSED; 178 | obj->o_arm = (bless == '-' ? -1 : rnd(2) + 1); 179 | when R_AGGR: 180 | case R_TELEPORT: 181 | obj->o_flags |= ISCURSED; 182 | } 183 | else if (obj->o_type == STICK) 184 | fix_stick(obj); 185 | else if (obj->o_type == GOLD) 186 | { 187 | msg("how much?"); 188 | get_num(&obj->o_goldval, stdscr); 189 | } 190 | add_pack(obj, FALSE); 191 | } 192 | #endif 193 | 194 | /* 195 | * telport: 196 | * Bamf the hero someplace else 197 | */ 198 | 199 | void 200 | teleport() 201 | { 202 | static coord c; 203 | 204 | mvaddch(hero.y, hero.x, floor_at()); 205 | find_floor((struct room *) NULL, &c, FALSE, TRUE); 206 | if (roomin(&c) != proom) 207 | { 208 | leave_room(&hero); 209 | hero = c; 210 | enter_room(&hero); 211 | } 212 | else 213 | { 214 | hero = c; 215 | look(TRUE); 216 | } 217 | mvaddch(hero.y, hero.x, PLAYER); 218 | /* 219 | * turn off ISHELD in case teleportation was done while fighting 220 | * a Flytrap 221 | */ 222 | if (on(player, ISHELD)) { 223 | player.t_flags &= ~ISHELD; 224 | vf_hit = 0; 225 | strcpy(monsters['F'-'A'].m_stats.s_dmg, "000x0"); 226 | } 227 | no_move = 0; 228 | count = 0; 229 | running = FALSE; 230 | flush_type(); 231 | } 232 | 233 | #ifdef MASTER 234 | /* 235 | * passwd: 236 | * See if user knows password 237 | */ 238 | int 239 | passwd() 240 | { 241 | char *sp, c; 242 | static char buf[MAXSTR]; 243 | 244 | msg("wizard's Password:"); 245 | mpos = 0; 246 | sp = buf; 247 | while ((c = readchar()) != '\n' && c != '\r' && c != ESCAPE) 248 | if (c == md_killchar()) 249 | sp = buf; 250 | else if (c == md_erasechar() && sp > buf) 251 | sp--; 252 | else 253 | *sp++ = c; 254 | if (sp == buf) 255 | return FALSE; 256 | *sp = '\0'; 257 | return (strcmp(PASSWD, md_crypt(buf, "mT")) == 0); 258 | } 259 | 260 | /* 261 | * show_map: 262 | * Print out the map for the wizard 263 | */ 264 | 265 | void 266 | show_map() 267 | { 268 | int y, x, real; 269 | 270 | wclear(hw); 271 | for (y = 1; y < NUMLINES - 1; y++) 272 | for (x = 0; x < NUMCOLS; x++) 273 | { 274 | real = flat(y, x); 275 | if (!(real & F_REAL)) 276 | wstandout(hw); 277 | wmove(hw, y, x); 278 | waddch(hw, chat(y, x)); 279 | if (!real) 280 | wstandend(hw); 281 | } 282 | show_win("---More (level map)---"); 283 | } 284 | #endif 285 | --------------------------------------------------------------------------------