changeset 63:0ed67132cf10

Import Advanced Rogue 5.8 from the Roguelike Restoration Project (r1490)
author elwin
date Thu, 09 Aug 2012 22:58:48 +0000
parents 0ef99244acb8
children a98834ce7e04
files arogue5/LICENSE.TXT arogue5/Makefile arogue5/arogue58.doc arogue5/arogue58.html arogue5/arogue58.sln arogue5/arogue58.vcproj arogue5/chase.c arogue5/command.c arogue5/daemon.c arogue5/daemons.c arogue5/encumb.c arogue5/fight.c arogue5/init.c arogue5/io.c arogue5/list.c arogue5/mach_dep.h arogue5/main.c arogue5/maze.c arogue5/mdport.c arogue5/misc.c arogue5/monsters.c arogue5/move.c arogue5/network.h arogue5/new_level.c arogue5/options.c arogue5/outside.c arogue5/pack.c arogue5/passages.c arogue5/player.c arogue5/potions.c arogue5/rings.c arogue5/rip.c arogue5/rogue.c arogue5/rogue.h arogue5/rooms.c arogue5/save.c arogue5/scrolls.c arogue5/state.c arogue5/sticks.c arogue5/things.c arogue5/trader.c arogue5/util.c arogue5/vers.c arogue5/weapons.c arogue5/wear.c arogue5/wizard.c arogue5/xcrypt.c
diffstat 47 files changed, 29836 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/LICENSE.TXT	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,178 @@
+Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+Portions Copyright (C) 1984 Robert D. Kindelberger
+Portions Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+Portions Copyright (C) 2005 Nicholas J. Kisseberth
+Portions Copyright (C) 1994 David Burren
+All rights reserved.
+
+===========================================================================
+
+Advanced Rogue
+Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T 
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name(s) of the author(s) nor the names of other contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+4. The name "Advanced Rogue" and "ARogue" must not be used to endorse or 
+   promote products derived from this software without prior written 
+   permission.
+5. Products derived from this software may not be called "Advanced Rogue" or
+   "ARogue", nor may "Advanced Rogue" or "ARogue appear in their name, 
+   without prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+===========================================================================
+
+Portions of this software are based on the work of Robert D. Kindelberger.
+Used under license:
+
+Super-Rogue
+Copyright (C) 1984 Robert D. Kindelberger
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name(s) of the author(s) nor the names of other contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+4. The name "Super-Rogue" must not be used to endorse or promote products
+   derived from this software without prior written permission.
+5. Products derived from this software may not be called "Super-Rogue",
+   nor may "Super-Rogue" appear in their name, without prior written
+   permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+===========================================================================
+
+Portions of this software are based on the work of Michael Toy, Ken Arnold
+and Glenn Wichman. Used under license:
+
+Rogue: Exploring the Dungeons of Doom
+Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name(s) of the author(s) nor the names of other contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+===========================================================================
+
+Portions of this software (save/restore game state) are based on the work 
+of Nicholas J. Kisseberth. Used under license:
+
+Copyright (C) 2005 Nicholas J. Kisseberth
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name(s) of the author(s) nor the names of other contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+===========================================================================
+
+Portions of this software (encryption) are based on the work 
+of David Burren. Used under license:
+
+FreeSec: libcrypt
+
+Copyright (C) 1994 David Burren
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name(s) of the author(s) nor the names of other contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/Makefile	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,203 @@
+#
+# Makefile for rogue
+#
+# Advanced Rogue
+# Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+# All rights reserved.
+#
+# Based on "Rogue: Exploring the Dungeons of Doom"
+# Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+# All rights reserved.
+#
+# See the file LICENSE.TXT for full copyright and licensing information.
+#
+
+DISTNAME=arogue5.8.2
+PROGRAM=arogue58
+
+O=o
+
+HDRS  = rogue.h mach_dep.h network.h
+OBJS1 = chase.$(O) command.$(O) daemon.$(O) daemons.$(O) encumb.$(O) \
+        fight.$(O) init.$(O) io.$(O) list.$(O) main.$(O) maze.$(O) mdport.$(O)\
+        misc.$(O) monsters.$(O) move.$(O) new_level.$(O) options.$(O) \
+	outside.$(O) 
+OBJS2 = pack.$(O) passages.$(O) player.$(O) potions.$(O) rings.$(O) rip.$(O) \
+        rogue.$(O) rooms.$(O) save.$(O) scrolls.$(O) state.$(O) sticks.$(O) \
+        things.$(O) trader.$(O) util.$(O) vers.$(O) weapons.$(O) wear.$(O) \
+        wizard.$(O) xcrypt.$(O)
+OBJS  = $(OBJS1) $(OBJS2)
+CFILES= \
+      vers.c chase.c command.c daemon.c daemons.c encumb.c \
+      fight.c init.c io.c list.c main.c maze.c mdport.c misc.c monsters.c \
+      move.c new_level.c options.c outside.c pack.c passages.c player.c \
+      potions.c rings.c rip.c rogue.c \
+      rooms.c save.c scrolls.c state.c sticks.c things.c trader.c util.c \
+      weapons.c wear.c wizard.c xcrypt.c
+
+MISC=	Makefile LICENSE.TXT arogue58.sln arogue58.vcproj
+DOCS= arogue58.doc arogue58.html
+
+CC    = gcc
+CFLAGS= -g
+CRLIB = -lcurses
+RM    = rm -f
+TAR   = tar
+.SUFFIXES: .obj
+
+.c.obj:
+	$(CC) $(CFLAGS) /c $*.c
+
+$(PROGRAM): $(OBJS)
+	$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(CRLIB) -o $@
+
+tags: $(HDRS) $(CFILES)
+	ctags -u $?
+	ed - tags < :ctfix
+	sort tags -o tags
+
+lint:
+	lint -hxbc $(CFILES) $(CRLIB) > linterrs
+
+clean:
+	$(RM) $(OBJS1)
+	$(RM) $(OBJS2)
+	$(RM) core a.exe a.out a.exe.stackdump $(PROGRAM) $(PROGRAM).exe $(PROGRAM).tar $(PROGRAM).tar.gz $(PROGRAM).zip
+
+count:
+	wc -l $(HDRS) $(CFILES)
+
+realcount:
+	cc -E $(CFILES) | ssp - | wc -l
+
+update:
+	ar uv .SAVE $(CFILES) $(HDRS) $(MISC)
+
+dist:
+	@mkdir dist
+	cp $(CFILES) $(HDRS) $(MISC) dist
+
+dist.src:
+	make clean
+	tar cf $(DISTNAME)-src.tar $(CFILES) $(HDRS) $(MISC) $(DOCS)
+	gzip -f $(DISTNAME)-src.tar
+
+dist.irix:
+	make clean
+	make CC=cc CFLAGS="-woff 1116 -O3" $(PROGRAM)
+	tar cf $(DISTNAME)-irix.tar $(PROGRAM) LICENSE.TXT $(DOCS)
+	gzip -f $(DISTNAME)-irix.tar
+
+dist.aix:
+	make clean
+	make CC=xlc CFLAGS="-qmaxmem=16768 -O3 -qstrict" $(PROGRAM)
+	tar cf $(DISTNAME)-aix.tar $(PROGRAM) LICENSE.TXT $(DOCS)
+	gzip -f $(DISTNAME)-aix.tar
+
+debug.linux:
+	make clean
+	make CFLAGS="-g -DWIZARD" $(PROGRAM)
+
+dist.linux:
+	make clean
+	make $(PROGRAM)
+	tar cf $(DISTNAME)-linux.tar $(PROGRAM) LICENSE.TXT $(DOCS)
+	gzip -f $(DISTNAME)-linux.tar
+	
+debug.interix: 
+	make clean
+	make CFLAGS="-g3 -DWIZARD" $(PROGRAM)
+	
+dist.interix: 
+	make clean
+	make $(PROGRAM)
+	tar cf $(DISTNAME)-interix.tar $(PROGRAM) LICENSE.TXT $(DOCS)
+	gzip -f $(DISTNAME)-interix.tar
+	
+debug.cygwin:
+	make clean
+	make CFLAGS="-g3 -DWIZARD" $(PROGRAM)
+
+dist.cygwin:
+	make clean
+	make CRLIB="-static -lcurses" $(PROGRAM)
+	tar cf $(DISTNAME)-cygwin.tar $(PROGRAM).exe LICENSE.TXT $(DOCS)
+	gzip -f $(DISTNAME)-cygwin.tar
+
+#
+# Use MINGW32-MAKE to build this target
+#
+dist.mingw32:
+	@$(MAKE) --no-print-directory RM="cmd /c del" clean
+	@$(MAKE) --no-print-directory CRLIB="-lpdcurses" $(PROGRAM)
+	cmd /c del $(DISTNAME)-mingw32.zip
+	zip $(DISTNAME)-mingw32.zip $(PROGRAM).exe LICENSE.TXT $(DOCS)
+	
+dist.msys:
+	@$(MAKE) --no-print-directory clean
+	@$(MAKE) --no-print-directory CRLIB="-lcurses" $(PROGRAM)
+	tar cf $(DISTNAME)-msys.tar $(PROGRAM).exe LICENSE.TXT $(DOCS)
+	gzip -f $(DISTNAME)-msys.tar
+	
+debug.djgpp: 
+	make clean
+	make CFGLAGS="-g3 -DWIZARD" LDFLAGS="-L$(DJDIR)/LIB" CRLIB="-lpdcurses" $(PROGRAM)
+
+dist.djgpp: 
+	make clean
+	make LDFLAGS="-L$(DJDIR)/LIB" CRLIB="-lpdcurses" $(PROGRAM)
+	rm -f $(DISTNAME)-djgpp.zip
+	zip $(DISTNAME)-djgpp.zip $(PROGRAM).exe LICENSE.TXT $(DOCS)
+
+#
+# Use NMAKE to build this target
+#
+
+debug.win32:
+	nmake O="obj" RM="-del" clean
+	nmake O="obj" CC="CL" CRLIB="..\pdcurses\pdcurses.lib shfolder.lib user32.lib Advapi32.lib" CFLAGS="-DWIZARD -nologo -I..\pdcurses -Ox -wd4033 -wd4716" $(PROGRAM)
+
+dist.win32:
+	nmake O="obj" RM="-del" clean
+	nmake O="obj" CC="CL" CRLIB="..\pdcurses\pdcurses.lib shfolder.lib user32.lib Advapi32.lib" CFLAGS="-nologo -I..\pdcurses -Ox -wd4033 -wd4716" $(PROGRAM)
+	-del $(DISTNAME)-win32.zip
+	zip $(DISTNAME)-win32.zip $(PROGRAM).exe LICENSE.TXT $(DOCS)
+
+vers.$(O): vers.c rogue.h
+chase.$(O): chase.c rogue.h
+command.$(O): command.c rogue.h
+daemon.$(O): daemon.c rogue.h
+daemons.$(O): daemons.c rogue.h
+encumb.$(O): encumb.c rogue.h
+fight.$(O): fight.c rogue.h
+init.$(O): init.c rogue.h
+io.$(O): io.c rogue.h
+list.$(O): list.c rogue.h
+main.$(O): main.c rogue.h
+maze.$(O): maze.c rogue.h
+misc.$(O): misc.c rogue.h
+monsters.$(O): monsters.c rogue.h
+move.$(O): move.c rogue.h
+new_level.$(O): new_level.c rogue.h
+options.$(O): options.c rogue.h
+outside.$(O): outside.c rogue.h
+pack.$(O): pack.c rogue.h
+passages.$(O): passages.c rogue.h
+player.$(O): player.c rogue.h
+potions.$(O): potions.c rogue.h
+rings.$(O): rings.c rogue.h
+rip.$(O): rip.c rogue.h
+rogue.$(O): rogue.c rogue.h
+rooms.$(O): rooms.c rogue.h
+save.$(O): save.c rogue.h
+scrolls.$(O): scrolls.c rogue.h
+state.$(O): state.c rogue.h
+sticks.$(O): sticks.c rogue.h
+things.$(O): things.c rogue.h
+trader.$(O): trader.c rogue.h
+util.$(O): util.c rogue.h
+weapons.$(O): weapons.c rogue.h
+wear.$(O): wear.c rogue.h
+wizard.$(O): wizard.c rogue.h
+xcrypt.$(O): xcrypt.c
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/arogue58.doc	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,1025 @@
+
+
+
+
+
+			   The Dungeons	of Doom
+
+			  AT&T Bell Laboratories
+			   The Dungeons	of Doom
+
+
+       1.  INTRODUCTION
+
+	    Rogue is a screen-oriented fantasy game set	in the
+       ever-changing Dungeons of Doom.	The game comes complete
+       with monsters, spells, weapons, armor, potions, and other
+       magical items.  The dungeon's geography changes with every
+       game, and although many magical items have certain
+       identifiable properties,	such as	turning	the player
+       invisible, the physical manifestation of	the magic changes
+       each game.  A red potion, for example, will cause the same
+       reaction	throughout a given game, but it	may be a completely
+       different potion	in a new game.
+
+	    Entering the dungeon with only a little food, armor,
+       and a weapon, the player	must develop a good strategy of
+       when to fight, when to run, and how to best use any magical
+       items found in the dungeon.  To make things interesting,	the
+       player has a quest to return one	of several unique
+       artifacts, rumored to lie deep in the dungeon's bowels.
+       Returning with this artifact brings great glory and the
+       title of	Complete Winner.  But even after finding the
+       artifact, the player may	wish to	continue further to match
+       wits with an arch-devil,	demon prince, or even a	deity found
+       far down	in the dungeon.	 Defeating such	a creature will
+       gain the	player many experience points, the basis for
+       scoring in Rogue.
+
+	    It is very difficult to return from	the Dungeons of
+       Doom.  Few people ever make it out alive.  Should this
+       unlikely	event occur, the player	would be proclaimed a
+       complete	winner and handsomely rewarded for any booty
+       removed from the	dungeon.
+
+
+       2.  CHARACTER CLASSES AND ATTRIBUTES
+
+	    Before placing the player in the dungeon, the game
+       requests	the player to select a character class:	 a fighter,
+       a magic user, a cleric, or a thief.
+
+       2.1  The_Fighter
+
+	    A fighter is very strong and will have a high strength
+       rating.	This great strength gives a fighter the	best odds
+       of winning a battle with	a monster.  At high experience
+       levels the fighter also gets to attack multiple times in	a
+       single turn.  This obviously further increases his chances
+       at winning battles.  Intrinsic to the fighter class is a
+       robustness which	results	in 1 to	10 extra hit points for
+
+
+
+
+
+
+
+
+
+
+
+				  - 2 -
+
+
+
+       every new experience level.
+
+       2.2  The_Magician
+
+	    A magician's major attribute is intelligence, which
+       enables the magician to cast spells.  The number	and variety
+       of spells increases as the magician gains experience and
+       intelligence.  Other types of characters	can cast spells,
+       but only	if they	manage to gain extraordinarily high
+       intelligence.  Magic users are not as hearty as fighters;
+       they receive 1 to 8 extra hit points for	every new
+       experience level.
+
+       2.3  The_Cleric
+
+	    A cleric has a high	wisdom rating and can thus pray.
+       The number and variety of prayers which the gods	are willing
+       to grant	to a cleric increase as	the cleric gains experience
+       and wisdom.  Other character types can pray only	if they
+       manage to gain extraordinary wisdom.
+
+	    Because of their religious nature, clerics can also
+       affect the "undead" beings, like	zombies	and ghouls, which
+       became monsters after they died.	 If an "undead"	creature is
+       next to a cleric, the cleric may	try to turn it and cause it
+       to flee.	 If the	cleric is sufficiently powerful	relative to
+       the monster, the	cleric will destroy it.	 This ability
+       increases as the	character gains	experience levels.
+
+	    Clerics can	gain from 1 to 8 extra hit points on
+       reaching	a new experience level.
+
+       2.4  The_Thief
+
+	    A thief is exceptionally dextrous and has a	good chance
+       to set a	trap or	rob a monster.	Any type of character can
+       try to set a trap or steal from a monster standing next to
+       the character, but the chances of success are low compared
+       to a thief's chances.
+
+	    By their nature, thieves can automatically detect all
+       the gold	on the current level of	the dungeon.  They are also
+       good at detecting hidden	traps.	Because	thieves	slink
+       along, they are not as likely as	other characters to wake
+       sleeping	monsters.  If a	thief manages to sneak up on a
+       creature	without	waking it, he will get a chance	to backstab
+       the monster. When this is done, the damage done by the thief
+       greatly increases based on his experience level.
+
+	    Thieves gain from 1	to 6 extra hit points from a new
+       experience level.
+
+
+
+
+
+
+
+
+
+
+
+				  - 3 -
+
+
+
+       2.5  Constitution
+
+	    Every character has	a constitution rating.	A character
+       with an exceptionally good constitution will gain more than
+       the normal amount of hit	points associated with the
+       character's class when the character reaches a new
+       experience level. Exceptional constitution also provides
+       better protection versus	poison-based attacks and diseases.
+
+       2.6  Experience_Levels
+
+	    Characters gain experience for killing monsters,
+       stealing	from monsters, and turning monsters.  Each
+       character class has a set of thresholds associated with it.
+       When a character	reaches	a threshold, the character attains
+       the next	experience level.  This	new level brings extra hit
+       points and a greater chance of success in performing the
+       abilities associated with the character's class.	 Magicians
+       receive new spells, and clerics receive new prayers.
+
+	    Thieves have the lowest threshold for gaining
+       experience levels, followed by clerics.	Fighters are next,
+       and magicians have the highest threshold.
+
+
+       3.  THE SCREEN
+
+	    During the normal course of	play, the screen consists
+       of three	separate sections:  the	top line of the	terminal,
+       the bottom two lines of the terminal, and the remaining
+       middle lines.  The top line reports actions which occur
+       during the game,	the middle section depicts the dungeon,	and
+       the bottom lines	describe the player's current condition.
+
+       3.1  The_Top_Line
+
+	    Whenever anything happens to the player, such as
+       finding a scroll	or hitting or being hit	by a monster, a
+       short report of the occurrence appears on the top line of
+       the screen.  When such reports occur quickly, one right
+       after another, the game displays	the notice followed by the
+       prompt '--More--.'  After reading this notice, the player
+       can press a space to display the	next message.  At such a
+       point, the game ignores all commands until the player
+       presses a space.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+				  - 4 -
+
+
+
+       3.2  The_Dungeon_Section
+
+	    The	large middle section of	the screen displays the
+       player's	surroundings using the following symbols:
+
+       |	 A wall	of a room.
+
+       -	 A wall	of a room.
+
+       *	 A pile	of gold.
+
+       %	 A way to the next level.
+
+       +	 A doorway.
+
+       .	 The floor in a	room.
+
+       @	 The player.
+
+       _	 The player, when invisible.
+
+       #	 The floor in a	passageway.
+
+       !	 A flask containing a potion.
+
+       ?	 A sealed scroll.
+
+       :	 Some food.
+
+       )	 A weapon.
+
+		 Solid rock (denoted by	a space).
+
+       ]	 Some armor.
+
+       ;	 A miscellaneous magic item
+
+       ,	 An artifact
+
+       =	 A ring.
+
+       /	 A wand	or a staff.
+
+       ^	 The entrance to a trading post
+
+       >	 A trapdoor leading to the next	level
+
+       {	 An arrow trap
+
+       $	 A sleeping gas	trap
+
+
+
+
+
+
+
+
+
+
+
+
+				  - 5 -
+
+
+
+       }	 A beartrap
+
+       ~	 A trap	that teleports you somewhere else
+
+       `	 A poison dart trap
+
+       "	 A shimmering magic pool
+
+       '	 An entrance to	a maze
+
+       $	 Any magical item. (During magic detection)
+
+       >	 A blessed magical item. (During magic detection)
+
+       <	 A cursed magical item.	(During	magic detection)
+
+       A letter	 A monster.  Note that a given letter may signify
+		 multiple monsters, depending on the level of the
+		 dungeon.  The player can always identify a current
+		 monster by using the identify command ('/').
+
+       3.3  The_Status_Section
+
+	    The	bottom two lines of the	screen describe	the
+       player's	current	status.	 The first line	gives the player's
+       characteristics:
+
+	  o Intelligence (Int)
+
+	  o Strength (Str)
+
+	  o Wisdom (Wis)
+
+	  o Dexterity (Dxt)
+
+	  o Constitution (Const)
+
+	  o Encumbrance (Carry)
+
+	    Intelligence, strength, wisdom, dexterity, and
+       constitution have a normal maximum of 25, but can be higher
+       when augmented by a ring.  Encumbrance is a measurement	of
+       how much	the player can carry versus how	much he	is
+       currently carrying. The more you	carry relative to your
+       maximum causes you to use more food.
+
+	    The	second status line provides the	following
+       information:
+
+	  o The	current	level (Lvl) in the dungeon.  This number
+	    increases as the player goes further down.
+
+
+
+
+
+
+
+
+
+
+
+				  - 6 -
+
+
+
+	  o How	much gold (Au) the player is carrying.
+
+	  o The	player's current number	of hit points (Hp),
+	    followed in	parentheses by the player's current maximum
+	    number of hit points.  Hit points express the player's
+	    health.  As	a player heals by resting, the player's
+	    current hit	points gradually increase until	reaching
+	    the	current	maximum.  This maximum increases each time
+	    a player attains a new experience level.  If the
+	    player's current hit points	reach 0, the player dies.
+
+	  o The	player's armor class (Ac).  This number	describes
+	    the	amount of protection provided by the armor and
+	    rings currently worn by the	player.	 Wearing no armor
+	    is equivalent to an	armor class of 10.  The	protection
+	    level increases as the armor class decreases.
+
+	  o The	player's current experience level (Exp)	followed by
+	    the	player's experience points.  The player	can gain
+	    experience points by killing monsters, successfully
+	    stealing from monsters, and	turning	monsters.  When	a
+	    player gains enough	experience points to surpass a
+	    threshold that depends on the player's character type,
+	    the	player reaches a new experience	level.	A new
+	    experience level brings extra hit points and possibly
+	    added abilities, such as a new spell for a magician	or
+	    a new prayer for a cleric.
+
+	  o A description of the player's character.  This
+	    description	depends	on the player's	character type and
+	    experience level.
+
+
+       4.  COMMANDS
+
+	    A player can invoke	most Rogue commands by typing a
+       single character.  Some commands, however, require a
+       direction, in which case	the player types the command
+       character followed by a directional command.  Many commands
+       can be prefaced by a number, indicating how many	times the
+       command should be executed.
+
+	    When the player invokes a command referring	to an item
+       in the player's pack (such as reading a scroll),	the game
+       prompts for the item.  The player should	then type the
+       letter associated with the item,	as displayed by	the
+       inventory command.  Typing a '*'	at this	point produces a
+       list of the eligible items.
+
+	    Rogue understands the following commands:
+
+
+
+
+
+
+
+
+
+
+
+
+				  - 7 -
+
+
+
+       ?   Preceding a command by a '?'	produces a brief
+	   explanation of the command.	The command '?*' gives an
+	   explanation of all the commands.
+
+       /   Preceding a symbol by a '/' identifies the symbol.
+
+       h   Move	one position to	the left.
+
+       j   Move	one position down.
+
+       k   Move	one position up.
+
+       l   Move	one position to	the right.
+
+       y   Move	one position to	the top	left.
+
+       u   Move	one position to	the top	right.
+
+       b   Move	one position to	the bottom left.
+
+       n   Move	one position to	the bottom right.
+
+       H   Run to the left until reaching something interesting.
+
+       J   Run down until reaching something interesting.
+
+       K   Run up until	reaching something interesting.
+
+       L   Run to the right until reaching something interesting.
+
+       Y   Run to the top left until reaching something
+	   interesting.
+
+       U   Run to the top right	until reaching something
+	   interesting.
+
+       B   Run to the bottom left until	reaching something
+	   interesting.
+
+       N   Run to the bottom right until reaching something
+	   interesting.
+
+       t   This	command, followed by a directional command, prompts
+	   for an object from the players pack.	 The player then
+	   throws the object in	the specified direction.
+
+       f   When	this command precedes a	directional command, the
+	   player moves	in the specified direction until passing
+	   something interesting.
+
+
+
+
+
+
+
+
+
+
+
+
+
+				  - 8 -
+
+
+
+       z   This	command	must be	followed by a directional command.
+	   Rogue then prompts for a wand or staff from the player's
+	   pack	and zaps it in the specified direction.
+
+       >   Go down to the next level.
+
+       <   Go up to the	next level.
+
+       s   Search for a	secret door or a trap in the circle
+	   surrounding the player.
+
+       .   This	command	(a dot)	causes the player to rest a turn.
+
+       i   Display an inventory	of the player's	pack.
+
+       I   This	command	prompts	for an item from the player's pack
+	   and displays	the inventory information for that item.
+
+       q   Quaff a potion from the player's pack.
+
+       r   Read	a scroll from the player's pack.
+
+       e   Eat some food from the player's pack.
+
+       w   Wield a weapon from the player's pack.
+
+       W   Wear	some armor or miscellaneous magic item from the
+	   player's pack.
+
+       T   Take	off whatever the player	is wearing.
+
+       P   Put on a ring from the player's pack.  The player can
+	   wear	a maximum of eight rings.
+
+       R   Remove a ring from the player's hand.
+
+       ^U  Uuse	a miscellaneous	magic item in the player's pack.
+
+       d   Drop	an item	from the player's pack.
+
+       c   When	the player types this command, Rogue prompts for an
+	   item	from the player's pack and a one-line name.  Rogue
+	   then	calls all similar items	(such as all the blue
+	   potions) by the specified name.
+
+       m   When	the player types this command, Rogue prompts for an
+	   item	from the player's pack and a one-line name.  Rogue
+	   then	marks the specified item with the given	name.
+
+       o   Typing this command causes Rogue to display all the
+	   settable options.  The player can then merely examine
+
+
+
+
+
+
+
+
+
+
+
+				  - 9 -
+
+
+
+	   the options or change any or	all of them.
+
+       C   This	command, restricted to magicians and characters
+	   with	exceptionally high intelligence, produces a listing
+	   of the magician's current supply of spells.	The player
+	   can select one of the displayed spells and, if the
+	   player's energy level is sufficiently high, cast it.
+	   The more complicated	the spell, the more energy it
+	   takes.
+
+       p   This	command, restricted to clerics and characters with
+	   exceptionally high wisdom, produces a listing of the
+	   cleric's known prayers.  The	player can then	offer one
+	   of these prayers to the character's deity.  Deities are
+	   not known for favoring characters which continually pray
+	   to them, and	they are most likely to	answer the least
+	   "ambitious" prayers.
+
+       a   This	command	is restricted to clerics and characters
+	   with	exceptionally high wisdom and must be followed by a
+	   directional command.	 If there is an	"undead" monster
+	   standing next to the	player in the specified	direction,
+	   there is a chance the player	will affect the	monster	by
+	   causing it to flee or possibly even destroying it.
+
+       ^   This	command	sets a trap and	is most	likely to succeed
+	   for a character with	a high dexterity, such as a thief.
+	   If the character is successful, Rogue prompts the player
+	   for a type of trap and sets it where	the player is
+	   standing.
+
+       G   This	command	is restricted to thieves.  It causes Rogue
+	   to display all the gold on the current level.
+
+       D   Dip something into a	magic pool.
+
+       ^T  This	command	is most	likely to succeed for a	character
+	   with	a high dexterity, such as a thief, and it must be
+	   followed by a directional command.  If there	is a
+	   monster standing next to the	player in the specified
+	   direction, the player tries to steal	an item	from the
+	   monster's pack.  If the player is successful, the
+	   monster does	not notice anything, but if the	player is
+	   unsuccessful, there is a chance the monster will wake
+	   up.
+
+       ^L  Redraw the screen.
+
+       ^R  Repeat the last message that	was displayed on the top
+	   line	of the screen.
+
+
+
+
+
+
+
+
+
+
+
+
+				  - 10 -
+
+
+
+       ^[  Typing an escape will usually cause Rogue to	cancel the
+	   current command.
+
+       v   Print the current Rogue version number.
+
+       !   Escape to the shell.
+
+       S   Quit	and save the game for resumption at a later time.
+
+       Q   Quit	without	saving the game.
+
+
+       5.  IMPLICIT COMMANDS
+
+	    There is no	"attack" command.  If a	player wishes to
+       attack a	monster, the player simply tries to move onto the
+       spot where the monster is standing.  The	game then assumes
+       that the	player wishes to attack	the monster with whatever
+       weapon the player is wielding.
+
+	    When the player moves onto an item,	the game
+       automatically places the	object into the	player's pack.	If
+       there is	no room	left in	the pack, the game announces that
+       fact and	leaves the item	on the floor.
+
+
+       6.  LIGHT
+
+	    Some rooms in the dungeon possess a	natural	light
+       source.	In other rooms and in corridors	the player can see
+       only those things within	a one space radius from	the player.
+       These dark rooms	can be lit with	magical	light or by a fire
+       beetle.
+
+
+       7.  WEAPONS AND ARMOR
+
+	    The	player can wield exactly one weapon at a time.
+       When the	player attacks a monster, the amount of	damage
+       depends on the particular weapon	the player is wielding.	 To
+       fire a projectile weapon, such as a crossbow or a short bow,
+       the player should wield the bow and "throw" the bolt or
+       arrow at	the monster.
+
+	    A weapon may be cursed or blessed, affecting the
+       likelihood of hitting a monster with the	weapon and the
+       damage the weapon will inflict on the monster.  If the
+       player has identified a weapon, the "to hit" and	"to damage"
+       bonuses appear in that order before the weapon's	name in	an
+       inventory listing.  A positive bonus indicates a	blessed
+       weapon, and a negative bonus usually indicates a	cursed
+
+
+
+
+
+
+
+
+
+
+
+				  - 11 -
+
+
+
+       weapon.	The player cannot release a cursed weapon.
+
+	    Without any	armor the player has an	armor class of 10.
+       The lower the player's armor class, the harder it is for	a
+       monster to hit the player, so wearing armor can improve the
+       player's	armor class.  A	cursed suit of armor, however,
+       offers poor protection and may sometimes	be worse than no
+       armor at	all.
+
+	    After the player has identified a suit of armor, the
+       protection bonus	appears	before the armor's name	in an
+       inventory listing.  If the bonus	is positive the	armor is
+       blessed,	and if it is negative, the armor is usually cursed.
+       The player cannot remove	a cursed suit of armor.
+
+	    Some monsters can corrode armor when they hit it.  If
+       such a monster hits the player when the player is wearing
+       metal armor, the	armor loses some of its	protection value,
+       but the corrosion does not curse	the armor.
+
+
+       8.  POTIONS AND SCROLLS
+
+	    The	player can frequently find potions and scrolls in
+       the dungeon.  In	any given dungeon, the player can
+       distinguish among the different types of	potions	by a
+       potion's	color and among	the different types of scrolls by a
+       scroll's	name.  Quaffing	a potion or reading a scroll
+       usually causes some magical occurrence.	Most potions and
+       scrolls may be cursed or	blessed.
+
+
+       9.  RINGS
+
+	    The	player can wear	a maximum of eight rings, and they
+       have a magical effect on	the player as long as they are
+       worn.  Some rings also speed up the player's metabolism,
+       making the player require food more often.  Many	rings can
+       be cursed or blessed, and the player cannot remove a cursed
+       ring.  The player can distinguish among different types of
+       rings by	a ring's jewel.
+
+
+       10.  WANDS AND STAVES
+
+	    Wands and staves affect the	player's environment.  The
+       player can zap a	wand or	staff at something and perhaps
+       shoot a bolt of lightning at it or teleport it away.  All
+       wands or	staves of the same type	are constructed	with the
+       same type of wood.  Some	wands and staves may be	cursed or
+       blessed.
+
+
+
+
+
+
+
+
+
+
+
+				  - 12 -
+
+
+
+       11.  FOOD
+
+	    The	player must be careful not to run out of food since
+       moving through the dungeon fighting monsters consumes a lot
+       of energy.  Starving results in the player's fainting for
+       increasingly longer periods of time, during which any nearby
+       monster can attack the player freely.
+
+
+       12.  GOLD
+
+	    Gold has one use in	a dungeon:  buying things.  One	can
+       buy things in two ways, either in a trading post	or from	a
+       quartermaster.  A trading post is a place "between levels"
+       of the dungeon and can be entered by stepping on	the
+       entrance.  A quartermaster is a person who will sometimes
+       appear and will try to sell the player some of his wares.
+       These wares are never cursed and	frequently blessed, though
+       blessed goods cost more than normal goods.  If the player
+       chooses to buy one of the quartermaster's items,	the
+       quartermaster trades the	item for the specified amount of
+       gold and	disappears.  Attacking a quartermaster causes him
+       to vanish without offering a trade.
+
+
+       13.  MISCELLANEOUS MAGIC	ITEMS
+
+	    Miscellaneous items	such as	a pair of boots	or a book
+       may be found within the dungeon.	 These items can usually be
+       used to the player's advantage (assuming	they are not
+       cursed).	 Some of these items can be worn, such as a cloak,
+       while others are	to be used, such as a book.
+
+
+       14.  ARTIFACTS
+
+	    Some monsters down in the depths of	the dungeon carry
+       unique artifacts.  The game begins as a quest to	retrieve
+       one of these items.  Each artifact appears only on its
+       owner's person.
+
+
+       15.  TRAPS
+
+	    A variety of traps,	including trap doors, bear traps,
+       and sleeping traps, are hidden in the dungeon.  They remain
+       hidden until sprung by a	monster	or the player.	A sprung
+       trap continues to function, but since it	is visible, an
+       intelligent monster is not likely to tread on it.
+
+
+
+
+
+
+
+
+
+
+
+
+
+				  - 13 -
+
+
+
+       16.  THE	MONSTERS
+
+	    Each monster except	for the	merchant quartermaster
+       appears in a limited range of dungeon levels.  All monsters
+       of the same type	share the same abilities; all giant rats,
+       for example, can	give the player	a disease, and all
+       jackalweres can put the player to sleep.	 Monsters of the
+       same type can vary, however, such that one kobold may be
+       much more difficult to kill than	another	one.  In general,
+       the more	difficult it is	to kill	a monster, the more
+       experience points the monster is	worth.
+
+	    Most monsters attack by biting and clawing,	but some
+       monsters	carry weapons, including such projectile weapons as
+       short bows and crossbows, and some monsters have	breath
+       weapons.	 These latter monsters can attack the player from
+       across a	room or	down a corridor.
+
+	    Some monsters are more intelligent than others, and	the
+       more intelligent	a monster, the more likely that	the monster
+       will run	away if	it is about to die.  A fleeing monster will
+       not attack the player unless cornered.
+
+	    As the player moves	down in	the dungeon, the monsters
+       get more	powerful.  Deep	down in	the dungeon there exist
+       some one-of-a-kind monsters.  These monsters are	greatly
+       feared.	However, once a	"unique	monster" is killed, the
+       player will not find another in the current dungeon.
+
+
+       17.  OPTIONS
+
+	    Rogue has several options which may	be set by the
+       player:
+
+       terse  Setting this Boolean option results in shorter
+	      messages appearing on the	top line of the	screen.
+
+       jump   Setting this Boolean option results in waiting until
+	      the player has finished running to draw the player's
+	      path.  Otherwise the game	always displays	the path
+	      one step at a time.
+
+       step   Setting this Boolean option results in most listings,
+	      such as an inventory, appearing one item at a time on
+	      the top line of the screen.  When	this option is not
+	      set, the game clears the screen, displays	the list,
+	      and then redraws the dungeon.
+
+       flush  Setting this Boolean option results in flushing all
+	      typeahead	(pending) commands when	the player
+
+
+
+
+
+
+
+
+
+
+
+				  - 14 -
+
+
+
+	      encounters a monster.
+
+       askme  Setting this Boolean option results in the game
+	      prompting	the player for a name upon encountering	a
+	      new type of scroll, potion, ring,	staff, or wand.
+
+       name   This string is the player's name and defaults to the
+	      player's account name.
+
+       fruit  This string identifies the player's favorite fruit,
+	      sometimes	encountered in the dungeon.  It	defaults to
+	      slime-mold.
+
+       file   This string, which defaults to rogue.save, specifies
+	      the file to use for saving the game.
+
+       score  This string identifies the top-ten score file to use
+	      for the game.
+
+       class  This option specifies the	character class	of the
+	      rogue.  It can be	set only in the	ROGUEOPTS
+	      environment variable.
+
+	    The	player can set options at the beginning	of a game
+       via the ROGUEOPTS environment variable.	Naming a Boolean
+       option sets it, and preceding the Boolean option	name by
+       "no" clears it.	The syntax "stringoption=name" sets a
+       string option to	"name."	 So setting ROGUEOPTS to "terse,
+       jump, nostep, flush, askme, name=Ivan the Terrible,
+       fruit=pomegranate" would	set the	terse, jump, flush, and
+       askme Boolean options, clear the	step Boolean option, set
+       the player's name to "Ivan the Terrible," set the player's
+       favorite	fruit to a pomegranate,	and use	the defaults for
+       the save	file and the score file.
+
+	    The	player may change an option at any time	during the
+       game via	the option command, which results in a listing of
+       the current options.  Typing a new value	changes	the option,
+       a RETURN	moves to the next option, a '-'	moves to the
+       previous	option,	and an ESCAPE returns the player to the
+       dungeon.
+
+
+       18.  SCORING
+
+	    The	player receives	experience points for stealing
+       items from monsters, turning monsters (a	clerical ability),
+       and killing monsters.  When the player gets killed, the
+       player's	score equals the player's experience points.  A
+       player who quits	gets a score equal to the player's
+       experience points and gold.  If the player makes	it back	up
+
+
+
+
+
+
+
+
+
+
+
+				  - 15 -
+
+
+
+       out of the dungeon, the player's	score equals the player's
+       experience points plus the gold the player carried and the
+       gold received from selling the player's possessions.  Rogue
+       maintains a list	of the top ten scores to date, together
+       with the	name of	the player obtaining the score,	the level
+       where the player	finished, and the manner in which the
+       player ended the	game.
+
+
+       19.  ACKNOWLEDGEMENTS
+	    This version of Rogue is based on a	version	developed
+       at the University of California at Berkeley by Michael Toy
+       and Ken Arnold.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+			   The Dungeons	of Doom
+
+			  AT&T Bell Laboratories
+			   The Dungeons	of Doom
+
+
+				 ABSTRACT
+
+
+
+	    Rogue was  first  introduced  by  Michael  Toy  at	the
+       University  of  California  at Berkeley as a screen-oriented
+       fantasy game.  The game had 26 types of	monsters  that	the
+       player could meet while exploring a dungeon generated by	the
+       computer.  Scrolls, potions, rings,  wands,  staves,  armor,
+       and  weapons  helped the	player to battle these monsters	and
+       to gain gold, the basis for scoring.
+
+	    The	version	of Rogue described in this guide  has  been
+       expanded	to include over	110 monsters with many new capabil-
+       ities.  Many of the monsters are	intelligent, and they, like
+       the player, must	avoid traps and	decide when it is better to
+       fight or	to run.	 The player chooses a  character  class	 at
+       the  beginning of the game which	defines	the player's abili-
+       ties.  Experience, rather than gold,  decides  the  player's
+       score.
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/arogue58.html	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,953 @@
+<!-- Advanced Rogue                                                         -->
+<!-- Copyright (C) 1984, 1985, 1986 Michael Morgan, Ken Dalka and AT&T      -->
+<!-- All rights reserved.                                                   -->
+<!--                                                                        -->
+<!-- Based on "Rogue: Exploring the Dungeons of Doom"                       -->
+<!-- Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman     -->
+<!-- All rights reserved.                                                   -->
+<!--                                                                        -->
+<!-- See the file LICENSE.TXT for full copyright and licensing information. -->
+<!-- Creator     : groff version 1.18.1 -->
+<!-- CreationDate: Sat Jan 21 09:55:23 2006 -->
+<h1 align="center"><a href="http://roguelike.sourceforge.net/arogue77">The Dungeons of 
+	Doom</a></h1>
+<br>
+<h2 align="center">AT&amp;T Bell Laboratories</h2>
+<h3 align="center"><A href="http://roguelike.sourceforge.net/arogue58">http://roguelike.sourceforge.net/arogue58</A></h3>
+<br>
+<table border="0" cellpadding="3" cellspacing="3" style="BORDER-COLLAPSE: collapse" id="table1" align="center">
+    <tr>
+	<td nowrap>
+	    Advanced Rogue<br>
+	    Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&amp;T<br>
+	    All rights reserved.
+	</td>
+    </tr>
+    <tr>
+	<td nowrap>
+	    Based on "Rogue: Exploring the Dungeons of Doom"<br>
+	    Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman<br>
+	    All rights reserved.
+	</td>
+    </tr>
+</table>
+<p align="center">See the file LICENSE.TXT for full copyright and licensing 
+    information.</p>
+<p align="center">&nbsp;</p>
+<p align="center"><b>ABSTRACT</b></p>
+<blockquote>
+	<blockquote>
+		<p align="justify">Rogue was first introduced by Michael Toy at the 
+		University of California at Berkeley as a screen-oriented fantasy game. 
+		The game had 26 types of monsters that the player could meet while 
+		exploring a dungeon generated by the computer. Scrolls, potions, rings, 
+		wands, staves, armor, and weapons helped the player to battle these 
+		monsters and to gain gold, the basis for scoring.</p>
+		<p align="justify">The version of Rogue described in this guide has been 
+		expanded to include over 110 monsters with many new capabilities. Many 
+		of the monsters are intelligent, and they, like the player, must avoid 
+		traps and decide when it is better to fight or to run. The player 
+		chooses a character class at the beginning of the game which defines the 
+		player's abilities. Experience, rather than gold, decides the player's 
+		score.</p>
+	</blockquote>
+</blockquote>
+<h2 align="justify">&nbsp;</h2>
+<h3 align="justify">1. INTRODUCTION</h3>
+<p align="justify">
+    Rogue is a screen-oriented fantasy game set in the ever-changing Dungeons of 
+	Doom. The game comes complete with monsters, spells, weapons, armor, 
+	potions, and other magical items. The dungeon's geography changes with every 
+	game, and although many magical items have certain identifiable properties, 
+	such as turning the player invisible, the physical manifestation of the 
+	magic changes each game. A red potion, for example, will cause the same 
+	reaction throughout a given game, but it may be a completely different 
+	potion in a new game.</p>
+<p align="justify">
+    Entering the dungeon with only a little food, armor, and a weapon, the 
+	player must develop a good strategy of when to fight, when to run, and how 
+	to best use any magical items found in the dungeon. To make things 
+	interesting, the player has a quest to return one of several unique 
+	artifacts, rumored to lie deep in the dungeon's bowels. Returning with this 
+	artifact brings great glory and the title of Complete Winner. But even after 
+	finding the artifact, the player may wish to continue further to match wits 
+	with an arch-devil, demon prince, or even a deity found far down in the 
+	dungeon. Defeating such a creature will gain the player many experience 
+	points, the basis for scoring in Rogue.</p>
+<p align="justify">
+    It is very difficult to return from the Dungeons of Doom. Few people ever 
+	make it out alive. Should this unlikely event occur, the player would be 
+	proclaimed a complete winner and handsomely rewarded for any booty removed 
+	from the dungeon.</p>
+<h3 align="justify">2. CHARACTER CLASSES AND ATTRIBUTES</h3>
+<p align="justify">
+    Before placing the player in the dungeon, the game requests the player to 
+	select a character class: a fighter, a magic user, a cleric, or a thief.</p>
+<p align="justify"><span style="FONT-VARIANT: small-caps"><strong>2.1 The Fighter</strong></span></p>
+<p align="justify">
+    A fighter is very strong and will have a high strength rating. This great 
+	strength gives a fighter the best odds of winning a battle with a monster. 
+	At high experience levels the fighter also gets to attack multiple times in 
+	a single turn. This obviously further increases his chances at winning 
+	battles. Intrinsic to the fighter class is a robustness which results in 1 
+	to 10 extra hit points for every new experience level.</p>
+<p align="justify"><span style="FONT-VARIANT: small-caps"><strong>2.2 The Magician</strong></span></p>
+<p align="justify">
+    A magician's major attribute is intelligence, which enables the magician to 
+	cast spells. The number and variety of spells increases as the magician 
+	gains experience and intelligence. Other types of characters can cast 
+	spells, but only if they manage to gain extraordinarily high intelligence. 
+	Magic users are not as hearty as fighters; they receive 1 to 8 extra hit 
+	points for every new experience level.</p>
+<p align="justify"><strong><span style="FONT-VARIANT: small-caps">2.3 The Cleric</span></strong></p>
+<p align="justify">
+    A cleric has a high wisdom rating and can thus pray. The number and variety 
+	of prayers which the gods are willing to grant to a cleric increase as the 
+	cleric gains experience and wisdom. Other character types can pray only if 
+	they manage to gain extraordinary wisdom.</p>
+<p align="justify">
+    Because of their religious nature, clerics can also affect the &quot;undead&quot; 
+	beings, like zombies and ghouls, which became monsters after they died. If 
+	an &quot;undead&quot; creature is next to a cleric, the cleric may try to turn it and 
+	cause it to flee. If the cleric is sufficiently powerful relative to the 
+	monster, the cleric will destroy it. This ability increases as the character 
+	gains experience levels.</p>
+<p align="justify">
+    Clerics can gain from 1 to 8 extra hit points on reaching a new experience 
+	level.</p>
+<p align="justify"><strong><span style="FONT-VARIANT: small-caps">2.4 The Thief</span></strong></p>
+<p align="justify">
+    A thief is exceptionally dextrous and has a good chance to set a trap or rob 
+	a monster. Any type of character can try to set a trap or steal from a 
+	monster standing next to the character, but the chances of success are low 
+	compared to a thief's chances.
+</p>
+<p align="justify">
+    By their nature, thieves can automatically detect all the gold on the 
+	current level of the dungeon. They are also good at detecting hidden traps. 
+	Because thieves slink along, they are not as likely as other characters to 
+	wake sleeping monsters. If a thief manages to sneak up on a creature without 
+	waking it, he will get a chance to backstab the monster. When this is done, 
+	the damage done by the thief greatly increases based on his experience 
+	level.</p>
+<p align="justify">
+    Thieves gain from 1 to 6 extra hit points from a new experience level.
+</p>
+<p align="justify"><strong><span style="FONT-VARIANT: small-caps">2.5 
+CONSTITUTION</span></strong></p>
+<p align="justify">Every character has a constitution rating. A character with 
+an exceptionally good constitution will gain more than the normal amount of hit 
+points associated with the character's class when the character reaches a new 
+experience level. Exceptional constitution also provides better protection 
+versus poison-based attacks and diseases.</p>
+<p align="justify"><strong><span style="FONT-VARIANT: small-caps">2.6 Experience Levels</span></strong></p>
+<p align="justify">
+    Characters gain experience for killing monsters, stealing from monsters, and 
+	turning monsters. Each character class has a set of thresholds associated 
+	with it. When a character reaches a threshold, the character attains the 
+	next experience level. This new level brings extra hit points and a greater 
+	chance of success in performing the abilities associated with the 
+	character's class. Magicians receive new spells, and clerics receive new 
+	prayers.</p>
+<p align="justify">
+    Thieves have the lowest threshold for gaining experience levels, followed by 
+	clerics. Fighters are next, and magicians have the highest threshold.</p>
+<h3 align="justify">
+    3. THE SCREEN</h3>
+<p align="justify">
+    During the normal course of play, the screen consists of three separate 
+	sections: the top line of the terminal, the bottom two lines of the 
+	terminal, and the remaining middle lines. The top line reports actions which 
+	occur during the game, the middle section depicts the dungeon, and the 
+	bottom lines describe the player's current condition.</p>
+<p align="justify"><strong><span style="FONT-VARIANT: small-caps">3.1 The Top Line</span></strong>
+<p align="justify">
+    Whenever anything happens to the player, such as finding a scroll or hitting 
+	or being hit by a monster, a short report of the occurrence appears on the 
+	top line of the screen. When such reports occur quickly, one right after 
+	another, the game displays the notice followed by the prompt '--More--.' 
+	After reading this notice, the player can press a space to display the next 
+	message. At such a point, the game ignores all commands until the player 
+	presses a space.</p>
+<p align="justify">
+    <strong>
+	<span style="FONT-VARIANT: small-caps">3.2 The Dungeon Section</span></strong>
+<p align="justify">
+    The large middle section of the screen displays the player's surroundings using 
+    the following symbols:
+</p>
+<p>
+    <table border="0" cellpadding="3" style="BORDER-COLLAPSE: collapse" id="table3" cellspacing="3">
+	<tr>
+	    <td align="middle">|</td>
+	    <td>&nbsp;&nbsp;&nbsp;&nbsp;
+	    </td>
+	    <td>A wall of a room.</td>
+	</tr>
+	<tr>
+	    <td align="middle">-</td>
+	    <td>&nbsp;</td>
+	    <td>A wall of a room.</td>
+	</tr>
+	<tr>
+	    <td align="middle">*</td>
+	    <td>&nbsp;</td>
+	    <td>A pile of gold.</td>
+	</tr>
+	<tr>
+	    <td align="middle">%</td>
+	    <td>&nbsp;</td>
+	    <td>A way to the next level.</td>
+	</tr>
+	<tr>
+	    <td align="middle">+</td>
+	    <td>&nbsp;</td>
+	    <td>A doorway.</td>
+	</tr>
+	<tr>
+	    <td align="middle">.</td>
+	    <td>&nbsp;</td>
+	    <td>The floor in a room.</td>
+	</tr>
+	<tr>
+	    <td align="middle">@</td>
+	    <td>&nbsp;</td>
+	    <td>The player.</td>
+	</tr>
+	<tr>
+	    <td align="middle">_</td>
+	    <td>&nbsp;</td>
+	    <td>The player, when invisible.</td>
+	</tr>
+	<tr>
+	    <td align="middle">#</td>
+	    <td>&nbsp;</td>
+	    <td>The floor in a passageway.</td>
+	</tr>
+	<tr>
+	    <td align="middle">!</td>
+	    <td>&nbsp;</td>
+	    <td>A flask containing a potion.</td>
+	</tr>
+	<tr>
+	    <td align="middle">?</td>
+	    <td>&nbsp;</td>
+	    <td>A sealed scroll.</td>
+	</tr>
+	<tr>
+	    <td align="middle">:</td>
+	    <td>&nbsp;</td>
+	    <td>Some food.</td>
+	</tr>
+	<tr>
+	    <td align="middle">)</td>
+	    <td>&nbsp;</td>
+	    <td>A weapon.</td>
+	</tr>
+	<tr>
+	    <td align="middle">&nbsp;</td>
+	    <td nowrap>&nbsp;</td>
+	    <td nowrap>Solid rock (denoted by a space).</td>
+	</tr>
+	<tr>
+	    <td align="middle">]</td>
+	    <td>&nbsp;</td>
+	    <td>Some armor.</td>
+	</tr>
+	<tr>
+	    <td align="middle">;</td>
+	    <td>&nbsp;</td>
+	    <td>A miscellaneous magic item.</td>
+	</tr>
+	<tr>
+	    <td align="middle">,</td>
+	    <td>&nbsp;</td>
+	    <td>An artifact.</td>
+	</tr>
+	<tr>
+	    <td align="middle">=</td>
+	    <td>&nbsp;</td>
+	    <td>A ring.</td>
+	</tr>
+	<tr>
+	    <td align="middle">/</td>
+	    <td>&nbsp;</td>
+	    <td>A wand or a staff.</td>
+	</tr>
+	<tr>
+	    <td align="middle">^</td>
+	    <td>&nbsp;</td>
+	    <td>The entrance to a trading post.</td>
+	</tr>
+	<tr>
+	    <td align="middle">&gt;</td>
+	    <td>&nbsp;</td>
+	    <td>A trapdoor leading to the next level</td>
+	</tr>
+	<tr>
+	    <td align="middle">{</td>
+	    <td>&nbsp;</td>
+	    <td>An arrow trap</td>
+	</tr>
+	<tr>
+	    <td align="middle">$</td>
+	    <td>&nbsp;</td>
+	    <td>A sleeping gas trap</td>
+	</tr>
+	<tr>
+	    <td align="middle">}</td>
+	    <td>&nbsp;</td>
+	    <td>A beartrap</td>
+	</tr>
+	<tr>
+	    <td align="middle">~</td>
+	    <td>&nbsp;</td>
+	    <td>A trap that teleports you somewhere else</td>
+	</tr>
+	<tr>
+	    <td align="middle">`</td>
+	    <td>&nbsp;</td>
+	    <td>A poison dart trap</td>
+	</tr>
+	<tr>
+	    <td align="middle">"</td>
+	    <td>&nbsp;</td>
+	    <td>a shimmering magic pool</td>
+	</tr>
+	<tr>
+	    <td align="middle">'</td>
+	    <td>&nbsp;</td>
+	    <td>An entrance to a maze</td>
+	</tr>
+	<tr>
+	    <td align="middle">$</td>
+	    <td>&nbsp;</td>
+	    <td>Any magical item. (During magic detection)</td>
+	</tr>
+	<tr>
+	    <td align="middle">&gt;</td>
+	    <td nowrap>&nbsp;</td>
+	    <td nowrap>A blessed magical item. (During magic detection)</td>
+	</tr>
+	<tr>
+	    <td align="middle">&lt;</td>
+	    <td>&nbsp;</td>
+	    <td>A cursed magical item. (During magic detection)</td>
+	</tr>
+	<tr>
+	    <td align="middle">A letter</td>
+	    <td>&nbsp;</td>
+	    <td>A monster. Note that a given letter may signify<br>
+		multiple monsters, depending on the level of the<br>
+		dungeon. The player can always identify a current<br>
+		monster by using the identify command ('/').</td>
+	</tr>
+    </table>
+</p>
+<p align="justify"><strong><span style="FONT-VARIANT: small-caps">3.3 The Status Section</span></strong></p>
+<p align="justify">
+    The bottom two lines of the screen describe the player's current status. The 
+    first line gives the player's characteristics:
+</p>
+<ul>
+    <li>
+	<p align="justify">Intelligence (Int)</p>
+    <li>
+	<p align="justify">Strength (Str)</p>
+    <li>
+	<p align="justify">Wisdom (Wis)</p>
+    <li>
+	<p align="justify">Dexterity (Dxt)</p>
+    <li>
+	<p align="justify">Constitution (Const)</p>
+    <li>
+	<p align="justify">Charisma (Char)</p>
+    <li>
+	<p align="justify">Encumbrance (Carry)</p>
+    </li>
+</ul>
+<p align="justify">
+    Intelligence, strength, wisdom, dexterity, and constitution have a normal 
+	maximum of 25, but can be higher when augmented by a ring. Encumbrance is a 
+	measurement of how much the player can carry versus how much he is currently 
+	carrying. The more you carry relative to your maximum causes you to use more 
+	food.</p>
+<p align="justify">
+    The second status line provides the following information:
+</p>
+<ul>
+    <li>
+	<p align="justify">The current level (Lvl) in the dungeon. This number 
+	increases as the player goes further down.</p>
+	<li>
+	<p align="justify">How much gold (Au) the player is carrying.</p>
+    <li>
+	<p align="justify">The player's current number of hit points (Hp), followed 
+	in parentheses by the player's current maximum number of hit points. Hit 
+	points express the player's health. As a player heals by resting, the 
+	player's current hit points gradually increase until reaching the current 
+	maximum. This maximum increases each time a player attains a new experience 
+	level. If the player's current hit points reach 0, the player dies.</p>
+    <li>
+	<p align="justify">The player's armor class (Ac). This number describes the 
+	amount of protection provided by the armor and rings currently worn by the 
+	player. Wearing no armor is equivalent to an armor class of 10. The 
+	protection level increases as the armor class decreases.</p>
+    <li>
+	<p align="justify">The player's current experience level (Exp) followed by 
+	the player's experience points. The player can gain experience points by 
+	killing monsters, successfully stealing from monsters, and turning monsters. 
+	When a player gains enough experience points to surpass a threshold that 
+	depends on the player's character type, the player reaches a new experience 
+	level. A new experience level brings extra hit points and possibly added 
+	abilities, such as a new spell for a magician or a new prayer for a cleric.</p>
+    <li>
+	<p align="justify">A description of the player's character. This description 
+	depends on the player's character type and experience level.</p>
+    </li>
+</ul>
+<h3 align="justify">4. COMMANDS</h3>
+<p align="justify">
+    A player can invoke most Rogue commands by typing a single character. Some 
+	commands, however, require a direction, in which case the player types the 
+	command character followed by a directional command. Many commands can be 
+	prefaced by a number, indicating how many times the command should be 
+	executed.</p>
+<p align="justify">
+    When the player invokes a command referring to an item in the player's pack 
+	(such as reading a scroll), the game prompts for the item. The player should 
+	then type the letter associated with the item, as displayed by the inventory 
+	command. Typing a '*' at this point produces a list of the eligible items.</p>
+<p align="center"><b><i>Rogue understands the following commands:</i></b></p>
+<p>
+    <table border="0" cellpadding="3" style="BORDER-COLLAPSE: collapse" id="table4" cellspacing="3">
+	<tr>
+	    <td align="middle" valign="top">?</td>
+	    <td>&nbsp;&nbsp;&nbsp;</td>
+	    <td>Preceding a command by a '?' produces a brief explanation of the command. The 
+		command '?*' gives an explanation of all the commands.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">/</td>
+	    <td>&nbsp;</td>
+	    <td>Preceding a symbol by a '/' identifies the symbol.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">h</td>
+	    <td>&nbsp;</td>
+	    <td>Move one position to the left.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">j</td>
+	    <td>&nbsp;</td>
+	    <td>Move one position down.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">k</td>
+	    <td>&nbsp;</td>
+	    <td>Move one position up.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">l</td>
+	    <td>&nbsp;</td>
+	    <td>Move one position to the right.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">y</td>
+	    <td height="21">&nbsp;</td>
+	    <td height="21">Move one position to the top left.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">u</td>
+	    <td>&nbsp;</td>
+	    <td>Move one position to the top right.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">b</td>
+	    <td>&nbsp;</td>
+	    <td>Move one position to the bottom left.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">n</td>
+	    <td>&nbsp;</td>
+	    <td>Move one position to the bottom right</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">H</td>
+	    <td>&nbsp;</td>
+	    <td>Run to the left until reaching something interesting.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">J</td>
+	    <td>&nbsp;</td>
+	    <td>Run down until reaching something interesting.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">K</td>
+	    <td>&nbsp;</td>
+	    <td>Run up until reaching something interesting.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">L</td>
+	    <td>&nbsp;</td>
+	    <td>Run to the right until reaching something interesting.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">Y</td>
+	    <td>&nbsp;</td>
+	    <td>Run to the top left until reaching something interesting.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">U</td>
+	    <td>&nbsp;</td>
+	    <td>Run to the top right until reaching something interesting.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">B</td>
+	    <td>&nbsp;</td>
+	    <td>Run to the bottom left until reaching something interesting.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">N</td>
+	    <td>&nbsp;</td>
+	    <td>Run to the bottom right until reaching something interesting</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">t</td>
+	    <td>&nbsp;</td>
+	    <td>This command, followed by a directional command, prompts for an 
+		object from the players pack. The player then throws the object in the 
+		specified direction.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">f</td>
+	    <td>&nbsp;</td>
+	    <td>When this command precedes a directional command, the player moves 
+		in the specified direction until passing something interesting.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">z</td>
+	    <td>&nbsp;</td>
+	    <td>This command must be followed by a directional command. Rogue then 
+		prompts for a wand or staff from the player's pack and zaps it in the 
+		specified direction.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">&gt;</td>
+	    <td>&nbsp;</td>
+	    <td>Go down to the next level.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">&lt;</td>
+	    <td>&nbsp;</td>
+	    <td>Go up to the next level.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">s</td>
+	    <td>&nbsp;</td>
+	    <td>Search for a secret door or a trap in the circle surrounding the player.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">.</td>
+	    <td>&nbsp;</td>
+	    <td>This command (a dot) causes the player to rest a turn.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">i</td>
+	    <td>&nbsp;</td>
+	    <td>Display an inventory of the player's pack.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">I</td>
+	    <td>&nbsp;</td>
+	    <td>This command prompts for an item from the player's pack and displays 
+		the inventory information for that item.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">q</td>
+	    <td>&nbsp;</td>
+	    <td>Quaff a potion from the player's pack.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">r</td>
+	    <td>&nbsp;</td>
+	    <td>Read a scroll from the player's pack.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">e</td>
+	    <td>&nbsp;</td>
+	    <td>Eat some food from the player's pack.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">w</td>
+	    <td>&nbsp;</td>
+	    <td>Wield a weapon from the player's pack.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">W</td>
+	    <td>&nbsp;</td>
+	    <td>Wear some armor or miscellaneous magic item from the player's pack.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">T</td>
+	    <td>&nbsp;</td>
+	    <td>Take off whatever the player is wearing.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">P</td>
+	    <td>&nbsp;</td>
+	    <td>Put on a ring from the player's pack. The player can wear a maximum 
+		of eight rings.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">R</td>
+	    <td>&nbsp;</td>
+	    <td>Remove a ring from the player's hand.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">^U</td>
+	    <td>&nbsp;</td>
+	    <td>Use a miscellaneous magic item in the player's pack.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">d</td>
+	    <td>&nbsp;</td>
+	    <td>Drop an item from the player's pack.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">c</td>
+	    <td>&nbsp;</td>
+	    <td>When the player types this command, Rogue prompts for an item from 
+		the player's pack and a one-line name. Rogue then calls all similar 
+		items (such as all the blue potions) by the specified name.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">m</td>
+	    <td>&nbsp;</td>
+	    <td>When the player types this command, Rogue prompts for an item from 
+		the player's pack and a one-line name. Rogue then marks the specified 
+		item with the given name.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">o</td>
+	    <td>&nbsp;</td>
+	    <td>Typing this command causes Rogue to display all the settable 
+		options. The player can then merely examine the options or change any or 
+		all of them.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">C</td>
+	    <td>&nbsp;</td>
+	    <td>This command, restricted to magicians and characters with 
+		exceptionally high intelligence, produces a listing of the magician's 
+		current supply of spells. The player can select one of the displayed 
+		spells and, if the player's energy level is sufficiently high, cast it. 
+		The more complicated the spell, the more energy it takes.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">p</td>
+	    <td>&nbsp;</td>
+	    <td>This command, restricted to clerics and characters with 
+		exceptionally high wisdom, produces a listing of the cleric's known 
+		prayers. The player can then offer one of these prayers to the 
+		character's deity. Deities are not known for favoring characters which 
+		continually pray to them, and they are most likely to answer the least 
+		&quot;ambitious&quot; prayers.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">a</td>
+	    <td>&nbsp;</td>
+	    <td>This command is restricted to clerics and characters with 
+		exceptionally high wisdom and must be followed by a directional command. 
+		If there is an &quot;undead&quot; monster standing next to the player in the 
+		specified direction, there is a chance the player will affect the 
+		monster by causing it to flee or possibly even destroying it.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">^</td>
+	    <td>&nbsp;</td>
+	    <td>This command sets a trap and is most likely to succeed for a 
+		character with a high dexterity, such as a thief. If the character is 
+		successful, Rogue prompts the player for a type of trap and sets it 
+		where the player is standing.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">G</td>
+	    <td>&nbsp;</td>
+	    <td>This command is restricted to thieves. It causes Rogue to display 
+		all the gold on the current level.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">D</td>
+	    <td>&nbsp;</td>
+	    <td>Dip something into a magic pool.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">^T</td>
+	    <td height="22">&nbsp;</td>
+	    <td height="22">This command is most likely to succeed for a character 
+		with a high dexterity, such as a thief, and it must be followed by a 
+		directional command. If there is a monster standing next to the player 
+		in the specified direction, the player tries to steal an item from the 
+		monster's pack. If the player is successful, the monster does not notice 
+		anything, but if the player is unsuccessful, there is a chance the 
+		monster will wake up.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">^L</td>
+	    <td>&nbsp;</td>
+	    <td>Redraw the screen.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">^R</td>
+	    <td>&nbsp;</td>
+	    <td>Repeat the last message that was displayed on the top line of the screen.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">Escape (^[)</td>
+	    <td>&nbsp;</td>
+	    <td>Typing an escape will usually cause Rogue to cancel the current command.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">v</td>
+	    <td>&nbsp;</td>
+	    <td>Print the current Rogue version number.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">!</td>
+	    <td>&nbsp;</td>
+	    <td>Escape to the shell level.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">S</td>
+	    <td>&nbsp;</td>
+	    <td>Quit and save the game for resumption at a later time.</td>
+	</tr>
+	<tr>
+	    <td align="middle" valign="top">Q</td>
+	    <td>&nbsp;</td>
+	    <td>Quit without saving the game.</td>
+	</tr>
+    </table>
+</p>
+<h3 align="justify">5. IMPLICIT COMMANDS</h3>
+<p align="justify">
+    There is no &quot;attack&quot; command. If a player wishes to attack a monster, the 
+	player simply tries to move onto the spot where the monster is standing. The 
+	game then assumes that the player wishes to attack the monster with whatever 
+	weapon the player is wielding.</p>
+<p align="justify">
+    When the player moves onto an item, the game automatically places the object 
+	into the player's pack. If there is no room left in the pack, the game 
+	announces that fact and leaves the item on the floor.</p>
+<h3 align="justify">6. LIGHT</h3>
+<p align="justify">
+    Some rooms in the dungeon possess a natural light source. In other rooms and 
+	in corridors the player can see only those things within a one space radius 
+	from the player. These dark rooms can be lit with magical light or by a fire 
+	beetle.</p>
+<h3 align="justify">7. WEAPONS AND ARMOR</h3>
+<p align="justify">
+    The player can wield exactly one weapon at a time. When the player attacks a 
+	monster, the amount of damage depends on the particular weapon the player is 
+	wielding. To fire a projectile weapon, such as a crossbow or a short bow, 
+	the player should wield the bow and &quot;throw&quot; the bolt or arrow at the 
+	monster.</p>
+<p align="justify">
+    A weapon may be cursed or blessed, affecting the likelihood of hitting a 
+	monster with the weapon and the damage the weapon will inflict on the 
+	monster. If the player has identified a weapon, the &quot;to hit&quot; and &quot;to damage&quot; 
+	bonuses appear in that order before the weapon's name in an inventory 
+	listing. A positive bonus indicates a blessed weapon, and a negative bonus 
+	usually indicates a cursed weapon. The player cannot release a cursed 
+	weapon.</p>
+<p align="justify">
+    Without any armor the player has an armor class of 10. The lower the 
+	player's armor class, the harder it is for a monster to hit the player, so 
+	wearing armor can improve the player's armor class. A cursed suit of armor, 
+	however, offers poor protection and may sometimes be worse than no armor at 
+	all.</p>
+<p align="justify">
+    After the player has identified a suit of armor, the protection bonus 
+	appears before the armor's name in an inventory listing. If the bonus is 
+	positive the armor is blessed, and if it is negative, the armor is usually 
+	cursed. The player cannot remove a cursed suit of armor.</p>
+<p align="justify">
+    Some monsters can corrode armor when they hit it. If such a monster hits the 
+	player when the player is wearing metal armor, the armor loses some of its 
+	protection value, but the corrosion does not curse the armor.</p>
+<h3 align="justify">8. POTIONS AND SCROLLS</h3>
+<p align="justify">
+    The player can frequently find potions and scrolls in the dungeon. In any 
+	given dungeon, the player can distinguish among the different types of 
+	potions by a potion's color and among the different types of scrolls by a 
+	scroll's name. Quaffing a potion or reading a scroll usually causes some 
+	magical occurrence. Most potions and scrolls may be cursed or blessed.</p>
+<h3 align="justify">9. RINGS</h3>
+<p align="justify">
+    The player can wear a maximum of eight rings, and they have a magical effect 
+	on the player as long as they are worn. Some rings also speed up the 
+	player's metabolism, making the player require food more often. Many rings 
+	can be cursed or blessed, and the player cannot remove a cursed ring. The 
+	player can distinguish among different types of rings by a ring's jewel.</p>
+<h3 align="justify">10. WANDS AND STAVES</h3>
+<p align="justify">
+    Wands and staves affect the player's environment. The player can zap a wand 
+	or staff at something and perhaps shoot a bolt of lightning at it or 
+	teleport it away. All wands or staves of the same type are constructed with 
+	the same type of wood. Some wands and staves may be cursed or blessed.</p>
+<h3 align="justify">11. FOOD</h3>
+<p>The player must be careful not to run out of food since moving through the 
+dungeon fighting monsters consumes a lot of energy. Starving results in the 
+player's fainting for increasingly longer periods of time, during which any 
+nearby monster can attack the player freely. </p>
+<h3 align="justify">12. GOLD</h3>
+<p>Gold has one use in a dungeon: buying things. One can buy things in two ways, 
+either in a trading post or from a quartermaster. A trading post is a place 
+&quot;between levels&quot; of the dungeon and can be entered by stepping on the entrance. 
+A quartermaster is a person who will sometimes appear and will try to sell the 
+player some of his wares. These wares are never cursed and frequently blessed, 
+though blessed goods cost more than normal goods. If the player chooses to buy 
+one of the quartermaster's items, the quartermaster trades the item for the 
+specified amount of gold and disappears. Attacking a quartermaster causes him to 
+vanish without offering a trade. </p>
+<h3 align="justify">13. MISCELLANEOUS MAGIC ITEMS</h3>
+<p align="justify">
+    Miscellaneous items such as a pair of boots or a book may be found within 
+	the dungeon. These items can usually be used to the player's advantage 
+	(assuming they are not cursed). Some of these items can be worn, such as a 
+	cloak, while others are to be used, such as a book.</p>
+<h3 align="justify">14. ARTIFACTS</h3>
+<p align="justify">
+    Some monsters down in the depths of the dungeon carry unique artifacts. The 
+	game begins as a quest to retrieve one of these items. Each artifact appears 
+	only on its owner's person.</p>
+<h3 align="justify">15. TRAPS</h3>
+<p align="justify">
+    &nbsp;A variety of traps, including trap doors, bear traps, and sleeping 
+	traps, are hidden in the dungeon. They remain hidden until sprung by a 
+	monster or the player. A sprung trap continues to function, but since it is 
+	visible, an intelligent monster is not likely to tread on it.</p>
+<h3 align="justify">16. THE MONSTERS</h3>
+<p align="justify">
+    Each monster except for the merchant quartermaster appears in a limited 
+	range of dungeon levels. All monsters of the same type share the same 
+	abilities; all giant rats, for example, can give the player a disease, and 
+	all jackalweres can put the player to sleep. Monsters of the same type can 
+	vary, however, such that one kobold may be much more difficult to kill than 
+	another one. In general, the more difficult it is to kill a monster, the 
+	more experience points the monster is worth.</p>
+<p align="justify">
+    Most monsters attack by biting and clawing, but some monsters carry weapons, 
+	including such projectile weapons as short bows and crossbows, and some 
+	monsters have breath weapons. These latter monsters can attack the player 
+	from across a room or down a corridor.</p>
+<p align="justify">
+    Some monsters are more intelligent than others, and the more intelligent a 
+	monster, the more likely that the monster will run away if it is about to 
+	die. A fleeing monster will not attack the player unless cornered.</p>
+<p align="justify">As the player moves down in the dungeon, the monsters get 
+more powerful. Deep down in the dungeon there exist some one-of-a-kind monsters. 
+These monsters are greatly feared. However, once a &quot;unique monster&quot; is killed, 
+the player will not find another in the current dungeon.</p>
+<h3 align="justify">17. OPTIONS</h3>
+<p align="justify">
+    Rogue has several options which may be set by the player:
+</p>
+<p>
+    <table border="0" cellpadding="3" style="BORDER-COLLAPSE: collapse" id="table5" cellspacing="3">
+	<tr>
+	    <td valign="top">terse</td>
+	    <td>&nbsp;&nbsp;</td>
+	    <td>Setting this Boolean option results in shorter messages appearing on 
+		the top line of the screen.</td>
+	</tr>
+	<tr>
+	    <td valign="top">jump</td>
+	    <td>&nbsp;</td>
+	    <td>Setting this Boolean option results in waiting until the player has 
+		finished running to draw the player's path. Otherwise the game always 
+		displays the path one step at a time.</td>
+	</tr>
+	<tr>
+	    <td valign="top">step</td>
+	    <td>&nbsp;</td>
+	    <td>Setting this Boolean option results in most listings, such as an 
+		inventory, appearing one item at a time on the top line of the screen. 
+		When this option is not set, the game clears the screen, displays the 
+		list, and then redraws the dungeon.</td>
+	</tr>
+	<tr>
+	    <td valign="top">flush</td>
+	    <td>&nbsp;</td>
+	    <td>Setting this Boolean option results in flushing all type ahead 
+		(pending) commands when the player encounters a monster.</td>
+	</tr>
+	<tr>
+	    <td valign="top">askme</td>
+	    <td nowrap>&nbsp;</td>
+	    <td>Setting this Boolean option results in the game prompting the player 
+		for a name upon encountering a new type of scroll, potion, ring, staff, 
+		or wand.</td>
+	</tr>
+	<tr>
+	    <td valign="top">name</td>
+	    <td>&nbsp;</td>
+	    <td>This string is the player's name and defaults to the player's 
+		account name.</td>
+	</tr>
+	<tr>
+	    <td valign="top">fruit</td>
+	    <td>&nbsp;</td>
+	    <td>This string identifies the player's favorite fruit, sometimes 
+		encountered in the dungeon. It defaults to slime-mold.</td>
+	</tr>
+	<tr>
+	    <td valign="top">file</td>
+	    <td>&nbsp;</td>
+	    <td>This string, which defaults to rogue.save, specifies the file to use 
+		for saving the game.</td>
+	</tr>
+	<tr>
+	    <td valign="top">score</td>
+	    <td>&nbsp;</td>
+	    <td>This string identifies the top-ten score file to use for the game.</td>
+	</tr>
+	<tr>
+	    <td valign="top">class</td>
+	    <td>&nbsp;</td>
+	    <td>This option specifies the character class of the rogue. It can be 
+		set only in the ROGUEOPTS environment variable.</td>
+	</tr>
+	</table>
+</p>
+<p align="justify">
+    The player can set options at the beginning of a game via the ROGUEOPTS 
+	environment variable. Naming a Boolean option sets it, and preceding the 
+	Boolean option name by &quot;no&quot; clears it. The syntax &quot;stringoption=name&quot; sets a 
+	string option to &quot;name.&quot; So setting ROGUEOPTS to &quot;terse, jump, nostep, 
+	flush, askme, name=Ivan the Terrible, fruit=pomegranate&quot; would set the 
+	terse, jump, flush, and askme Boolean options, clear the step Boolean 
+	option, set the player's name to &quot;Ivan the Terrible,&quot; set the player's 
+	favorite fruit to a pomegranate, and use the defaults for the save file and 
+	the score file.</p>
+<p align="justify">
+    The player may change an option at any time during the game via the option 
+	command, which results in a listing of the current options. Typing a new 
+	value changes the option, a RETURN moves to the next option, a '-' moves to 
+	the previous option, and an ESCAPE returns the player to the dungeon.</p>
+<h3 align="justify">18. SCORING</h3>
+<p>The player receives experience points for stealing items from monsters, 
+turning monsters (a clerical ability), and killing monsters. When the player 
+gets killed, the player's score equals the player's experience points. A player 
+who quits gets a score equal to the player's experience points and gold. If the 
+player makes it back up out of the dungeon, the player's score equals the 
+player's experience points plus the gold the player carried and the gold 
+received from selling the player's possessions. Rogue maintains a list of the 
+top ten scores to date, together with the name of the player obtaining the 
+score, the level where the player finished, and the manner in which the player 
+ended the game.</p>
+<h3 align="justify">19. ACKNOWLEDGEMENTS</h3>
+<p align="justify">
+    This version of Rogue is based on a version developed at the University of 
+	California at Berkeley by Michael Toy and Ken Arnold.</p>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/arogue58.sln	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,24 @@
+Microsoft Visual Studio Solution File, Format Version 7.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "arogue58", "arogue58.vcproj", "{2EEE53AB-A85A-4D4D-8DB2-B5F23513F415}"
+EndProject
+Global
+	GlobalSection(SolutionConfiguration) = preSolution
+		ConfigName.0 = Debug
+		ConfigName.1 = Release
+		ConfigName.2 = test
+	EndGlobalSection
+	GlobalSection(ProjectDependencies) = postSolution
+	EndGlobalSection
+	GlobalSection(ProjectConfiguration) = postSolution
+		{2EEE53AB-A85A-4D4D-8DB2-B5F23513F415}.Debug.ActiveCfg = Debug|Win32
+		{2EEE53AB-A85A-4D4D-8DB2-B5F23513F415}.Debug.Build.0 = Debug|Win32
+		{2EEE53AB-A85A-4D4D-8DB2-B5F23513F415}.Release.ActiveCfg = Release|Win32
+		{2EEE53AB-A85A-4D4D-8DB2-B5F23513F415}.Release.Build.0 = Release|Win32
+		{2EEE53AB-A85A-4D4D-8DB2-B5F23513F415}.test.ActiveCfg = Debug|Win32
+		{2EEE53AB-A85A-4D4D-8DB2-B5F23513F415}.test.Build.0 = Debug|Win32
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+	EndGlobalSection
+	GlobalSection(ExtensibilityAddIns) = postSolution
+	EndGlobalSection
+EndGlobal
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/arogue58.vcproj	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,305 @@
+<?xml version="1.0" encoding = "Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.00"
+	Name="arogue58"
+	ProjectGUID="{2EEE53AB-A85A-4D4D-8DB2-B5F23513F415}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="Debug"
+			IntermediateDirectory="Debug"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalOptions="/I.. /wd4033 /wd4716"
+				Optimization="0"
+				OptimizeForWindowsApplication="TRUE"
+				AdditionalIncludeDirectories="../pdcurses"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+				MinimalRebuild="FALSE"
+				ExceptionHandling="FALSE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="5"
+				BufferSecurityCheck="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="4"
+				CompileAs="1"
+				DisableSpecificWarnings="4013;4033;4716"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="pdcurses.lib Ws2_32.lib"
+				AdditionalDependencies="shfolder.lib pdcurses.lib"
+				OutputFile="$(OutDir)/arogue58.exe"
+				LinkIncremental="0"
+				AdditionalLibraryDirectories="..\pdcurses"
+				IgnoreDefaultLibraryNames="LIBC.LIB"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/arogue58.pdb"
+				SubSystem="1"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="Release"
+			IntermediateDirectory="Release"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				OmitFramePointers="TRUE"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+				StringPooling="TRUE"
+				RuntimeLibrary="4"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="3"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)/arogue58.exe"
+				LinkIncremental="1"
+				GenerateDebugInformation="TRUE"
+				SubSystem="2"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+		</Configuration>
+		<Configuration
+			Name="test|Win32"
+			OutputDirectory="test"
+			IntermediateDirectory="test"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="5"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="4"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)/arogue58.exe"
+				LinkIncremental="2"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/arogue58.pdb"
+				SubSystem="2"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+		</Configuration>
+	</Configurations>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
+			<File
+				RelativePath="chase.c">
+			</File>
+			<File
+				RelativePath="command.c">
+			</File>
+			<File
+				RelativePath="daemon.c">
+			</File>
+			<File
+				RelativePath="daemons.c">
+			</File>
+			<File
+				RelativePath="encumb.c">
+			</File>
+			<File
+				RelativePath="fight.c">
+			</File>
+			<File
+				RelativePath="init.c">
+			</File>
+			<File
+				RelativePath="io.c">
+			</File>
+			<File
+				RelativePath="list.c">
+			</File>
+			<File
+				RelativePath="main.c">
+			</File>
+			<File
+				RelativePath="maze.c">
+			</File>
+			<File
+				RelativePath="mdport.c">
+			</File>
+			<File
+				RelativePath="misc.c">
+			</File>
+			<File
+				RelativePath="monsters.c">
+			</File>
+			<File
+				RelativePath="move.c">
+			</File>
+			<File
+				RelativePath="new_level.c">
+			</File>
+			<File
+				RelativePath="options.c">
+			</File>
+			<File
+				RelativePath="outside.c">
+			</File>
+			<File
+				RelativePath="pack.c">
+			</File>
+			<File
+				RelativePath="passages.c">
+			</File>
+			<File
+				RelativePath="player.c">
+			</File>
+			<File
+				RelativePath="potions.c">
+			</File>
+			<File
+				RelativePath="rings.c">
+			</File>
+			<File
+				RelativePath="rip.c">
+			</File>
+			<File
+				RelativePath="rogue.c">
+			</File>
+			<File
+				RelativePath="rooms.c">
+			</File>
+			<File
+				RelativePath="save.c">
+			</File>
+			<File
+				RelativePath="scrolls.c">
+			</File>
+			<File
+				RelativePath="state.c">
+			</File>
+			<File
+				RelativePath="sticks.c">
+			</File>
+			<File
+				RelativePath="things.c">
+			</File>
+			<File
+				RelativePath="trader.c">
+			</File>
+			<File
+				RelativePath="util.c">
+			</File>
+			<File
+				RelativePath="vers.c">
+			</File>
+			<File
+				RelativePath="weapons.c">
+			</File>
+			<File
+				RelativePath="wear.c">
+			</File>
+			<File
+				RelativePath="wizard.c">
+			</File>
+			<File
+				RelativePath="xcrypt.c">
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc">
+			<File
+				RelativePath="mach_dep.h">
+			</File>
+			<File
+				RelativePath="network.h">
+			</File>
+			<File
+				RelativePath="rogue.h">
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
+		</Filter>
+		<File
+			RelativePath="LICENSE.TXT">
+		</File>
+		<File
+			RelativePath="Makefile">
+		</File>
+		<File
+			RelativePath="arogue58.doc">
+		</File>
+		<File
+			RelativePath="arogue58.html">
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/chase.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,1008 @@
+/*
+ * Code for one object to chase another
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include <ctype.h>
+#include <limits.h>
+#include "curses.h"
+#include "rogue.h"
+#define	MAXINT	INT_MAX
+#define	MININT	INT_MIN
+
+coord ch_ret;				/* Where chasing takes you */
+
+
+
+
+
+/*
+ * Canblink checks if the monster can teleport (blink).  If so, it will
+ * try to blink the monster next to the player.
+ */
+
+bool
+can_blink(tp)
+register struct thing *tp;
+{
+    register int y, x, index=9;
+    coord tryp;	/* To hold the coordinates for use in diag_ok */
+    bool spots[9], found_one=FALSE;
+
+    /*
+     * First, can the monster even blink?  And if so, there is only a 50%
+     * chance that it will do so.  And it won't blink if it is running or
+     * held.
+     */
+    if (off(*tp, CANBLINK) || (on(*tp, ISHELD)) ||
+	on(*tp, ISFLEE) ||
+	(on(*tp, ISSLOW) && off(*tp, ISHASTE) && !(tp->t_turn)) ||
+	tp->t_no_move ||
+	(rnd(12) < 6)) return(FALSE);
+
+
+    /* Initialize the spots as illegal */
+    do {
+	spots[--index] = FALSE;
+    } while (index > 0);
+
+    /* Find a suitable spot next to the player */
+    for (y=hero.y-1; y<hero.y+2; y++)
+	for (x=hero.x-1; x<hero.x+2; x++, index++) {
+	    /* Make sure x coordinate is in range and that we are
+	     * not at the player's position
+	     */
+	    if (x<0 || x >= COLS || index == 4) continue;
+
+	    /* Is it OK to move there? */
+	    if (step_ok(y, x, NOMONST, tp) &&
+		(!isatrap(mvwinch(cw, y, x)) ||
+		  rnd(10) >= tp->t_stats.s_intel ||
+		  on(*tp, ISFLY))) {
+		/* OK, we can go here.  But don't go there if
+		 * monster can't get at player from there
+		 */
+		tryp.y = y;
+		tryp.x = x;
+		if (diag_ok(&tryp, &hero, tp)) {
+		    spots[index] = TRUE;
+		    found_one = TRUE;
+		}
+	    }
+	}
+
+    /* If we found one, go to it */
+    if (found_one) {
+	char rch;	/* What's really where the creatures moves to */
+
+	/* Find a legal spot */
+	while (spots[index=rnd(9)] == FALSE) continue;
+
+	/* Get the coordinates */
+	y = hero.y + (index/3) - 1;
+	x = hero.x + (index % 3) - 1;
+
+	/* Move the monster from the old space */
+	mvwaddch(cw, tp->t_pos.y, tp->t_pos.x, tp->t_oldch);
+
+	/* Move it to the new space */
+	tp->t_oldch = CCHAR( mvwinch(cw, y, x) );
+
+	/* Display the creature if our hero can see it */
+	if (cansee(y, x) &&
+	    off(*tp, ISINWALL) &&
+	    !invisible(tp))
+	    mvwaddch(cw, y, x, tp->t_type);
+
+	/* Fix the monster window */
+	mvwaddch(mw, tp->t_pos.y, tp->t_pos.x, ' '); /* Clear old position */
+	mvwaddch(mw, y, x, tp->t_type);
+
+	/* Record the new position */
+	tp->t_pos.y = y;
+	tp->t_pos.x = x;
+
+	/* If the monster is on a trap, trap it */
+	rch = CCHAR( mvinch(y, x) );
+	if (isatrap(rch)) {
+	    if (cansee(y, x)) tp->t_oldch = rch;
+	    be_trapped(tp, &(tp->t_pos));
+	}
+    }
+
+    return(found_one);
+}
+
+/* 
+ * Can_shoot determines if the monster (er) has a direct line of shot 
+ * at the player (ee).  If so, it returns the direction in which to shoot.
+ */
+
+coord *
+can_shoot(er, ee)
+register coord *er, *ee;
+{
+    static coord shoot_dir;
+
+    /* Make sure we are chasing the player */
+    if (!ce((*ee), hero)) return(NULL);
+
+    /* 
+     * They must be in the same room or very close (at door)
+     */
+    if (roomin(er) != roomin(&hero) && DISTANCE(er->y,er->x,ee->y,ee->x) > 1)
+	return(NULL);
+
+    /* Do we have a straight shot? */
+    if (!straight_shot(er->y, er->x, ee->y, ee->x, &shoot_dir)) return(NULL);
+    else return(&shoot_dir);
+}
+
+/*
+ * chase:
+ *	Find the spot for the chaser(er) to move closer to the
+ *	chasee(ee).  Returns TRUE if we want to keep on chasing later
+ *	FALSE if we reach the goal.
+ */
+
+chase(tp, ee, flee, mdead)
+register struct thing *tp;
+register coord *ee;
+bool flee; /* True if destination (ee) is player and monster is running away
+	    * or the player is in a wall and the monster can't get to it
+	    */
+bool *mdead;
+{
+    int damage, dist, thisdist, monst_dist = MAXINT; 
+    struct linked_list *weapon;
+    register coord *er = &tp->t_pos; 
+    coord *shoot_dir;
+    char ch, mch;
+    bool next_player = FALSE;
+
+    if (mdead != NULL)
+	*mdead = 0;
+
+    /* 
+     * set the distance from the chas(er) to the chas(ee) here and then
+     * we won't have to reset it unless the chas(er) moves (instead of shoots)
+     */
+    dist = DISTANCE(er->y, er->x, ee->y, ee->x);
+
+    /*
+     * If the thing is confused or it can't see the player,
+     * let it move randomly. 
+     */
+    if ((on(*tp, ISHUH) && rnd(10) < 8) ||
+	(on(player, ISINVIS) && off(*tp, CANSEE))) { /* Player is invisible */
+	/*
+	 * get a valid random move
+	 */
+	ch_ret = *rndmove(tp);
+	dist = DISTANCE(ch_ret.y, ch_ret.x, ee->y, ee->x);
+	/*
+	 * check to see if random move takes creature away from player
+	 * if it does then turn off ISHELD
+	 */
+	if (dist > 2) {
+	    if (on(*tp, DIDHOLD)) {
+		 turn_off(*tp, DIDHOLD);
+		 turn_on(*tp, CANHOLD);
+		 if (--hold_count == 0) 
+		     turn_off(player, ISHELD);
+	    }
+
+	    /* If monster was suffocating, stop it */
+	    if (on(*tp, DIDSUFFOCATE)) {
+		turn_off(*tp, DIDSUFFOCATE);
+		turn_on(*tp, CANSUFFOCATE);
+		extinguish(suffocate);
+	    }
+	}
+    }
+
+    /* If we can breathe, we may do so */
+    else if (on(*tp, CANBREATHE)		&&
+	     (dist < BOLT_LENGTH*BOLT_LENGTH)	&&
+	     (shoot_dir = can_shoot(er, ee))	&&
+	     !on(player, ISINWALL)		&&
+	     (rnd(100) < 75)) {
+		register char *breath = NULL;
+
+		damage = tp->t_stats.s_hpt;
+		/* Will it breathe at random */
+		if (on(*tp, CANBRANDOM)) {
+		    /* Turn off random breath */
+		    turn_off(*tp, CANBRANDOM);
+
+		    /* Select type of breath */
+		    switch (rnd(10)) {
+		    case 0: breath = "acid";
+			    turn_on(*tp, NOACID);
+		    when 1: breath = "flame";
+			    turn_on(*tp, NOFIRE);
+		    when 2: breath = "lightning bolt";
+			    turn_on(*tp, NOBOLT);
+		    when 3: breath = "chlorine gas";
+			    turn_on(*tp, NOGAS);
+		    when 4: breath = "ice";
+			    turn_on(*tp, NOCOLD);
+		    when 5: breath = "nerve gas";
+			    turn_on(*tp, NOPARALYZE);
+		    when 6: breath = "sleeping gas";
+			    turn_on(*tp, NOSLEEP);
+		    when 7: breath = "slow gas";
+			    turn_on(*tp, NOSLOW);
+		    when 8: breath = "confusion gas";
+			    turn_on(*tp, ISCLEAR);
+		    when 9: breath = "fear gas";
+			    turn_on(*tp, NOFEAR);
+		    }
+		}
+
+		/* Or can it breathe acid? */
+		else if (on(*tp, CANBACID)) {
+		    turn_off(*tp, CANBACID);
+		    breath = "acid";
+		}
+
+		/* Or can it breathe fire */
+		else if (on(*tp, CANBFIRE)) {
+		    turn_off(*tp, CANBFIRE);
+		    breath = "flame";
+		}
+
+		/* Or can it breathe electricity? */
+		else if (on(*tp, CANBBOLT)) {
+		    turn_off(*tp, CANBBOLT);
+		    breath = "lightning bolt";
+		}
+
+		/* Or can it breathe gas? */
+		else if (on(*tp, CANBGAS)) {
+		    turn_off(*tp, CANBGAS);
+		    breath = "chlorine gas";
+		}
+
+		/* Or can it breathe ice? */
+		else if (on(*tp, CANBICE)) {
+		    turn_off(*tp, CANBICE);
+		    breath = "ice";
+		}
+
+		else if (on(*tp, CANBPGAS)) {
+		    turn_off(*tp, CANBPGAS);
+		    breath = "nerve gas";
+		}
+
+		/* can it breathe sleeping gas */
+		else if (on(*tp, CANBSGAS)) {
+		    turn_off(*tp, CANBSGAS);
+		    breath = "sleeping gas";
+		}
+
+		/* can it breathe slow gas */
+		else if (on(*tp, CANBSLGAS)) {
+		    turn_off(*tp, CANBSLGAS);
+		    breath = "slow gas";
+		}
+		/* can it breathe confusion gas */
+		else if (on(*tp, CANBCGAS)) {
+		    turn_off(*tp, CANBCGAS);
+		    breath = "confusion gas";
+		}
+		/* can it breathe fear gas */
+		else {
+		    turn_off(*tp, CANBFGAS);
+		    breath = "fear gas";
+		}
+
+		/* Now breathe -- sets "monst_dead" if it kills someone */
+		*mdead = shoot_bolt(	tp, *er, *shoot_dir, FALSE, 
+				tp->t_index, breath, damage);
+
+		ch_ret = *er;
+		running = FALSE;
+		if (*mdead) return(TRUE);
+    }
+
+    /* We may shoot missiles if we can */
+    else if (on(*tp, CANMISSILE) 		&& 
+	    (shoot_dir = can_shoot(er, ee))	&&
+	    !on(player, ISINWALL)		&& 
+	    (rnd(100) < 75)) {
+	    static struct object missile =
+	    {
+		MISSILE, {0, 0}, "", 0, "", "0d4 " , NULL, 0, WS_MISSILE, 100, 1
+	    };
+
+	    sprintf(missile.o_hurldmg, "%dd4", tp->t_stats.s_lvl);
+	    do_motion(&missile, shoot_dir->y, shoot_dir->x, tp);
+	    hit_monster(unc(missile.o_pos), &missile, tp);
+	    turn_off(*tp, CANMISSILE);
+	    ch_ret = *er;
+	    running = FALSE;
+    }
+
+    /* We may use a sonic blast if we can */
+    else if (on(*tp, CANSONIC)			&& 
+	    (dist < BOLT_LENGTH*2)		&&
+	    (shoot_dir = can_shoot(er, ee))	&&
+	    !on(player, ISINWALL)		&& 
+	    (rnd(100) < 50)) {
+	    static struct object blast =
+	    {
+		MISSILE, {0, 0}, "", 0, "", "150" , NULL, 0, 0, 0, 0
+	    };
+
+	    turn_off(*tp, CANSONIC);
+	    do_motion(&blast, shoot_dir->y, shoot_dir->x, tp);
+	    damage = 150;
+	    if (save(VS_BREATH, &player, -3))
+		damage /= 2;
+	    msg ("The %s's sonic blast hits you", monsters[tp->t_index].m_name);
+	    if ((pstats.s_hpt -= damage) <= 0)
+		death(tp->t_index);
+	    ch_ret = *er;
+	    running = FALSE;
+    }
+    /*
+     * If we have a special magic item, we might use it.  We will restrict
+     * this options to uniques with relics for now.
+     */
+    else if (on(*tp, ISUNIQUE) && m_use_item(tp, er, ee)) {
+	    ch_ret = *er;
+	    running = FALSE;
+    }
+    /* 
+     * If we can shoot or throw something, we might do so.
+     * If next to player, then 80% prob will fight.
+     */
+    else if(on(*tp, CANSHOOT)			&&
+	    (shoot_dir = can_shoot(er, ee))	&&
+	    !on(player, ISINWALL)		&&
+	    (dist > 3 || (rnd(100) > 80))	&&
+	    (weapon = get_hurl(tp))) {
+		missile(shoot_dir->y, shoot_dir->x, weapon, tp);
+		ch_ret = *er;
+	}
+
+    /*
+     * Otherwise, find the empty spot next to the chaser that is
+     * closest to the chasee.
+     */
+    else {
+	register int ey, ex, x, y;
+	register struct room *rer, *ree;
+	int dist_to_old = MININT; /* Dist from goal to old position */
+
+	/* Get rooms */
+	rer = roomin(er);	/* Room the chasER (monster) is in */	
+	ree = roomin(ee);	/* Room the chasEE is in */
+
+	/*
+	 * This will eventually hold where we move to get closer
+	 * If we can't find an empty spot, we stay where we are.
+	 */
+	dist = flee ? 0 : MAXINT;
+	ch_ret = *er;
+
+	/* Are we at our goal already? */
+	if (!flee && ce(ch_ret, *ee)) return(FALSE);
+
+	ey = er->y + 1;
+	ex = er->x + 1;
+
+	/* Check all possible moves */
+	for (x = er->x - 1; x <= ex; x++) {
+	    if (x < 0 || x >= COLS) /* Don't try off the board */
+		continue;
+	    for (y = er->y - 1; y <= ey; y++) {
+		coord tryp;
+
+		if ((y < 1) || (y >= LINES - 2)) /* Don't try off the board */
+		    continue;
+
+		/* Don't try the player if not going after the player */
+		if ((flee || !ce(hero, *ee)) && x == hero.x && y == hero.y) {
+		    next_player = TRUE;
+		    continue;
+		}
+
+		tryp.x = x;
+		tryp.y = y;
+
+		/* Is there a monster on this spot closer to our goal?
+		 * Don't look in our spot or where we were.
+		 */
+		if (!ce(tryp, *er) && !ce(tryp, tp->t_oldpos) &&
+		    isalpha(mch = CCHAR( mvwinch(mw, y, x) ) )) {
+		    int test_dist;
+
+		    test_dist = DISTANCE(y, x, ee->y, ee->x);
+		    if (test_dist <= 25 &&   /* Let's be fairly close */
+			test_dist < monst_dist) {
+			/* Could we really move there? */
+			mvwaddch(mw, y, x, ' '); /* Temporarily blank monst */
+			if (diag_ok(er, &tryp, tp)) monst_dist = test_dist;
+			mvwaddch(mw, y, x, mch); /* Restore monster */
+		    }
+		}
+
+		/* Can we move onto the spot? */	
+		if (!diag_ok(er, &tryp, tp)) continue;
+
+		ch = CCHAR( mvwinch(cw, y, x) );	/* Screen character */
+
+		/* Stepping on player is NOT okay if we are fleeing */
+		if (step_ok(y, x, NOMONST, tp) &&
+		    (off(*tp, ISFLEE) || ch != PLAYER))
+		{
+		    /*
+		     * If it is a trap, an intelligent monster may not
+		     * step on it (unless our hero is on top!)
+		     */
+		    if ((isatrap(ch))			&& 
+			(rnd(10) < tp->t_stats.s_intel) &&
+			(!on(*tp, ISFLY))		&&
+			(y != hero.y || x != hero.x)) 
+			    continue;
+
+		    /*
+		     * OK -- this place counts
+		     */
+		    thisdist = DISTANCE(y, x, ee->y, ee->x);
+
+		    /* Adjust distance if we are being shot at */
+		    if (tp->t_wasshot && tp->t_stats.s_intel > 5 &&
+			ce(hero, *ee)) {
+			/* Move out of line of sight */
+			if (straight_shot(tryp.y, tryp.x, ee->y, ee->x, NULL)) {
+			    if (flee) thisdist -= SHOTPENALTY;
+			    else thisdist += SHOTPENALTY;
+			}
+
+			/* But do we want to leave the room? */
+			else if (rer && rer == ree && ch == DOOR)
+			    thisdist += DOORPENALTY;
+		    }
+
+		    /* Don't move to the last position if we can help it
+		     * (unless out prey just moved there)
+		     */
+		    if (ce(tryp, tp->t_oldpos) && (flee || !ce(tryp, hero)))
+			dist_to_old = thisdist;
+
+		    else if ((flee && (thisdist > dist)) ||
+			(!flee && (thisdist < dist)))
+		    {
+			ch_ret = tryp;
+			dist = thisdist;
+		    }
+		}
+	    }
+	}
+
+	/* If we aren't trying to get the player, but he is in our way,
+	 * hit him (unless we have been turned)
+	 */
+	if (next_player && off(*tp, WASTURNED) &&
+	    ((flee && ce(ch_ret, *er)) ||
+	     (!flee && DISTANCE(er->y, er->x, ee->y, ee->x) < dist)) &&
+	    step_ok(tp->t_dest->y, tp->t_dest->x, NOMONST, tp)) {
+	    /* Okay to hit player */
+	    ch_ret = hero;
+	    return(FALSE);
+	}
+
+
+	/* If we can't get closer to the player (if that's our goal)
+	 * because other monsters are in the way, just stay put
+	 */
+	if (!flee && ce(hero, *ee) && monst_dist < MAXINT &&
+	    DISTANCE(er->y, er->x, hero.y, hero.x) < dist)
+		ch_ret = *er;
+
+	/* Do we want to go back to the last position? */
+	else if (dist_to_old != MININT &&      /* It is possible to move back */
+	    ((flee && dist == 0) ||	/* No other possible moves */
+	     (!flee && dist == MAXINT))) {
+	    /* Do we move back or just stay put (default)? */
+	    dist = DISTANCE(er->y, er->x, ee->y, ee->x); /* Current distance */
+	    if (!flee || (flee && (dist_to_old > dist))) ch_ret = tp->t_oldpos;
+	}
+    }
+
+    /* May actually hit here from a confused move */
+    return(!ce(ch_ret, hero));
+}
+
+/*
+ * do_chase:
+ *	Make one thing chase another.
+ */
+
+do_chase(th, flee)
+register struct thing *th;
+register bool flee; /* True if running away or player is inaccessible in wall */
+{
+    register struct room *rer, *ree,	/* room of chaser, room of chasee */
+			 *orig_rer,	/* Original room of chaser */
+			 *new_room;	/* new room of monster */
+    int dist = MININT;
+    int mindist = MAXINT, maxdist = MININT;
+    bool stoprun = FALSE,		/* TRUE means we are there */
+	 rundoor;			/* TRUE means run to a door */
+    bool mdead = 0;
+    char rch, sch;
+    coord *last_door=0,			/* Door we just came from */
+	   this;			/* Temporary destination for chaser */
+
+    /* Make sure the monster can move */
+    if (th->t_no_move != 0) {
+	th->t_no_move--;
+	return;
+    }
+
+    rer = roomin(&th->t_pos);	/* Find room of chaser */
+    ree = roomin(th->t_dest);	/* Find room of chasee */
+    orig_rer = rer;	/* Original room of chaser (including doors) */
+
+    /*
+     * We don't count monsters on doors as inside rooms for this routine
+     */
+    if ((sch = CCHAR( mvwinch(stdscr, th->t_pos.y, th->t_pos.x) )) == DOOR ||
+	sch == PASSAGE) {
+	rer = NULL;
+    }
+    this = *th->t_dest;
+
+    /*
+     * If we are not in a corridor and not a Xorn, then if we are running
+     * after the player, we run to a door if he is not in the same room.
+     * If we are fleeing, we run to a door if he IS in the same room.
+     * Note:  We don't bother with doors in mazes.
+     */
+    if (levtype != MAZELEV && rer != NULL && off(*th, CANINWALL)) {
+	if (flee) rundoor = (rer == ree);
+	else rundoor = (rer != ree);
+    }
+    else rundoor = FALSE;
+
+    if (rundoor) {
+	register struct linked_list *exitptr;	/* For looping through exits */
+	coord *exit;				/* A particular door */
+	int exity, exitx;			/* Door's coordinates */
+	char dch='\0';				/* Door character */
+
+	if (th->t_doorgoal)
+	    dch = CCHAR( mvwinch(stdscr, th->t_doorgoal->y, th->t_doorgoal->x) );
+	    
+	/* Do we have a valid goal? */
+	if ((dch == PASSAGE || dch == DOOR) &&  /* A real door */
+	    (!flee || !ce(*th->t_doorgoal, hero))) { /* Player should not
+						      * be at door if we are
+						      * running away
+						      */
+	    this = *th->t_doorgoal;
+	    dist = 0;	/* Indicate that we have our door */
+	}
+
+	/* Go through all the doors */
+	else for (exitptr = rer->r_exit; exitptr; exitptr = next(exitptr)) {
+	    exit = DOORPTR(exitptr);
+	    exity = exit->y;
+	    exitx = exit->x;
+
+	    /* Make sure it is a real door */
+	    dch = CCHAR( mvwinch(stdscr, exity, exitx) );
+	    if (dch == PASSAGE || dch == DOOR) {
+		/* Don't count a door if we are fleeing from the player and
+		 * he is standing on it
+		 */
+		if (flee && ce(*exit, hero)) continue;
+		
+		/* Were we just on this door? */
+		if (ce(*exit, th->t_oldpos)) last_door = exit;
+
+		else {
+		    dist = DISTANCE(th->t_dest->y, th->t_dest->x, exity, exitx);
+
+		    /* If fleeing, we want to maximize distance from door to
+		     * what we flee, and minimize distance from door to us.
+		     */
+		    if (flee)
+		       dist -= DISTANCE(th->t_pos.y, th->t_pos.x, exity, exitx);
+
+		    /* Maximize distance if fleeing, otherwise minimize it */
+		    if ((flee && (dist > maxdist)) ||
+			(!flee && (dist < mindist))) {
+			th->t_doorgoal = exit;	/* Use this door */
+			this = *exit;
+			mindist = maxdist = dist;
+		    }
+		}
+	    }
+	}
+
+	/* Could we not find a door? */
+	if (dist == MININT) {
+	    /* If we were on a door, go ahead and use it */
+	    if (last_door) {
+		th->t_doorgoal = last_door;
+		this = th->t_oldpos;
+		dist = 0;	/* Indicate that we found a door */
+	    }
+	    else th->t_doorgoal = NULL;	/* No more door goal */
+	}
+
+	/* Indicate that we do not want to flee from the door */
+	if (dist != MININT) flee = FALSE;
+    }
+    else th->t_doorgoal = 0;	/* Not going to any door */
+
+    /*
+     * this now contains what we want to run to this time
+     * so we run to it.  If we hit it we either want to fight it
+     * or stop running
+     */
+    if (!chase(th, &this, flee, &mdead)) {
+	if (ce(ch_ret, hero)) {
+	    /* merchants try to sell something --> others attack */
+	    if (on(*th, CANSELL)) sell(th);
+	    else attack(th, NULL, FALSE);
+	    return;
+	}
+	else if (on(*th, NOMOVE))
+	    stoprun = TRUE;
+    }
+
+    if (mdead) return;	/* Did monster kill someone? */
+
+    if (on(*th, NOMOVE)) return;
+
+    /* If we have a scavenger, it can pick something up */
+    if (on(*th, ISSCAVENGE)) {
+	register struct linked_list *n_item, *o_item;
+
+	while ((n_item = find_obj(ch_ret.y, ch_ret.x)) != NULL) {
+	    char floor = (roomin(&ch_ret) == NULL) ? PASSAGE : FLOOR;
+	    register struct object *n_obj, *o_obj;
+
+	    /*
+	     * see if he's got one of this group already
+	     */
+	    o_item = NULL;
+	    n_obj = OBJPTR(n_item);
+	    detach(lvl_obj, n_item);
+	    if (n_obj->o_group) {
+		for(o_item = th->t_pack; o_item != NULL; o_item = next(o_item)){
+		    o_obj = OBJPTR(o_item);
+		    if (o_obj->o_group == n_obj->o_group) {
+			o_obj->o_count += n_obj->o_count;
+			o_discard(n_item);
+			break;
+		    }
+		}
+	    }
+	    if (o_item == NULL) {	/* didn't find it */
+	        attach(th->t_pack, n_item);
+	    }
+	    if (cansee(ch_ret.y, ch_ret.x))
+	        mvwaddch(cw, ch_ret.y, ch_ret.x, floor);
+	    mvaddch(ch_ret.y, ch_ret.x, floor);
+	}
+    }
+
+    mvwaddch(cw, th->t_pos.y, th->t_pos.x, th->t_oldch);
+    sch = CCHAR( mvwinch(cw, ch_ret.y, ch_ret.x) ); /* What player sees */
+    rch = CCHAR( mvwinch(stdscr, ch_ret.y, ch_ret.x) ); /* What's really there */
+
+    /* Get new room of monster */
+    new_room=roomin(&ch_ret);
+
+    /* If we have a tunneling monster, it may be making a tunnel */
+    if (on(*th, CANTUNNEL)	&&
+	(rch == SECRETDOOR || rch == WALL || rch == '|' || rch == '-')) {
+	char nch;	/* The new look to the tunnel */
+
+	if (rch == WALL) nch = PASSAGE;
+	else if (levtype == MAZELEV) nch = FLOOR;
+	else nch = DOOR;
+	addch(nch);
+
+	if (cansee(ch_ret.y, ch_ret.x)) sch = nch; /* Can player see this? */
+
+	/* Does this make a new exit? */
+	if (rch == '|' || rch == '-') {
+	    struct linked_list *newroom;
+	    coord *exit;
+
+	    newroom = new_item(sizeof(coord));
+	    exit = DOORPTR(newroom);
+	    *exit = ch_ret;
+	    attach(new_room->r_exit, newroom);
+	}
+    }
+
+    /* Mark if the monster is inside a wall */
+    if (isrock(mvinch(ch_ret.y, ch_ret.x))) turn_on(*th, ISINWALL);
+    else turn_off(*th, ISINWALL);
+
+    /* If the monster can illuminate rooms, check for a change */
+    if (on(*th, HASFIRE)) {
+	register struct linked_list *fire_item;
+
+	/* Is monster entering a room? */
+	if (orig_rer != new_room && new_room != NULL) {
+	    fire_item = creat_item();	/* Get an item-only structure */
+	    ldata(fire_item) = (char *) th;
+
+	    attach(new_room->r_fires, fire_item);
+	    new_room->r_flags |= HASFIRE;
+
+	    if (cansee(ch_ret.y, ch_ret.x) && next(new_room->r_fires) == NULL)
+		light(&hero);
+	}
+
+	/* Is monster leaving a room? */
+	if (orig_rer != new_room && orig_rer != NULL) {
+	    /* Find the bugger in the list and delete him */
+	    for (fire_item = orig_rer->r_fires; fire_item != NULL;
+		 fire_item = next(fire_item)) {
+		if (THINGPTR(fire_item) == th)  {	/* Found him! */
+		    detach(orig_rer->r_fires, fire_item);
+		    destroy_item(fire_item);
+		    if (orig_rer->r_fires == NULL) {
+			orig_rer->r_flags &= ~HASFIRE;
+			if (cansee(th->t_pos.y, th->t_pos.x))
+			    light(&th->t_pos);
+		    }
+		    break;
+		}
+	    }
+	}
+    }
+
+    /* If monster is entering player's room and player can see it,
+     * stop the player's running.
+     */
+    if (new_room != orig_rer && new_room != NULL  &&
+	new_room == ree && cansee(unc(ch_ret))    &&
+	(off(*th, ISINVIS)     || on(player, CANSEE)) &&
+	(off(*th, ISSHADOW)    || on(player, CANSEE)) &&
+	(off(*th, CANSURPRISE) || ISWEARING(R_ALERT)))
+		running = FALSE;
+
+/*
+    if (rer != NULL && !lit_room(orig_rer) && sch == FLOOR &&
+	DISTANCE(ch_ret.y, ch_ret.x, th->t_pos.y, th->t_pos.x) < 3 &&
+	off(player, ISBLIND))
+	    th->t_oldch = ' ';
+    else
+ */
+	th->t_oldch = sch;
+
+    /* Let's display those creatures that we can see. */
+    if (cansee(unc(ch_ret)) &&
+	off(*th, ISINWALL) &&
+	!invisible(th))
+        mvwaddch(cw, ch_ret.y, ch_ret.x, th->t_type);
+
+    /*
+     * Blank out the old position and record the new position --
+     * the blanking must be done first in case the positions are the same.
+     */
+    mvwaddch(mw, th->t_pos.y, th->t_pos.x, ' ');
+    mvwaddch(mw, ch_ret.y, ch_ret.x, th->t_type);
+
+    /* Record monster's last position (if new one is different) */
+    if (!ce(ch_ret, th->t_pos)) th->t_oldpos = th->t_pos;
+    th->t_pos = ch_ret;		/* Mark the monster's new position */
+
+    /* If the monster is on a trap, trap it */
+    sch = CCHAR( mvinch(ch_ret.y, ch_ret.x) );
+    if (isatrap(sch)) {
+	if (cansee(ch_ret.y, ch_ret.x)) th->t_oldch = sch;
+	be_trapped(th, &ch_ret);
+    }
+
+
+    /*
+     * And stop running if need be
+     */
+    if (stoprun && ce(th->t_pos, *(th->t_dest)))
+	turn_off(*th, ISRUN);
+}
+
+
+/* 
+ * Get_hurl returns the weapon that the monster will "throw" if he has one 
+ */
+
+struct linked_list *
+get_hurl(tp)
+register struct thing *tp;
+{
+    struct linked_list *arrow, *bolt, *rock;
+    register struct linked_list *pitem;
+    bool bow=FALSE, crossbow=FALSE, sling=FALSE;
+
+    arrow = bolt = rock = NULL;	/* Don't point to anything to begin with */
+    for (pitem=tp->t_pack; pitem; pitem=next(pitem))
+	if ((OBJPTR(pitem))->o_type == WEAPON)
+	    switch ((OBJPTR(pitem))->o_which) {
+		case BOW:	bow = TRUE;
+		when CROSSBOW:	crossbow = TRUE;
+		when SLING:	sling = TRUE;
+		when ROCK:	rock = pitem;
+		when ARROW:	arrow = pitem;
+		when BOLT:	bolt = pitem;
+	    }
+    
+    /* Use crossbow bolt if possible */
+    if (crossbow && bolt) return(bolt);
+    if (bow && arrow) return(arrow);
+    if (sling && rock) return(rock);
+    return(NULL);
+}
+
+/*
+ * runners:
+ *	Make all the running monsters move.
+ */
+
+runners()
+{
+    register struct linked_list *item;
+    register struct thing *tp = NULL;
+
+    /*
+     * loop thru the list of running (wandering) monsters and see what
+     * each one will do this time. 
+     *
+     * Note: the special case that one of this buggers kills another.
+     *	     if this happens than we have to see if the monster killed
+     *	     himself or someone else. In case its himself we have to get next
+     *	     one immediately. If it wasn't we have to get next one at very
+     *	     end in case he killed the next one.
+     */
+
+    for (item = mlist; item != NULL; item = next(item)) {
+	tp = THINGPTR(item);
+	turn_on(*tp, ISREADY);
+    }
+
+    for (;;) {
+	for (item = mlist; item != NULL; item = next(item)) {
+	    tp = THINGPTR(item);
+
+	    if (on(*tp, ISREADY))
+		break;
+	}
+
+	if (item == NULL)
+	    break;
+
+	turn_off(*tp, ISREADY);
+
+	if (on(*tp, ISHELD) && rnd(tp->t_stats.s_lvl) > 11) {
+	    turn_off(*tp, ISHELD);
+	    turn_on(*tp, ISRUN);
+	    turn_off(*tp, ISDISGUISE);
+	    tp->t_dest = &hero;
+	    if (tp->t_stats.s_hpt < tp->maxstats.s_hpt)
+		turn_on(*tp, ISFLEE);
+	    if (cansee(tp->t_pos.y, tp->t_pos.x))
+		msg("The %s breaks free from the hold spell", 
+			monsters[tp->t_index].m_name);
+	}
+	if (off(*tp, ISHELD) && on(*tp, ISRUN)) {
+	    register bool flee;
+
+	    /* Should monster run away? */
+	    flee = on(*tp, ISFLEE) ||
+		((tp->t_dest == &hero) && on(player, ISINWALL) &&
+		 off(*tp, CANINWALL));
+
+	    if (off(*tp, ISSLOW) || tp->t_turn) {
+		doctor(tp);
+		do_chase(tp, flee);
+	    }
+	    if (off(*tp, ISDEAD) && off(*tp, ISELSEWHERE) && on(*tp, ISHASTE)) {
+		doctor(tp);
+		do_chase(tp, flee);
+	    }
+	    if (off(*tp, ISDEAD) && off(*tp, ISELSEWHERE)) {
+		tp->t_turn ^= TRUE;
+		tp->t_wasshot = FALSE;	/* Not shot anymore */
+	    }
+	}
+    }
+}
+
+/*
+ * runto:
+ *	Set a monster running after something
+ */
+
+runto(runner, spot)
+register struct thing *runner;
+coord *spot;
+{
+    /*
+     * Start the beastie running
+     */
+    runner->t_dest = spot;
+    turn_on(*runner, ISRUN);
+    turn_off(*runner, ISDISGUISE);
+}
+
+
+
+/*
+ * straight_shot:
+ *	See if there is a straight line of sight between the two
+ *	given coordinates.  If shooting is not NULL, it is a pointer
+ *	to a structure which should be filled with the direction
+ *	to shoot (if there is a line of sight).  If shooting, monsters
+ *	get in the way.  Otherwise, they do not.
+ */
+
+bool
+straight_shot(ery, erx, eey, eex, shooting)
+register int ery, erx, eey, eex;
+register coord *shooting;
+{
+    register int dy, dx;	/* Deltas */
+    char ch;
+
+    /* Does the monster have a straight shot at player */
+    if ((ery != eey) && (erx != eex) &&
+	(abs(ery - eey) != abs(erx - eex))) return(FALSE);
+
+    /* Get the direction to shoot */
+    if (eey > ery) dy = 1;
+    else if (eey == ery) dy = 0;
+    else dy = -1;
+
+    if (eex > erx) dx = 1;
+    else if (eex == erx) dx = 0;
+    else dx = -1;
+
+    /* Make sure we have free area all the way to the player */
+    ery += dy;
+    erx += dx;
+    while ((ery != eey) || (erx != eex)) {
+	switch (ch = CCHAR( winat(ery, erx) )) {
+	    case '|':
+	    case '-':
+	    case WALL:
+	    case DOOR:
+	    case SECRETDOOR:
+	    case FOREST:
+		return(FALSE);
+	    default:
+		if (shooting && isalpha(ch)) return(FALSE);
+	}
+	ery += dy;
+	erx += dx;
+    }
+
+    if (shooting) {	/* If we are shooting -- put in the directions */
+	shooting->y = dy;
+	shooting->x = dx;
+    }
+    return(TRUE);
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/command.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,938 @@
+/*
+ * Read and execute the user commands
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include <limits.h>
+#include <ctype.h>
+#include <signal.h>
+#include "mach_dep.h"
+#include "rogue.h"
+
+/*
+ * command:
+ *	Process the user commands
+ */
+
+command()
+{
+    register char ch;
+    register int ntimes = 1;			/* Number of player moves */
+    static char countch, direction, newcount = FALSE;
+    struct linked_list *item;
+    bool an_after = FALSE;
+
+    if (on(player, ISHASTE)) {
+	ntimes++;
+	turns--;	/* correct for later */
+    }
+    if (on(player, ISSLOW) || on(player, ISDANCE)) {
+	if (player.t_turn != TRUE) {
+	    ntimes--;
+	    turns++;
+	    an_after = TRUE;
+	}
+	player.t_turn ^= TRUE;
+    }
+
+    /*
+     * Let the daemons start up
+     */
+    do_daemons(BEFORE);
+    do_fuses(BEFORE);
+    while (ntimes-- > 0)
+    {	
+	/* One more tick of the clock. */
+	if ((++turns % DAYLENGTH) == 0) {
+	    daytime ^= TRUE;
+	    if (levtype == OUTSIDE) {
+		if (daytime) msg("The sun rises above the horizon");
+		else msg("The sun sinks below the horizon");
+	    }
+	    light(&hero);
+	}
+
+	look(after, FALSE);
+	if (!running) door_stop = FALSE;
+	lastscore = purse;
+	wmove(cw, hero.y, hero.x);
+	if (!((running || count) && jump)) {
+	    status(FALSE);
+	    wmove(cw, hero.y, hero.x);
+	    draw(cw);			/* Draw screen */
+	}
+	take = 0;
+	after = TRUE;
+	/*
+	 * Read command or continue run
+	 */
+	if (!no_command)
+	{
+	    if (running) {
+		/* If in a corridor or maze, if we are at a turn with only one
+		 * way to go, turn that way.
+		 */
+		if ((winat(hero.y, hero.x) == PASSAGE || levtype == MAZELEV) &&
+		    off(player, ISHUH) && (off(player, ISBLIND))) {
+		    int y, x;
+		    if (getdelta(runch, &y, &x) == TRUE) {
+			corr_move(y, x);
+		    }
+		}
+	        ch = runch;
+	    }
+	    else if (count) ch = countch;
+	    else
+	    {
+		ch = readchar();
+		if (mpos != 0 && !running)	/* Erase message if its there */
+		    msg("");
+	    }
+	}
+	else ch = '.';
+	if (no_command)
+	{
+	    if (--no_command == 0)
+		msg("You can move again.");
+	}
+	else
+	{
+	    /*
+	     * check for prefixes
+	     */
+	    if (isdigit(ch))
+	    {
+		count = 0;
+		newcount = TRUE;
+		while (isdigit(ch))
+		{
+		    count = count * 10 + (ch - '0');
+		    if (count > 255)
+			count = 255;
+		    ch = readchar();
+		}
+		countch = ch;
+		/*
+		 * turn off count for commands which don't make sense
+		 * to repeat
+		 */
+		switch (ch) {
+		    case 'h': case 'j': case 'k': case 'l':
+		    case 'y': case 'u': case 'b': case 'n':
+		    case 'H': case 'J': case 'K': case 'L':
+		    case 'Y': case 'U': case 'B': case 'N':
+		    case 'q': case 'r': case 's': case 'f':
+		    case 't': case 'C': case 'I': case '.':
+		    case 'z': case 'p':
+			break;
+		    default:
+			count = 0;
+		}
+	    }
+
+	    /* Save current direction */
+	    if (!running) /* If running, it is already saved */
+	    switch (ch) {
+		case 'h': case 'j': case 'k': case 'l':
+		case 'y': case 'u': case 'b': case 'n':
+		case 'H': case 'J': case 'K': case 'L':
+		case 'Y': case 'U': case 'B': case 'N':
+		    runch = tolower(ch);
+	    }
+
+	    /* Perform the action */
+	    switch (ch) {
+		case 'f':
+		    if (!on(player, ISBLIND))
+		    {
+			door_stop = TRUE;
+			firstmove = TRUE;
+		    }
+		    if (count && !newcount)
+			ch = direction;
+		    else
+			ch = readchar();
+		    switch (ch)
+		    {
+			case 'h': case 'j': case 'k': case 'l':
+			case 'y': case 'u': case 'b': case 'n':
+			    ch = toupper(ch);
+		    }
+		    direction = ch;
+	    }
+	    newcount = FALSE;
+	    /*
+	     * execute a command
+	     */
+	    if (count && !running)
+		count--;
+	    switch (ch)
+	    {
+		case '!' : shell();
+		when 'h' : do_move(0, -1);
+		when 'j' : do_move(1, 0);
+		when 'k' : do_move(-1, 0);
+		when 'l' : do_move(0, 1);
+		when 'y' : do_move(-1, -1);
+		when 'u' : do_move(-1, 1);
+		when 'b' : do_move(1, -1);
+		when 'n' : do_move(1, 1);
+		when 'H' : do_run('h');
+		when 'J' : do_run('j');
+		when 'K' : do_run('k');
+		when 'L' : do_run('l');
+		when 'Y' : do_run('y');
+		when 'U' : do_run('u');
+		when 'B' : do_run('b');
+		when 'N' : do_run('n');
+		when 't':
+		    if((item=get_item(pack,"throw", ALL)) != NULL && get_dir())
+			missile(delta.y, delta.x, item, &player);
+		    else
+			after = FALSE;
+		when 'Q' : after = FALSE; quit(-1);
+		when 'i' : after = FALSE; inventory(pack, ALL);
+		when 'I' : after = FALSE; picky_inven();
+		when 'd' : drop(NULL);
+		when 'P' : grab(hero.y, hero.x);
+		when 'q' : quaff(-1, NULL, TRUE);
+		when 'r' : read_scroll(-1, NULL, TRUE);
+		when 'e' : eat();
+		when 'w' : wield();
+		when 'W' : wear();
+		when 'T' : take_off();
+		when 'o' : option();
+		when 'c' : call(FALSE);
+		when 'm' : call(TRUE);
+		when '>' : after = FALSE; d_level();
+		when '<' : after = FALSE; u_level();
+		when '?' : after = FALSE; help();
+		when '/' : after = FALSE; identify();
+		when CTRL('U') : use_mm(-1);
+		when CTRL('T') :
+		    if (get_dir()) steal();
+		    else after = FALSE;
+		when 'D' : dip_it();
+		when 'G' : gsense();
+		when '^' : set_trap(&player, hero.y, hero.x);
+		when 's' : search(FALSE, FALSE);
+		when 'z' : if (!do_zap(TRUE, NULL, FALSE))
+				after=FALSE;
+		when 'p' : pray();
+		when 'C' : cast();
+		when 'a' :
+		    if (get_dir())
+			affect();
+		    else after = FALSE;
+		when 'v' : after = FALSE;
+			   msg("Advanced Rogue Version %s.",
+				release);
+		when CTRL('L') : after = FALSE; clearok(curscr, TRUE);
+				touchwin(cw); /* MMMMMMMMMM */
+		when CTRL('R') : after = FALSE; msg(huh);
+		when 'S' : 
+		    after = FALSE;
+		    if (save_game())
+		    {
+			wclear(cw);
+			draw(cw);
+			endwin();
+			printf("\n");
+			exit(0);
+		    }
+		when '.' : ;			/* Rest command */
+		when ' ' : after = FALSE;	/* Do Nothing */
+#ifdef WIZARD
+		when CTRL('P') :
+		    after = FALSE;
+		    if (wizard)
+		    {
+			wizard = FALSE;
+			trader = 0;
+			msg("Not wizard any more");
+		    }
+		    else
+		    {
+			if (waswizard || passwd())
+			{
+			    msg("Welcome, oh mighty wizard.");
+			    wizard = waswizard = TRUE;
+			}
+			else
+			    msg("Sorry");
+		    }
+#endif
+		when ESCAPE :	/* Escape */
+		    door_stop = FALSE;
+		    count = 0;
+		    after = FALSE;
+		when '#':
+		    if (levtype == POSTLEV)		/* buy something */
+			buy_it();
+		    after = FALSE;
+		when '$':
+		    if (levtype == POSTLEV)		/* price something */
+			price_it();
+		    after = FALSE;
+		when '%':
+		    if (levtype == POSTLEV)		/* sell something */
+			sell_it();
+		    after = FALSE;
+		otherwise :
+		    after = FALSE;
+#ifdef WIZARD
+		    if (wizard) switch (ch)
+		    {
+			case 'M' : create_obj(TRUE, 0, 0);
+			when CTRL('W') : wanderer();
+			when CTRL('I') : inventory(lvl_obj, ALL);
+			when CTRL('Z') : whatis(NULL);
+			when CTRL('D') : level++; new_level(NORMLEV);
+			when CTRL('F') : overlay(stdscr,cw);
+			when CTRL('X') : overlay(mw,cw);
+			when CTRL('J') : teleport();
+			when CTRL('E') : sprintf(outstring,"food left: %d\tfood level: %d", 
+						food_left, foodlev);
+				       msg(outstring);
+			when CTRL('A') : activity();
+			when CTRL('C') : 
+			{
+			    int tlev;
+			    prbuf[0] = '\0';
+			    msg("Which level? ");
+			    if(get_str(prbuf,cw) == NORM) {
+				tlev = atoi(prbuf);
+				if(tlev < 1) {
+				    mpos = 0;
+				    msg("Illegal level.");
+				}
+				else if (tlev > 199) {
+					levtype = MAZELEV;
+					level = tlev - 200 + 1;
+				}
+				else if (tlev > 99) {
+					levtype = POSTLEV;
+					level = tlev - 100 + 1;
+				} 
+				else {
+					levtype = NORMLEV;
+					level = tlev;
+				}
+				new_level(levtype);
+			    }
+			}
+			when CTRL('N') :
+			{
+			    if ((item=get_item(pack, "charge", STICK)) != NULL){
+				(OBJPTR(item))->o_charges=10000;
+			    }
+			}
+			when CTRL('H') :
+			{
+			    register int i;
+			    register struct object *obj;
+
+			    for (i = 0; i < 9; i++)
+				raise_level(TRUE);
+			    /*
+			     * Give the rogue a sword 
+			     */
+			    if(cur_weapon==NULL || cur_weapon->o_type!=RELIC) {
+				item = spec_item(WEAPON, TWOSWORD, 5, 5);
+				add_pack(item, TRUE, NULL);
+				cur_weapon = OBJPTR(item);
+				cur_weapon->o_flags |= (ISKNOW | ISPROT);
+			    }
+			    /*
+			     * And his suit of armor
+			     */
+			    if (player.t_ctype == C_THIEF)
+				item = spec_item(ARMOR, STUDDED_LEATHER, 10, 0);
+			    else
+				item = spec_item(ARMOR, PLATE_ARMOR, 7, 0);
+			    obj = OBJPTR(item);
+			    obj->o_flags |= (ISKNOW | ISPROT);
+			    obj->o_weight = armors[PLATE_ARMOR].a_wght;
+			    cur_armor = obj;
+			    add_pack(item, TRUE, NULL);
+			    purse += 20000;
+			}
+			otherwise :
+			    msg("Illegal command '%s'.", unctrl(ch));
+			    count = 0;
+		    }
+		    else
+#endif
+		    {
+			msg("Illegal command '%s'.", unctrl(ch));
+			count = 0;
+			after = FALSE;
+		    }
+	    }
+	    /*
+	     * turn off flags if no longer needed
+	     */
+	    if (!running)
+		door_stop = FALSE;
+	}
+	/*
+	 * If he ran into something to take, let him pick it up.
+	 * unless its a trading post
+	 */
+	if (auto_pickup && take != 0 && levtype != POSTLEV)
+	    pick_up(take);
+	if (!running)
+	    door_stop = FALSE;
+
+	/* If after is true, mark an_after as true so that if
+	 * we are hasted, the first "after" will be noted.
+	 * if after is FALSE then stay in this loop
+	 */
+	if (after) an_after = TRUE;
+	else ntimes++;
+    }
+
+    /*
+     * Kick off the rest if the daemons and fuses
+     */
+    if (an_after)
+    {
+	/* 
+	 * If player is infested, take off a hit point 
+	 */
+	if (on(player, HASINFEST)) {
+	    if ((pstats.s_hpt -= infest_dam) <= 0) death(D_INFESTATION);
+	}
+	/* 
+	 * if player has body rot then take off five hits 
+	 */
+	if (on(player, DOROT)) {
+	     if ((pstats.s_hpt -= 5) <= 0) death(D_ROT);
+	}
+	do_daemons(AFTER);
+	do_fuses(AFTER);
+	if (!((running || count) && jump)) look(FALSE, FALSE);
+
+
+    }
+    t_free_list(monst_dead);
+}
+
+/*
+ * quit:
+ *	Have player make certain, then exit.
+ */
+
+void
+quit(int sig)
+{
+    NOOP(sig);
+
+    /*
+     * Reset the signal in case we got here via an interrupt
+     */
+    if (signal(SIGINT, &quit) != &quit)
+	mpos = 0;
+    msg("Really quit? ");
+    draw(cw);
+    if (readchar() == 'y')
+    {
+	clear();
+	move(LINES-1, 0);
+	draw(stdscr);
+	score(pstats.s_exp + (long) purse, CHICKEN, 0);
+	exit(0);
+    }
+    else
+    {
+	signal(SIGINT, quit);
+	wmove(cw, 0, 0);
+	wclrtoeol(cw);
+	status(FALSE);
+	draw(cw);
+	mpos = 0;
+	count = 0;
+	running = FALSE;
+    }
+}
+
+/*
+ * bugkill:
+ *	killed by a program bug instead of voluntarily.
+ */
+
+void
+bugkill(sig)
+int sig;
+{
+    signal(sig, quit);	/* If we get it again, give up */
+    death(D_SIGNAL);	/* Killed by a bug */
+}
+
+
+/*
+ * search:
+ *	Player gropes about him to find hidden things.
+ */
+
+search(is_thief, door_chime)
+register bool is_thief, door_chime;
+{
+    register int x, y;
+    register char ch,	/* The trap or door character */
+		 sch,	/* Trap or door character (as seen on screen) */
+		 mch;	/* Monster, if a monster is on the trap or door */
+    register struct linked_list *item;
+    register struct thing *mp; /* Status on surrounding monster */
+
+    /*
+     * Look all around the hero, if there is something hidden there,
+     * give him a chance to find it.  If its found, display it.
+     */
+    if (on(player, ISBLIND))
+	return;
+    for (x = hero.x - 1; x <= hero.x + 1; x++)
+	for (y = hero.y - 1; y <= hero.y + 1; y++)
+	{
+	    if (y==hero.y && x==hero.x)
+		continue;
+
+	    /* Mch and ch will be the same unless there is a monster here */
+	    mch = CCHAR( winat(y, x) );
+	    ch = CCHAR( mvwinch(stdscr, y, x) );
+	    sch = CCHAR( mvwinch(cw, y, x) );	/* What's on the screen */
+
+	    if (door_chime == FALSE && isatrap(ch)) {
+		    register struct trap *tp;
+
+		    /* Is there a monster on the trap? */
+		    if (mch != ch && (item = find_mons(y, x)) != NULL) {
+			mp = THINGPTR(item);
+			if (sch == mch) sch = mp->t_oldch;
+		    }
+		    else mp = NULL;
+
+		    /* 
+		     * is this one found already?
+		     */
+		    if (isatrap(sch)) 
+			continue;	/* give him chance for other traps */
+		    tp = trap_at(y, x);
+		    /* 
+		     * if the thief set it then don't display it.
+		     * if its not a thief he has 50/50 shot
+		     */
+		    if((tp->tr_flags&ISTHIEFSET) || (!is_thief && rnd(100)>50))
+			continue;	/* give him chance for other traps */
+		    tp->tr_flags |= ISFOUND;
+
+		    /* Let's update the screen */
+		    if (mp != NULL && CCHAR(mvwinch(cw, y, x)) == mch)
+			mp->t_oldch = ch; /* Will change when monst moves */
+		    else mvwaddch(cw, y, x, ch);
+
+		    count = 0;
+		    running = FALSE;
+		    msg(tr_name(tp->tr_type));
+	    }
+	    else if (ch == SECRETDOOR) {
+		if (door_chime == TRUE || (!is_thief && rnd(100) < 20)) {
+		    /* Is there a monster on the door? */
+		    if (mch != ch && (item = find_mons(y, x)) != NULL) {
+			mp = THINGPTR(item);
+
+			/* Screen will change when monster moves */
+			if (sch == mch) mp->t_oldch = ch;
+		    }
+		    mvaddch(y, x, DOOR);
+		    count = 0;
+		}
+	    }
+	}
+}
+
+
+/*
+ * help:
+ *	Give single character help, or the whole mess if he wants it
+ */
+
+help()
+{
+    register struct h_list *strp = helpstr;
+#ifdef WIZARD
+    struct h_list *wizp = wiz_help;
+#endif
+    register char helpch;
+    register int cnt;
+
+    msg("Character you want help for (* for all): ");
+    helpch = readchar();
+    mpos = 0;
+    /*
+     * If its not a *, print the right help string
+     * or an error if he typed a funny character.
+     */
+    if (helpch != '*') {
+	wmove(cw, 0, 0);
+	while (strp->h_ch) {
+	    if (strp->h_ch == helpch) {
+		sprintf(outstring,"%s%s", unctrl(strp->h_ch), strp->h_desc);
+		msg(outstring);
+		return;
+	    }
+	    strp++;
+	}
+#ifdef WIZARD
+	if (wizard) {
+	    while (wizp->h_ch) {
+		if (wizp->h_ch == helpch) {
+		    sprintf(outstring,"%s%s", unctrl(wizp->h_ch), wizp->h_desc);
+		    msg(outstring);
+		    return;
+		}
+		wizp++;
+	    }
+	}
+#endif
+
+	msg("Unknown character '%s'", unctrl(helpch));
+	return;
+    }
+    /*
+     * Here we print help for everything.
+     * Then wait before we return to command mode
+     */
+    wclear(hw);
+    cnt = 0;
+    while (strp->h_ch) {
+	mvwaddstr(hw, cnt % 23, cnt > 22 ? 40 : 0, unctrl(strp->h_ch));
+	waddstr(hw, strp->h_desc);
+	strp++;
+	if (++cnt >= 46 && strp->h_ch) {
+	    wmove(hw, LINES-1, 0);
+	    wprintw(hw, morestr);
+	    draw(hw);
+	    wait_for(hw,' ');
+	    wclear(hw);
+	    cnt = 0;
+	}
+    }
+#ifdef WIZARD
+    if (wizard) {
+	while (wizp->h_ch) {
+	    mvwaddstr(hw, cnt % 23, cnt > 22 ? 40 : 0, unctrl(wizp->h_ch));
+	    waddstr(hw, wizp->h_desc);
+	    wizp++;
+	    if (++cnt >= 46 && wizp->h_ch) {
+		wmove(hw, LINES-1, 0);
+		wprintw(hw, morestr);
+		draw(hw);
+		wait_for(hw,' ');
+		wclear(hw);
+		cnt = 0;
+	    }
+	}
+    }
+#endif
+    wmove(hw, LINES-1, 0);
+    wprintw(hw, spacemsg);
+    draw(hw);
+    wait_for(hw,' ');
+    wclear(hw);
+    draw(hw);
+    wmove(cw, 0, 0);
+    wclrtoeol(cw);
+    status(FALSE);
+    touchwin(cw);
+}
+/*
+ * identify:
+ *	Tell the player what a certain thing is.
+ */
+
+identify()
+{
+    register char ch;
+    const char *str;
+
+    msg("What do you want identified? ");
+    ch = readchar();
+    mpos = 0;
+    if (ch == ESCAPE)
+    {
+	msg("");
+	return;
+    }
+    if (isalpha(ch))
+	str = monsters[id_monst(ch)].m_name;
+    else switch(ch)
+    {
+	case '|':
+	case '-':
+	    str = (levtype == OUTSIDE) ? "boundary of sector"
+				       : "wall of a room";
+	when GOLD:	str = "gold";
+	when STAIRS :	str = (levtype == OUTSIDE) ? "entrance to a dungeon"
+						   : "passage leading down";
+	when DOOR:	str = "door";
+	when FLOOR:	str = (levtype == OUTSIDE) ? "meadow" : "room floor";
+	when VPLAYER:	str = "the hero of the game ---> you";
+	when IPLAYER:	str = "you (but invisible)";
+	when PASSAGE:	str = "passage";
+	when POST:	str = "trading post";
+	when POOL:	str = (levtype == OUTSIDE) ? "lake"
+						   : "a shimmering pool";
+	when TRAPDOOR:	str = "trapdoor";
+	when ARROWTRAP:	str = "arrow trap";
+	when SLEEPTRAP:	str = "sleeping gas trap";
+	when BEARTRAP:	str = "bear trap";
+	when TELTRAP:	str = "teleport trap";
+	when DARTTRAP:	str = "dart trap";
+	when MAZETRAP:	str = "entrance to a maze";
+	when FOREST:	str = "forest";
+	when POTION:	str = "potion";
+	when SCROLL:	str = "scroll";
+	when FOOD:	str = "food";
+	when WEAPON:	str = "weapon";
+	when ' ' :	str = "solid rock";
+	when ARMOR:	str = "armor";
+	when MM:	str = "miscellaneous magic";
+	when RING:	str = "ring";
+	when STICK:	str = "wand or staff";
+	when SECRETDOOR:str = "secret door";
+	when RELIC:	str = "artifact";
+	otherwise:	str = "unknown character";
+    }
+    sprintf(outstring,"'%s' : %s", unctrl(ch), str);
+    msg(outstring);
+}
+
+/*
+ * d_level:
+ *	He wants to go down a level
+ */
+
+d_level()
+{
+    bool no_phase=FALSE;
+
+
+    /* If we are at a top-level trading post, we probably can't go down */
+    if (levtype == POSTLEV && level == 0 && rnd(100) < 80) {
+	msg("I see no way down.");
+	return;
+    }
+
+    if (winat(hero.y, hero.x) != STAIRS) {
+	if (off(player, CANINWALL) ||	/* Must use stairs if can't phase */
+	    (levtype == OUTSIDE && rnd(100) < 90)) {
+	    msg("I see no way down.");
+	    return;
+	}
+
+	/* Is there any dungeon left below? */
+	if (level >= nfloors) {
+	    msg("There is only solid rock below.");
+	    return;
+	}
+
+	extinguish(unphase);	/* Using phase to go down gets rid of it */
+	no_phase = TRUE;
+    }
+
+    /* Is this the bottom? */
+    if (level >= nfloors) {
+	msg("The stairway only goes up.");
+	return;
+    }
+
+    level++;
+    new_level(NORMLEV);
+    if (no_phase) unphase();
+}
+
+/*
+ * u_level:
+ *	He wants to go up a level
+ */
+
+u_level()
+{
+    bool no_phase = FALSE;
+    register struct linked_list *item;
+    struct thing *tp;
+    struct object *obj;
+
+    if (winat(hero.y, hero.x) != STAIRS) {
+	if (off(player, CANINWALL)) {	/* Must use stairs if can't phase */
+	    msg("I see no way up.");
+	    return;
+	}
+
+	extinguish(unphase);
+	no_phase = TRUE;
+    }
+
+    if (level == 0) {
+	msg("The stairway only goes down.");
+	return;
+    }
+
+    /*
+     * does he have the item he was quested to get?
+     */
+    if (level == 1) {
+	for (item = pack; item != NULL; item = next(item)) {
+	    obj = OBJPTR(item);
+	    if (obj->o_type == RELIC && obj->o_which == quest_item)
+		total_winner();
+	}
+    }
+    /*
+     * check to see if he trapped a UNIQUE, If he did then put it back
+     * in the monster table for next time
+     */
+    for (item = tlist; item != NULL; item = next(item)) {
+	tp = THINGPTR(item);
+	if (on(*tp, ISUNIQUE)) 
+	    monsters[tp->t_index].m_normal = TRUE;
+    }
+    t_free_list(tlist);	/* Monsters that fell below are long gone! */
+
+    if (levtype != POSTLEV) level--;
+    if (level > 0) new_level(NORMLEV);
+    else {
+	level = -1;	/* Indicate that we are new to the outside */
+	msg("You emerge into the %s", daytime ? "light" : "night");
+	new_level(OUTSIDE); 	/* Leaving the dungeon */
+    }
+
+    if (no_phase) unphase();
+}
+
+/*
+ * Let him escape for a while
+ */
+
+shell()
+{
+    /*
+     * Set the terminal back to original mode
+     */
+    wclear(hw);
+    wmove(hw, LINES-1, 0);
+    draw(hw);
+    endwin();
+    in_shell = TRUE;
+    fflush(stdout);
+    
+    md_shellescape();
+
+    printf(retstr);
+    fflush(stdout);
+    noecho();
+    raw();
+    keypad(cw,1);
+    in_shell = FALSE;
+    wait_for(hw,'\n');
+    clearok(cw, TRUE);
+    touchwin(cw);
+    wmove(cw,0,0);
+    draw(cw);
+}
+
+/*
+ * allow a user to call a potion, scroll, or ring something
+ */
+call(mark)
+bool mark;
+{
+    register struct object *obj;
+    register struct linked_list *item;
+    register char **guess = NULL, *elsewise = NULL;
+    register bool *know;
+
+    if (mark) item = get_item(pack, "mark", ALL);
+    else item = get_item(pack, "call", CALLABLE);
+    /*
+     * Make certain that it is somethings that we want to wear
+     */
+    if (item == NULL)
+	return;
+    obj = OBJPTR(item);
+    switch (obj->o_type)
+    {
+	case RING:
+	    guess = r_guess;
+	    know = r_know;
+	    elsewise = (r_guess[obj->o_which] != NULL ?
+			r_guess[obj->o_which] : r_stones[obj->o_which]);
+	when POTION:
+	    guess = p_guess;
+	    know = p_know;
+	    elsewise = (p_guess[obj->o_which] != NULL ?
+			p_guess[obj->o_which] : p_colors[obj->o_which]);
+	when SCROLL:
+	    guess = s_guess;
+	    know = s_know;
+	    elsewise = (s_guess[obj->o_which] != NULL ?
+			s_guess[obj->o_which] : s_names[obj->o_which]);
+	when STICK:
+	    guess = ws_guess;
+	    know = ws_know;
+	    elsewise = (ws_guess[obj->o_which] != NULL ?
+			ws_guess[obj->o_which] : ws_made[obj->o_which]);
+	when MM:
+	    guess = m_guess;
+	    know = m_know;
+	    elsewise = (m_guess[obj->o_which] != NULL ?
+			m_guess[obj->o_which] : "nothing");
+	otherwise:
+	    if (!mark) {
+		msg("You can't call that anything.");
+		return;
+	    }
+	    else know = (bool *) 0;
+    }
+    if ((obj->o_flags & ISPOST)	|| (know && know[obj->o_which]) && !mark) {
+	msg("That has already been identified.");
+	return;
+    }
+    if (mark) {
+	if (obj->o_mark[0]) {
+	    addmsg(terse ? "M" : "Was m");
+	    msg("arked \"%s\"", obj->o_mark);
+	}
+	msg(terse ? "Mark it: " : "What do you want to mark it? ");
+	prbuf[0] = '\0';
+    }
+    else {
+	addmsg(terse ? "C" : "Was c");
+	msg("alled \"%s\"", elsewise);
+	msg(terse ? "Call it: " : "What do you want to call it? ");
+	if (guess[obj->o_which] != NULL)
+	    free(guess[obj->o_which]);
+	strcpy(prbuf, elsewise);
+    }
+    if (get_str(prbuf, cw) == NORM) {
+	if (mark) {
+	    strncpy(obj->o_mark, prbuf, MARKLEN-1);
+	    obj->o_mark[MARKLEN-1] = '\0';
+	}
+	else {
+	    guess[obj->o_which] = new((unsigned int) strlen(prbuf) + 1);
+	    strcpy(guess[obj->o_which], prbuf);
+	}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/daemon.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,244 @@
+/*
+ * Contains functions for dealing with things that happen in the future.
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include "rogue.h"
+
+#define EMPTY		0
+#define DAEMON		-1
+
+#define _X_ { EMPTY }
+
+struct delayed_action d_list[MAXDAEMONS] = {
+	_X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_
+};
+struct delayed_action f_list[MAXFUSES] = {
+	_X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_,
+	_X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_
+};
+int demoncnt = 0;	/* number of active daemons */
+int fusecnt = 0;
+
+
+/*
+ * d_slot:
+ *	Find an empty slot in the daemon list
+ */
+struct delayed_action *
+d_slot()
+{
+	reg int i;
+	reg struct delayed_action *dev;
+
+	for (i = 0, dev = d_list; i < MAXDAEMONS; i++, dev++)
+		if (dev->d_type == EMPTY)
+			return dev;
+	return NULL;
+}
+
+/*
+ * f_slot:
+ *	Find an empty slot in the fuses list
+ */
+struct delayed_action *
+f_slot()
+{
+	reg int i;
+	reg struct delayed_action *dev;
+
+	for (i = 0, dev = f_list; i < MAXFUSES; i++, dev++)
+		if (dev->d_type == EMPTY)
+			return dev;
+	return NULL;
+}
+
+
+
+/*
+ * find_slot:
+ *	Find a particular slot in the table
+ */
+struct delayed_action *
+find_slot(func)
+reg int (*func)();
+{
+	reg int i;
+	reg struct delayed_action *dev;
+
+	for (i = 0, dev = f_list; i < MAXFUSES; i++, dev++)
+		if (dev->d_type != EMPTY && func == dev->d_func)
+			return dev;
+	return NULL;
+}
+
+
+/*
+ * daemon:
+ *	Start a daemon, takes a function.
+ */
+daemon(func, arg, type)
+reg int arg, type, (*func)();
+{
+	reg struct delayed_action *dev;
+
+	dev = d_slot();
+	if (dev != NULL) {
+		dev->d_type = type;
+		dev->d_func = func;
+		dev->d_arg = arg;
+		dev->d_time = DAEMON;
+		demoncnt += 1;			/* update count */
+	}
+}
+
+
+/*
+ * kill_daemon:
+ *	Remove a daemon from the list
+ */
+kill_daemon(func)
+reg int (*func)();
+{
+	reg struct delayed_action *dev;
+	reg int i;
+
+	for (i = 0, dev = d_list; i < MAXDAEMONS; i++, dev++) {
+		if (dev->d_type != EMPTY && func == dev->d_func)
+			break;
+	}
+	if (i >= MAXDAEMONS) return; /* if not found, forget it */
+	/*
+	 * Take it out of the list
+	 */
+	dev->d_type = EMPTY;
+	dev->d_arg = 0;
+	dev->d_func = NULL;
+	dev->d_time = 0;
+	demoncnt -= 1;			/* update count */
+}
+
+
+/*
+ * do_daemons:
+ *	Run all the daemons that are active with the current flag,
+ *	passing the argument to the function.
+ */
+do_daemons(flag)
+reg int flag;
+{
+	reg struct delayed_action *dev;
+
+	/*
+	 * Loop through the devil list
+	 */
+	for (dev = d_list; dev <= &d_list[MAXDAEMONS-1]; dev++)
+	/*
+	 * Executing each one, giving it the proper arguments
+	 */
+		if (dev->d_func != NULL && dev->d_type == flag && dev->d_time == DAEMON)
+			(*dev->d_func)(dev->d_arg);
+}
+
+
+/*
+ * fuse:
+ *	Start a fuse to go off in a certain number of turns
+ */
+fuse(func, arg, time, type)
+reg int (*func)(), arg, time, type;
+{
+	reg struct delayed_action *wire;
+
+	wire = f_slot();
+	if (wire != NULL) {
+		wire->d_type = type;
+		wire->d_func = func;
+		wire->d_arg = arg;
+		wire->d_time = time;
+		fusecnt += 1;			/* update count */
+	}
+}
+
+
+/*
+ * lengthen:
+ *	Increase the time until a fuse goes off
+ */
+lengthen(func, xtime)
+reg int (*func)(), xtime;
+{
+	reg struct delayed_action *wire;
+
+	if ((wire = find_slot(func)) == NULL)
+		return;
+	wire->d_time += xtime;
+}
+
+
+/*
+ * extinguish:
+ *	Put out a fuse
+ */
+extinguish(func)
+reg int (*func)();
+{
+	reg struct delayed_action *wire;
+
+	if ((wire = find_slot(func)) == NULL)
+		return;
+	wire->d_type = EMPTY;
+	wire->d_func = NULL;
+	wire->d_arg = 0;
+	wire->d_time = 0;
+	fusecnt -= 1;
+}
+
+
+/*
+ * do_fuses:
+ *	Decrement counters and start needed fuses
+ */
+do_fuses(flag)
+reg int flag;
+{
+	reg struct delayed_action *wire;
+
+	/*
+	 * Step though the list
+	 */
+	for (wire = f_list; wire <= &f_list[MAXFUSES-1]; wire++) {
+	/*
+	 * Decrementing counters and starting things we want.  We also need
+	 * to remove the fuse from the list once it has gone off.
+	 */
+	    if(flag == wire->d_type && wire->d_time > 0	&&
+	      --wire->d_time == 0) {
+		wire->d_type = EMPTY;
+		if (wire->d_func != NULL)
+		    (*wire->d_func)(wire->d_arg);
+		fusecnt -= 1;
+	    }
+	}
+}
+
+/*
+ * activity:
+ *	Show wizard number of demaons and memory blocks used
+ */
+activity()
+{
+	sprintf(outstring,"Daemons = %d : Fuses = %d : Memory Items = %d : Memory Used = %d",
+	    demoncnt,fusecnt,total,md_memused());
+	msg(outstring);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/daemons.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,487 @@
+/*
+ * All the daemon and fuse functions are in here
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include "rogue.h"
+
+int between = 0;
+
+/*
+ * doctor:
+ *	A healing daemon that restors hit points after rest
+ */
+
+doctor(tp)
+register struct thing *tp;
+{
+    register int ohp;
+    register int limit, new_points;
+    register struct stats *curp; /* current stats pointer */
+    register struct stats *maxp; /* max stats pointer */
+
+    curp = &(tp->t_stats);
+    maxp = &(tp->maxstats);
+    if (curp->s_hpt == maxp->s_hpt) {
+	tp->t_quiet = 0;
+	return;
+    }
+    tp->t_quiet++;
+    switch (tp->t_ctype) {
+	case C_MAGICIAN:
+	    limit = 8 - curp->s_lvl;
+	    new_points = curp->s_lvl - 3;
+	when C_THIEF:
+	    limit = 8 - curp->s_lvl;
+	    new_points = curp->s_lvl - 2;
+	when C_CLERIC:
+	    limit = 8 - curp->s_lvl;
+	    new_points = curp->s_lvl - 3;
+	when C_FIGHTER:
+	    limit = 16 - curp->s_lvl*2;
+	    new_points = curp->s_lvl - 5;
+	when C_MONSTER:
+	    limit = 16 - curp->s_lvl;
+	    new_points = curp->s_lvl - 6;
+	otherwise:
+	    debug("what a strange character you are!");
+	    return;
+    }
+    ohp = curp->s_hpt;
+    if (off(*tp, HASDISEASE) && off(*tp, DOROT)) {
+	if (curp->s_lvl < 8) {
+	    if (tp->t_quiet > limit) {
+		curp->s_hpt++;
+		tp->t_quiet = 0;
+	    }
+	}
+	else {
+	    if (tp->t_quiet >= 3) {
+		curp->s_hpt += rnd(new_points)+1;
+		tp->t_quiet = 0;
+	    }
+	}
+    }
+    if (tp == &player) {
+	if (ISRING(LEFT_1, R_REGEN)) curp->s_hpt++;
+	if (ISRING(LEFT_2, R_REGEN)) curp->s_hpt++;
+	if (ISRING(LEFT_3, R_REGEN)) curp->s_hpt++;
+	if (ISRING(LEFT_4, R_REGEN)) curp->s_hpt++;
+	if (ISRING(RIGHT_1, R_REGEN)) curp->s_hpt++;
+	if (ISRING(RIGHT_2, R_REGEN)) curp->s_hpt++;
+	if (ISRING(RIGHT_3, R_REGEN)) curp->s_hpt++;
+	if (ISRING(RIGHT_4, R_REGEN)) curp->s_hpt++;
+    }
+    if (on(*tp, ISREGEN))
+	curp->s_hpt += curp->s_lvl/10 + 1;
+    if (ohp != curp->s_hpt) {
+	if (curp->s_hpt >= maxp->s_hpt) {
+	    curp->s_hpt = maxp->s_hpt;
+	    if (off(*tp, WASTURNED) && on(*tp, ISFLEE) && tp != &player) {
+		turn_off(*tp, ISFLEE);
+		tp->t_oldpos = tp->t_pos;	/* Start our trek over */
+	    }
+	}
+    }
+}
+
+/*
+ * Swander:
+ *	Called when it is time to start rolling for wandering monsters
+ */
+
+swander()
+{
+    daemon(rollwand, 0, BEFORE);
+}
+
+/*
+ * rollwand:
+ *	Called to roll to see if a wandering monster starts up
+ */
+
+rollwand()
+{
+    if (++between >= 4)
+    {
+	/* Theives may not awaken a monster */
+	if ((roll(1, 6) == 4) &&
+	   ((player.t_ctype != C_THIEF) || (rnd(30) >= dex_compute()))) {
+	    if (levtype != POSTLEV)
+	        wanderer();
+	    kill_daemon(rollwand);
+	    fuse(swander, 0, WANDERTIME, BEFORE);
+	}
+	between = 0;
+    }
+}
+/*
+ * this function is a daemon called each turn when the character is a thief
+ */
+trap_look()
+{
+    if (rnd(100) < (2*dex_compute() + 5*pstats.s_lvl))
+	search(TRUE, FALSE);
+}
+
+/*
+ * unconfuse:
+ *	Release the poor player from his confusion
+ */
+
+unconfuse()
+{
+    turn_off(player, ISHUH);
+    msg("You feel less confused now");
+}
+
+
+/*
+ * unsee:
+ *	He lost his see invisible power
+ */
+
+unsee()
+{
+    if (!ISWEARING(R_SEEINVIS)) {
+	turn_off(player, CANSEE);
+	msg("The tingling feeling leaves your eyes");
+    }
+}
+
+/*
+ * unstink:
+ *	Remove to-hit handicap from player
+ */
+
+unstink()
+{
+    turn_off(player, HASSTINK);
+}
+
+/*
+ * unclrhead:
+ *	Player is no longer immune to confusion
+ */
+
+unclrhead()
+{
+    turn_off(player, ISCLEAR);
+    msg("The blue aura about your head fades away.");
+}
+
+/*
+ * unphase:
+ *	Player can no longer walk through walls
+ */
+
+unphase()
+{
+    turn_off(player, CANINWALL);
+    msg("Your dizzy feeling leaves you.");
+    if (!step_ok(hero.y, hero.x, NOMONST, &player)) death(D_PETRIFY);
+}
+
+/*
+ * land:
+ *	Player can no longer fly
+ */
+
+land()
+{
+    turn_off(player, ISFLY);
+    msg("You regain your normal weight");
+    running = FALSE;
+}
+
+/*
+ * sight:
+ *	He gets his sight back
+ */
+
+sight()
+{
+    if (on(player, ISBLIND))
+    {
+	extinguish(sight);
+	turn_off(player, ISBLIND);
+	light(&hero);
+	msg("The veil of darkness lifts");
+    }
+}
+
+/*
+ * res_strength:
+ *	Restore player's strength
+ */
+
+res_strength()
+{
+
+    /* If lost_str is non-zero, restore that amount of strength,
+     * else all of it 
+     */
+    if (lost_str) {
+	chg_str(lost_str);
+	lost_str = 0;
+    }
+
+    /* Otherwise, put player at the maximum strength */
+    else {
+	pstats.s_str = max_stats.s_str + ring_value(R_ADDSTR);
+    }
+
+    updpack(TRUE);
+}
+
+/*
+ * nohaste:
+ *	End the hasting
+ */
+
+nohaste()
+{
+    turn_off(player, ISHASTE);
+    msg("You feel yourself slowing down.");
+}
+
+/*
+ * noslow:
+ *	End the slowing
+ */
+
+noslow()
+{
+    turn_off(player, ISSLOW);
+    msg("You feel yourself speeding up.");
+}
+
+/*
+ * suffocate:
+ *	If this gets called, the player has suffocated
+ */
+
+suffocate()
+{
+    death(D_SUFFOCATION);
+}
+
+/*
+ * digest the hero's food
+ */
+stomach()
+{
+    register int oldfood, old_hunger, food_use, i;
+
+    old_hunger = hungry_state;
+    if (food_left <= 0)
+    {
+	/*
+	 * the hero is fainting
+	 */
+	if (no_command || rnd(100) > 20)
+	    return;
+	no_command = rnd(8)+4;
+	if (!terse)
+	    addmsg("You feel too weak from lack of food.  ");
+	msg("You faint");
+	running = FALSE;
+	count = 0;
+	hungry_state = F_FAINT;
+    }
+    else
+    {
+	oldfood = food_left;
+	food_use = 0;
+	for (i=0; i<MAXRELIC; i++) { /* each relic eats an additional food */
+	    if (cur_relic[i])
+		food_use++;
+	}
+	food_use +=    (ring_eat(LEFT_1)  + ring_eat(LEFT_2)  +
+			ring_eat(LEFT_3)  + ring_eat(LEFT_4)  +
+	    		ring_eat(RIGHT_1) + ring_eat(RIGHT_2) +
+			ring_eat(RIGHT_3) + ring_eat(RIGHT_4) + 
+			foodlev);
+	if (food_use < 1)
+	    food_use = 1;
+	food_left -= food_use;
+	if (food_left < MORETIME && oldfood >= MORETIME) {
+	    msg("You are starting to feel weak");
+	    running = FALSE;
+	    hungry_state = F_WEAK;
+	}
+	else if (food_left < 2 * MORETIME && oldfood >= 2 * MORETIME)
+	{
+	    msg(terse ? "Getting hungry" : "You are starting to get hungry");
+	    running = FALSE;
+	    hungry_state = F_HUNGRY;
+	}
+
+    }
+    if (old_hunger != hungry_state) 
+	updpack(TRUE);
+    wghtchk();
+}
+/*
+ * daemon for curing the diseased
+ */
+cure_disease()
+{
+    turn_off(player, HASDISEASE);
+    if (off (player, HASINFEST))
+	msg(terse ? "You feel yourself improving"
+		: "You begin to feel yourself improving again");
+}
+
+/*
+ * daemon for adding back dexterity
+ */
+un_itch()
+{
+    if (--lost_dext < 1) {
+	lost_dext = 0;
+	turn_off(player, HASITCH);
+    }
+    res_dexterity(1);
+}
+/*
+ * appear:
+ *	Become visible again
+ */
+appear()
+{
+    turn_off(player, ISINVIS);
+    PLAYER = VPLAYER;
+    msg("The tingling feeling leaves your body");
+    light(&hero);
+}
+/*
+ * dust_appear:
+ *	dust of disappearance wears off
+ */
+dust_appear()
+{
+    turn_off(player, ISINVIS);
+    PLAYER = VPLAYER;
+    msg("You become visible again");
+    light(&hero);
+}
+/*
+ * unchoke:
+ * 	the effects of "dust of choking and sneezing" wear off
+ */
+unchoke()
+{
+    if (!find_slot(unconfuse))
+	turn_off(player, ISHUH);
+    if (!find_slot(sight))
+	turn_off(player, ISBLIND);
+    light(&hero);
+    msg("Your throat and eyes return to normal");
+}
+/*
+ * make some potion for the guy in the Alchemy jug
+ */
+alchemy(obj)
+register struct object *obj;
+{
+    register struct object *tobj = NULL;
+    register struct linked_list *item;
+
+    /*
+     * verify that the object pointer we have still points to an alchemy
+     * jug (hopefully the right one!) because the hero could have thrown
+     * it away
+     */
+    for (item = pack; item != NULL; item = next(item)) {
+	tobj = OBJPTR(item);
+	if (tobj	 == obj		&& 
+	    tobj->o_type == MM		&& 
+	    tobj->o_which== MM_JUG	&&
+	    tobj->o_ac   == JUG_EMPTY	)
+		break;
+    }
+    if (item == NULL) { 	/* not in the pack, check the level */
+	for (item = lvl_obj; item != NULL; item = next(item)) {
+	    tobj = OBJPTR(item);
+	    if (tobj	     == obj		&& 
+		tobj->o_type == MM		&& 
+		tobj->o_which== MM_JUG		&&
+		tobj->o_ac   == JUG_EMPTY	)
+		    break;
+	}
+    }
+    if (item == NULL)	/* can't find it.....too bad */
+	return;
+    
+    switch(rnd(9)) {
+	case 0: tobj->o_ac = P_PHASE;
+	when 1: tobj->o_ac = P_CLEAR;
+	when 2: tobj->o_ac = P_SEEINVIS;
+	when 3: tobj->o_ac = P_HEALING;
+	when 4: tobj->o_ac = P_MFIND;
+	when 5: tobj->o_ac = P_TFIND;
+	when 6: tobj->o_ac = P_HASTE;
+	when 7: tobj->o_ac = P_RESTORE;
+	when 8: tobj->o_ac = P_FLY;
+    }
+}
+/*
+ * otto's irresistable dance wears off 
+ */
+
+undance()
+{
+    turn_off(player, ISDANCE);
+    msg ("Your feet take a break.....whew!");
+}
+
+/* 
+ * if he has our favorite necklace of strangulation then take damage every turn
+ */
+strangle()
+{
+     if ((pstats.s_hpt -= 6) <= 0) death(D_STRANGLE);
+}
+/*
+ * if he has on the gauntlets of fumbling he might drop his weapon each turn
+ */
+fumble()
+{
+    register struct linked_list *item;
+
+    if(cur_weapon!=NULL && cur_weapon->o_type!=RELIC && rnd(100)<3) {
+	for (item = pack; item != NULL; item = next(item)) {
+	    if (OBJPTR(item) == cur_weapon)
+		break;
+	}
+	if (item != NULL) {
+	    drop(item);
+	    running = FALSE;
+	}
+    }
+}
+/*
+ * this is called each turn the hero has the ring of searching on
+ */
+ring_search()
+{
+    search(FALSE, FALSE);
+}
+/*
+ * this is called each turn the hero has the ring of teleportation on
+ */
+ring_teleport()
+{
+    if (rnd(100) < 2) teleport();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/encumb.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,175 @@
+/*
+ * Stuff to do with encumberence
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Super-Rogue"
+ * Copyright (C) 1984 Robert D. Kindelberger
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include "rogue.h"
+
+/*
+ * updpack:
+ *	Update his pack weight and adjust fooduse accordingly
+ */
+updpack(getmax)
+int getmax;
+{
+
+	reg int topcarry, curcarry;
+
+	if (getmax)
+	    pstats.s_carry = totalenc();	/* get total encumb */
+	curcarry = packweight();		/* get pack weight */
+	topcarry = pstats.s_carry / 5;		/* 20% of total carry */
+	if(curcarry > 4 * topcarry) {
+	    if(rnd(100) < 80)
+		foodlev = 3;			/* > 80% of pack */
+	} else if(curcarry > 3 * topcarry) {
+	    if(rnd(100) < 60)
+		foodlev = 2;			/* > 60% of pack */
+	} else
+	    foodlev = 1;			/* <= 60% of pack */
+	pstats.s_pack = curcarry;		/* update pack weight */
+}
+
+
+/*
+ * packweight:
+ *	Get the total weight of the hero's pack
+ */
+packweight()
+{
+	reg struct object *obj;
+	reg struct linked_list *pc;
+	reg int weight;
+
+	weight = 0;
+	for(pc = pack ; pc != NULL ; pc = next(pc)) {
+	    obj = OBJPTR(pc);
+	    weight += itemweight(obj);
+	}
+	if(weight < 0)		/* in case of amulet */
+	     weight = 0;
+	if(ISWEARING(R_HEAVY))
+	    weight += weight / 4;
+	return(weight);
+}
+
+
+/*
+ * itemweight:
+ *	Get the weight of an object
+ */
+itemweight(wh)
+reg struct object *wh;
+{
+	reg int weight;
+	reg int ac;
+
+	weight = wh->o_weight;		/* get base weight */
+	switch(wh->o_type) {
+	    case ARMOR:
+		/*
+		 * subtract 10% for each enchantment
+		 * this will add weight for negative items
+		 */
+		ac = armors[wh->o_which].a_class - wh->o_ac;
+		weight = ((weight*10) - (weight*ac)) / 10;
+		if (weight < 0) weight = 0;
+	    when WEAPON:
+		if ((wh->o_hplus + wh->o_dplus) > 0)
+			weight /= 2;
+	}
+	if(wh->o_flags & ISCURSED)
+		weight += weight / 5;	/* 20% more for cursed */
+        weight *= wh->o_count;
+	return(weight);
+}
+
+
+/*
+ * playenc:
+ *	Get hero's carrying ability above norm
+ */
+playenc()
+{
+	return ((str_compute()-8)*50);
+}
+
+
+/*
+ * totalenc:
+ *	Get total weight that the hero can carry
+ */
+totalenc()
+{
+	reg int wtotal;
+
+	wtotal = NORMENCB + playenc();
+	switch(hungry_state) {
+		case F_OKAY:
+		case F_HUNGRY:	;			/* no change */
+		when F_WEAK:	wtotal -= wtotal / 10;	/* 10% off weak */
+		when F_FAINT:	wtotal /= 2;		/* 50% off faint */
+	}
+	return(wtotal);
+}
+
+
+
+/*
+ * whgtchk:
+ *	See if the hero can carry his pack
+ */
+
+wghtchk()
+{
+	reg int dropchk, err = TRUE;
+	reg char ch;
+	int wghtchk();
+
+	inwhgt = TRUE;
+	if (pstats.s_pack > pstats.s_carry) {
+	    ch = CCHAR( mvwinch(stdscr, hero.y, hero.x) );
+	    if((ch != FLOOR && ch != PASSAGE)) {
+		extinguish(wghtchk);
+		fuse(wghtchk,TRUE,1,AFTER);
+		inwhgt = FALSE;
+		return;
+	    }
+	    extinguish(wghtchk);
+	    msg("Your pack is too heavy for you");
+	    do {
+		dropchk = drop(NULL);
+		if(dropchk == FALSE) {
+		    mpos = 0;
+		    msg("You must drop something");
+		}
+		if(dropchk == TRUE)
+		    err = FALSE;
+	    } while(err);
+	}
+	inwhgt = FALSE;
+}
+
+
+/*
+ * hitweight:
+ *	Gets the fighting ability according to current weight
+ * 	This returns a  +1 hit for light pack weight
+ * 			 0 hit for medium pack weight
+ *			-1 hit for heavy pack weight
+ */
+
+hitweight()
+{
+	return(2 - foodlev);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/fight.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,1579 @@
+/*
+ * All the fighting gets done here
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include <ctype.h>
+#include <string.h>
+#include "rogue.h"
+
+#define CONF_DAMAGE	-1
+#define PARAL_DAMAGE	-2
+#define DEST_DAMAGE	-3
+
+static const struct matrix att_mat[5] = {
+/* Base		Max_lvl,	Factor,		Offset,		Range */
+{  10,		25,		2,		1,		2 },
+{  9,		18,		2,		1,		5 },
+{  10,		19,		2,		1,		3 },
+{  10,		21,		2,		1,		4 },
+{   7,		25,		1,		0,		2 }
+};
+
+/*
+ * fight:
+ *	The player attacks the monster.
+ */
+
+fight(mp, weap, thrown)
+register coord *mp;
+struct object *weap;
+bool thrown;
+{
+    register struct thing *tp;
+    register struct linked_list *item;
+    register bool did_hit = TRUE;
+    bool back_stab = FALSE;
+
+    /*
+     * Find the monster we want to fight
+     */
+    if ((item = find_mons(mp->y, mp->x)) == NULL) {
+	return(FALSE); /* must have killed him already */
+    }
+    tp = THINGPTR(item);
+    /*
+     * Since we are fighting, things are not quiet so no healing takes
+     * place.
+     */
+    player.t_quiet = 0;
+    tp->t_quiet = 0;
+
+    /*
+     * if its in the wall, we can't hit it
+     */
+    if (on(*tp, ISINWALL) && off(player, CANINWALL))
+	return(FALSE);
+
+    /*
+     * Let him know it was really a mimic (if it was one).
+     */
+    if (on(*tp, ISDISGUISE) && (tp->t_type != tp->t_disguise) &&
+	off(player, ISBLIND))
+    {
+	msg("Wait! That's a %s!", monsters[tp->t_index].m_name);
+	turn_off(*tp, ISDISGUISE);
+	did_hit = thrown;
+    }
+    if (on(*tp, CANSURPRISE) && off(player, ISBLIND) && !ISWEARING(R_ALERT)) {
+	msg("Wait! There's a %s!", monsters[tp->t_index].m_name);
+	turn_off(*tp, CANSURPRISE);
+	did_hit = thrown;
+    }
+    /*
+     * if he's a thief and the creature is asleep then he gets a chance
+     * for a backstab
+     */
+    if (player.t_ctype == C_THIEF			 	 && 
+	(!on(*tp, ISRUN) || on(*tp, ISHELD) || tp->t_no_move > 0)&&
+	!on(*tp, NOSTAB))
+	back_stab = TRUE;
+
+    runto(tp, &hero);
+
+    if (did_hit)
+    {
+	register const char *mname;
+
+	did_hit = FALSE;
+	mname = (on(player, ISBLIND)) ? "it" : monsters[tp->t_index].m_name;
+	if (!can_blink(tp) &&
+	    ( ((weap != NULL) && (weap->o_type == RELIC)) ||
+	     ((off(*tp, MAGICHIT)  || ((weap != NULL) && (weap->o_hplus > 0 || weap->o_dplus > 0)) ) &&
+	      (off(*tp, BMAGICHIT) || ((weap != NULL) && (weap->o_hplus > 1 || weap->o_dplus > 1)) ) &&
+	      (off(*tp, CMAGICHIT) || ((weap != NULL) && (weap->o_hplus > 2 || weap->o_dplus > 2)) ) ) )
+	    && roll_em(&player, tp, weap, thrown, cur_weapon, back_stab))
+	{
+	    did_hit = TRUE;
+
+	    if (on(*tp, NOMETAL) && weap != NULL &&
+		weap->o_type != RELIC && weap->o_flags & ISMETAL) {
+		sprintf(outstring,"Your %s passes right through the %s!",
+		    weaps[weap->o_which].w_name, mname);
+		msg(outstring);
+	    }
+	    else if (thrown) {
+		tp->t_wasshot = TRUE;
+		thunk(weap, tp, mname);
+	    }
+	    else
+		hit(weap, tp, NULL, mname, back_stab);
+
+	    /* If the player hit a rust monster, he better have a + weapon */
+	    if (on(*tp, CANRUST) && !thrown && (weap != NULL) &&
+		weap->o_type != RELIC &&
+		(weap->o_flags & ISMETAL) &&
+		!(weap->o_flags & ISPROT) &&
+		(weap->o_hplus < 1) && (weap->o_dplus < 1)) {
+		if (rnd(100) < 50) weap->o_hplus--;
+		else weap->o_dplus--;
+		msg(terse ? "Your %s weakens!"
+			  : "Your %s appears to be weaker now!",
+		    weaps[weap->o_which].w_name);
+	    }
+		
+	    /* If the player hit something that shrieks, wake the dungeon */
+	    if (on(*tp, CANSHRIEK)) {
+		turn_off(*tp, CANSHRIEK);
+		msg("The %s emits a piercing shriek.", mname);
+		aggravate();
+	    }
+
+	    /* If the player hit something that can surprise, it can't now */
+	    if (on(*tp, CANSURPRISE)) turn_off(*tp, CANSURPRISE);
+
+
+	    /* 
+	     * Can the player confuse? 
+	     */
+	    if (on(player, CANHUH) && !thrown) {
+		msg("Your hands stop glowing red");
+		msg("The %s appears confused.", mname);
+		turn_on(*tp, ISHUH);
+		turn_off(player, CANHUH);
+	    }
+	    /*
+	     * does the creature explode when hit?
+	     */
+	    if (on(*tp, CANEXPLODE))
+		explode(tp);
+
+	    /* 
+	     * Merchants just disappear if hit 
+	     */
+	    if (on(*tp, CANSELL)) {
+		msg("The %s disappears with his wares in a flash.",mname);
+		killed(item, FALSE, FALSE);
+	    }
+
+	    else if (tp->t_stats.s_hpt <= 0)
+		killed(item, TRUE, TRUE);
+
+	    /* If the monster is fairly intelligent and about to die, it
+	     * may turn tail and run.
+	     */
+	    else if ((tp->t_stats.s_hpt < max(10, tp->maxstats.s_hpt/10)) &&
+		     (rnd(25) < tp->t_stats.s_intel)) {
+		turn_on(*tp, ISFLEE);
+
+		/* If monster was suffocating, stop it */
+		if (on(*tp, DIDSUFFOCATE)) {
+		    turn_off(*tp, DIDSUFFOCATE);
+		    extinguish(suffocate);
+		}
+
+		/* If monster held us, stop it */
+		if (on(*tp, DIDHOLD) && (--hold_count == 0))
+			turn_off(player, ISHELD);
+		turn_off(*tp, DIDHOLD);
+	    }
+	}
+	else {
+	    if (thrown)
+		bounce(weap, tp, mname);
+	    else
+		miss(weap, tp, NULL, mname);
+	}
+    }
+    count = 0;
+    return did_hit;
+}
+
+/*
+ * attack:
+ *	The monster attacks the player
+ */
+
+attack(mp, weapon, thrown)
+register struct thing *mp;
+register struct object *weapon;
+bool thrown;
+{
+    register const char *mname;
+    register bool did_hit = FALSE;
+    register struct object *wielded;	/* The wielded weapon */
+
+    /*
+     * Since this is an attack, stop running and any healing that was
+     * going on at the time.
+     */
+    running = FALSE;
+    player.t_quiet = 0;
+    mp->t_quiet = 0;
+
+    if (on(*mp, ISDISGUISE) && off(player, ISBLIND))
+	turn_off(*mp, ISDISGUISE);
+    mname = on(player, ISBLIND) ? "it" : monsters[mp->t_index].m_name;
+
+    /*
+     * Try to find a weapon to wield.  Wield_weap will return a
+     * projector if weapon is a projectile (eg. bow for arrow).
+     * If weapon is NULL, it will try to find a suitable weapon.
+     */
+    wielded = wield_weap(weapon, mp);
+    if (weapon == NULL) weapon = wielded;
+
+    if (roll_em(mp, &player, weapon, thrown, wielded, FALSE)) {
+	did_hit = TRUE;
+
+	if (thrown) m_thunk(weapon, mp, mname);
+	else hit(weapon, mp, mname, NULL, FALSE);
+
+	if (pstats.s_hpt <= 0)
+	    death(mp->t_index);	/* Bye bye life ... */
+
+	/*
+	 * suprising monsters appear after they shoot at you 
+	 */
+	if (thrown) {
+	    if (on(*mp, CANSURPRISE)) 
+		turn_off(*mp, CANSURPRISE);
+	}
+	if (!thrown) {
+	    /*
+	     * If a vampire hits, it may take half your hit points
+	     */
+	    if (on(*mp, CANSUCK) && !save(VS_MAGIC, &player, 0)) {
+		if (pstats.s_hpt == 1) death(mp->t_index);
+		else {
+		  pstats.s_hpt /= 2;
+		  msg("You feel your life force being drawn from you.");
+		}
+	    }
+
+	    /*
+	     * Stinking monsters make player weaker (to hit)
+	     */
+	    if (on(*mp, CANSTINK)) {
+		turn_off(*mp, CANSTINK);
+		if (!save(VS_POISON, &player, 0)) {
+		    msg("The stench of the %s sickens you.", mname);
+		    if (on(player, HASSTINK)) lengthen(unstink, STINKTIME);
+		    else {
+			turn_on(player, HASSTINK);
+			fuse(unstink, 0, STINKTIME, AFTER);
+		    }
+		}
+	    }
+
+	    /*
+	     * Chilling monster reduces strength each time
+	     */
+	    if (on(*mp, CANCHILL)) {
+		if (!ISWEARING(R_SUSABILITY) && !save(VS_POISON, &player, 0)) {
+		    msg("You cringe at the %s's chilling touch.", mname);
+		    chg_str(-1);
+		    if (lost_str++ == 0)
+			fuse(res_strength, 0, CHILLTIME, AFTER);
+		    else lengthen(res_strength, CHILLTIME);
+		}
+	    }
+
+	    /*
+	     * itching monsters reduce dexterity (temporarily)
+	     */
+	    if (on(*mp, CANITCH) && !save(VS_POISON, &player, 0)) {
+		msg("The claws of the %s scratch you", mname);
+		if(ISWEARING(R_SUSABILITY)) {
+		    msg("The scratch has no effect");
+		}
+		else {
+		    turn_on(player, HASITCH);
+		    add_dexterity(TRUE);
+		    lost_dext++;
+		    fuse(un_itch, 0, roll(HEALTIME,SICKTIME), AFTER);
+		}
+	    }
+
+
+	    /*
+	     * If a hugging monster hits, it may SQUEEEEEEEZE
+	     */
+	    if (on(*mp, CANHUG)) {
+		if (roll(1,20) >= 18 || roll(1,20) >= 18) {
+		    msg("The %s squeezes you against itself.", mname);
+		    if ((pstats.s_hpt -= roll(2,8)) <= 0)
+			death(mp->t_index);
+		}
+	    }
+
+	    /*
+	     * If a disease-carrying monster hits, there is a chance the
+	     * player will catch the disease
+	     */
+	    if (on(*mp, CANDISEASE) &&
+		(rnd(pstats.s_const) < mp->t_stats.s_lvl) &&
+		off(player, HASDISEASE)) {
+		if (ISWEARING(R_HEALTH)) msg("The wound heals quickly.");
+		else {
+		    turn_on(player, HASDISEASE);
+		    fuse(cure_disease, 0, roll(HEALTIME,SICKTIME), AFTER);
+		    msg(terse ? "You have been diseased."
+			: "You have contracted a disease!");
+		}
+	    }
+
+	    /*
+	     * If a rust monster hits, you lose armor
+	     */
+	    if (on(*mp, CANRUST)) { 
+		if (cur_armor != NULL				&&
+		    cur_armor->o_which != LEATHER		&&
+		    cur_armor->o_which != STUDDED_LEATHER	&&
+		    cur_armor->o_which != PADDED_ARMOR		&&
+		    !(cur_armor->o_flags & ISPROT)		&&
+		    cur_armor->o_ac < pstats.s_arm+1		) {
+			msg(terse ? "Your armor weakens"
+			    : "Your armor appears to be weaker now. Oh my!");
+			cur_armor->o_ac++;
+	        }
+		if (cur_misc[WEAR_BRACERS] != NULL		&&
+		    cur_misc[WEAR_BRACERS]->o_ac > 0		&&
+		    !(cur_misc[WEAR_BRACERS]->o_flags & ISPROT)) {
+			cur_misc[WEAR_BRACERS]->o_ac--;
+			if (cur_misc[WEAR_BRACERS]->o_ac == 0) {
+			    register struct linked_list *item;
+
+			    for (item=pack; item!=NULL; item=next(item)) {
+				if (OBJPTR(item) == cur_misc[WEAR_BRACERS]) {
+				    detach(pack, item);
+				    o_discard(item);
+				    break;
+				}
+			    }
+			    msg ("Your bracers crumble and fall off!");
+			    cur_misc[WEAR_BRACERS] = NULL;
+			    inpack--;
+			}
+			else {
+			    msg("Your bracers weaken!");
+			}
+		}
+	    }
+	    /*
+	     * If can dissolve and hero has leather type armor
+	     */
+	    if (on(*mp, CANDISSOLVE) && cur_armor != NULL &&
+		(cur_armor->o_which == LEATHER		  ||
+		 cur_armor->o_which == STUDDED_LEATHER	  ||
+		 cur_armor->o_which == PADDED_ARMOR)	  &&
+		!(cur_armor->o_flags & ISPROT) &&
+		cur_armor->o_ac < pstats.s_arm+1) {
+		msg(terse ? "Your armor dissolves"
+		    : "Your armor appears to dissolve. Oh my!");
+		cur_armor->o_ac++;
+	    }
+
+	    /* If a surprising monster hit you, you can see it now */
+	    if (on(*mp, CANSURPRISE)) turn_off(*mp, CANSURPRISE);
+
+	    /*
+	     * If an infesting monster hits you, you get a parasite or rot
+	     */
+	    if (on(*mp, CANINFEST) && rnd(pstats.s_const) < mp->t_stats.s_lvl) {
+		if (ISWEARING(R_HEALTH)) msg("The wound quickly heals.");
+		else {
+		    turn_off(*mp, CANINFEST);
+		    msg(terse ? "You have been infested."
+			: "You have contracted a parasitic infestation!");
+		    infest_dam++;
+		    turn_on(player, HASINFEST);
+		}
+	    }
+
+	    /*
+	     * Ants have poisonous bites
+	     */
+	    if (on(*mp, CANPOISON) && !save(VS_POISON, &player, 0)) {
+		if (ISWEARING(R_SUSABILITY))
+		    msg(terse ? "Sting has no effect"
+			      : "A sting momentarily weakens you");
+		else {
+		    chg_str(-1);
+		    msg(terse ? "A sting has weakened you" :
+		    "You feel a sting in your arm and now feel weaker");
+		}
+	    }
+	    /*
+	     * does it take wisdom away?
+	     */
+	    if (on(*mp, TAKEWISDOM)		&& 
+		!save(VS_MAGIC, &player, 0)	&&
+		!ISWEARING(R_SUSABILITY)) {
+			add_wisdom(TRUE);
+	    }
+	    /*
+	     * does it take intelligence away?
+	     */
+	    if (on(*mp, TAKEINTEL)		&& 
+		!save(VS_MAGIC, &player, 0)	&&
+		!ISWEARING(R_SUSABILITY)) {
+			add_intelligence(TRUE);
+	    }
+	    /*
+	     * Cause fear by touching
+	     */
+	    if (on(*mp, TOUCHFEAR)) {
+		turn_off(*mp, TOUCHFEAR);
+		if (!ISWEARING(R_HEROISM)	&&
+		    !save(VS_WAND, &player, 0)	&&
+		    !(on(player, ISFLEE) && (player.t_dest == &mp->t_pos))) {
+			turn_on(player, ISFLEE);
+			player.t_dest = &mp->t_pos;
+			msg("The %s's touch terrifies you.", mname);
+		}
+	    }
+
+	    /*
+	     * make the hero dance (as in otto's irresistable dance)
+	     */
+	    if (on(*mp, CANDANCE) 	&& 
+		!on(player, ISDANCE)	&&
+		!save(VS_MAGIC, &player, -4)) {
+		    turn_off(*mp, CANDANCE);
+		    turn_on(player, ISDANCE);
+		    msg("You begin to dance uncontrollably!");
+		    fuse(undance, 0, roll(2,4), AFTER);
+	    }
+
+	    /*
+	     * Suffocating our hero
+	     */
+	    if (on(*mp, CANSUFFOCATE) && (rnd(100) < 15) &&
+		(find_slot(suffocate) == FALSE)) {
+		turn_on(*mp, DIDSUFFOCATE);
+		msg("The %s is beginning to suffocate you.", mname);
+		fuse(suffocate, 0, roll(4,2), AFTER);
+	    }
+
+	    /*
+	     * Turning to stone
+	     */
+	    if (on(*mp, TOUCHSTONE)) {
+		turn_off(*mp, TOUCHSTONE);
+		if (on(player, CANINWALL))
+			msg("The %s's touch has no effect.", mname);
+		else {
+		    if (!save(VS_PETRIFICATION, &player, 0) && rnd(100) < 15) {
+		        msg("Your body begins to solidify.");
+		        msg("You are turned to stone !!! --More--");
+		        wait_for(cw,' ');
+			death(D_PETRIFY);
+		    }
+		    else {
+			msg("The %s's touch stiffens your limbs.", mname);
+			no_command += STONETIME;
+		    }
+		}
+	    }
+
+	    /*
+	     * Wraiths might drain energy levels
+	     */
+	    if ((on(*mp, CANDRAIN) || on(*mp, DOUBLEDRAIN)) && rnd(100) < 15) {
+		lower_level(mp->t_index);
+		if (on(*mp, DOUBLEDRAIN)) lower_level(mp->t_index);
+		turn_on(*mp, DIDDRAIN);  
+	    }
+
+	    /*
+	     * Violet fungi stops the poor guy from moving
+	     */
+	    if (on(*mp, CANHOLD) && off(*mp, DIDHOLD)) {
+		turn_on(player, ISHELD);
+		turn_on(*mp, DIDHOLD);
+		hold_count++;
+	    }
+
+	    /*
+	     * Sucker will suck blood and run
+	     */
+	    if (on(*mp, CANDRAW)) {
+		turn_off(*mp, CANDRAW);
+		turn_on(*mp, ISFLEE);
+		msg("The %s sates itself with your blood.", mname);
+		if ((pstats.s_hpt -= 12) <= 0) death(mp->t_index);
+	    }
+
+	    /*
+	     * Bad smell will force a reduction in strength
+	     */
+	    if (on(*mp, CANSMELL)) {
+		turn_off(*mp, CANSMELL);
+		if (save(VS_MAGIC, &player, 0) || ISWEARING(R_SUSABILITY))
+		    msg("You smell an unpleasant odor.");
+		else {
+		    int odor_str = -(rnd(6)+1);
+
+		    msg("You are overcome by a foul odor.");
+		    if (lost_str == 0) {
+			chg_str(odor_str);
+			fuse(res_strength, 0, SMELLTIME, AFTER);
+			lost_str -= odor_str;
+		    }
+		    else lengthen(res_strength, SMELLTIME);
+		}
+	    }
+
+	    /*
+	     * Paralyzation
+	     */
+	    if (on(*mp, CANPARALYZE)) {
+		turn_off(*mp, CANPARALYZE);
+		if (!save(VS_PARALYZATION, &player, 0)) {
+		    if (on(player, CANINWALL))
+			msg("The %s's touch has no effect.", mname);
+		    else {
+			msg("The %s's touch paralyzes you.", mname);
+			no_command += FREEZETIME;
+		    }
+		}
+	    }
+
+	    /*
+	     * Painful wounds make you faint
+	     */
+	     if (on(*mp, CANPAIN)) {
+		turn_off(*mp, CANPAIN);
+		if (!ISWEARING(R_ALERT) && !save(VS_POISON, &player, 0)) {
+			msg("You faint from the painful wound");
+			no_command += PAINTIME;
+		}
+	    }
+
+	    /*
+	     * The monsters touch slows the hero down
+	     */
+	     if (on(*mp, CANSLOW)) {
+		turn_off(*mp, CANSLOW);
+		if (!save(VS_PARALYZATION, &player, 0)) 
+			add_slow();
+	    }
+
+	    /*
+	     * Rotting
+	     */
+	    if (on(*mp, CANROT)) {
+		if (!ISWEARING(R_HEALTH) && 
+		    !save(VS_POISON, &player, 0)     && 
+		    off(player, DOROT)) {
+		    turn_on(player, DOROT);
+		    msg("You feel your skin starting to rot away!");
+		}
+	    }
+
+	    if (on(*mp, STEALGOLD)) {
+		/*
+		 * steal some gold
+		 */
+		register long lastpurse;
+		register struct linked_list *item;
+		register struct object *obj;
+
+		lastpurse = purse;
+		purse -= GOLDCALC + GOLDCALC;
+		if (!save(VS_MAGIC, &player, mp->t_stats.s_lvl/10)) {
+		    if (on(*mp, ISUNIQUE))
+			purse -= GOLDCALC + GOLDCALC + GOLDCALC + GOLDCALC;
+		    purse -= GOLDCALC + GOLDCALC + GOLDCALC + GOLDCALC;
+		}
+		if (purse < 0)
+		    purse = 0;
+		if (purse != lastpurse) {
+		    msg("Your purse feels lighter");
+
+		    /* Give the gold to the thief */
+		    for (item=mp->t_pack; item != NULL; item=next(item)) {
+			obj = OBJPTR(item);
+			if (obj->o_type == GOLD) {
+			    obj->o_count += lastpurse - purse;
+			    break;
+			}
+		    }
+
+		    /* Did we do it? */
+		    if (item == NULL) {	/* Then make some */
+			item = new_item(sizeof *obj);
+			obj = OBJPTR(item);
+			obj->o_type = GOLD;
+			obj->o_count = lastpurse - purse;
+			obj->o_hplus = obj->o_dplus = 0;
+			strcpy(obj->o_damage,"0d0");
+                        strcpy(obj->o_hurldmg,"0d0");
+			obj->o_ac = 11;
+			obj->contents = NULL;
+			obj->o_group = 0;
+			obj->o_flags = 0;
+			obj->o_mark[0] = '\0';
+			obj->o_pos = mp->t_pos;
+
+			attach(mp->t_pack, item);
+		    }
+		}
+
+		turn_on(*mp, ISFLEE);
+		turn_on(*mp, ISINVIS);
+	    }
+
+	    if (on(*mp, STEALMAGIC)) {
+		register struct linked_list *list, *steal;
+		register struct object *obj;
+		register int nobj;
+
+		/*
+		 * steal a magic item, look through the pack
+		 * and pick out one we like.
+		 */
+		steal = NULL;
+		for (nobj = 0, list = pack; list != NULL; list = next(list))
+		{
+		    obj = OBJPTR(list);
+		    if (!is_current(obj) &&
+			is_magic(obj)	 && 
+			rnd(++nobj) == 0)
+			    steal = list;
+		}
+		if (steal != NULL)
+		{
+		    register struct object *obj;
+		    struct linked_list *item;
+
+		    obj = OBJPTR(steal);
+		    if (on(*mp, ISUNIQUE))
+			monsters[mp->t_index].m_normal = TRUE;
+		    item = find_mons(mp->t_pos.y, mp->t_pos.x);
+		    killed(item, FALSE, FALSE);
+		    if (obj->o_count > 1 && obj->o_group == 0) {
+			register int oc;
+
+			oc = --(obj->o_count);
+			obj->o_count = 1;
+			sprintf(outstring,"The %s stole %s!", mname, inv_name(obj, TRUE));
+			msg(outstring);
+			obj->o_count = oc;
+		    }
+		    else {
+			sprintf(outstring,"The %s stole %s!", mname, inv_name(obj, TRUE));
+			msg(outstring);
+			detach(pack, steal);
+
+			/* If this is a relic, clear its holding field */
+			if (obj->o_type == RELIC)
+			    cur_relic[obj->o_which] = 0;
+
+			o_discard(steal);
+		        inpack--;
+		    }
+		    updpack(FALSE);
+		}
+	    }
+	}
+    }
+    else {
+	/* If the thing was trying to surprise, no good */
+	if (on(*mp, CANSURPRISE)) turn_off(*mp, CANSURPRISE);
+
+	else if (thrown) m_bounce(weapon, mp, mname);
+	else miss(weapon, mp, mname, NULL);
+    }
+    if (fight_flush)
+	md_flushinp();
+    count = 0;
+    status(FALSE);
+    return(did_hit);
+}
+
+/*
+ * swing:
+ *	returns true if the swing hits
+ */
+
+swing(class, at_lvl, op_arm, wplus)
+short class;
+int at_lvl, op_arm, wplus;
+{
+    register int res = rnd(20)+1;
+    register int need;
+
+    need = att_mat[class].base -
+	   att_mat[class].factor *
+	   ((min(at_lvl, att_mat[class].max_lvl) -
+	    att_mat[class].offset)/att_mat[class].range) +
+	   (10 - op_arm);
+    if (need > 20 && need <= 25) need = 20;
+
+    return (res+wplus >= need);
+}
+
+/*
+ * roll_em:
+ *	Roll several attacks
+ */
+
+roll_em(att_er, def_er, weap, hurl, cur_weapon, back_stab)
+struct thing *att_er, *def_er;
+struct object *weap;
+bool hurl;
+struct object *cur_weapon;
+bool back_stab;
+{
+    register struct stats *att, *def;
+    register char *cp = NULL;
+    register int ndice, nsides, nplus, def_arm;
+    bool did_hit = FALSE;
+    int prop_hplus, prop_dplus;
+    int vampiric_damage;
+
+    /* Get statistics */
+    att = &att_er->t_stats;
+    def = &def_er->t_stats;
+
+    prop_hplus = prop_dplus = 0;
+    if (weap == NULL)
+	cp = att->s_dmg;
+    else if (hurl) {
+	if ((weap->o_flags&ISMISL) && cur_weapon != NULL &&
+	  cur_weapon->o_which == weap->o_launch)
+	{
+	    cp = weap->o_hurldmg;
+	    prop_hplus = cur_weapon->o_hplus;
+	    prop_dplus = cur_weapon->o_dplus;
+	}
+	else
+	    cp = (weap->o_flags&ISMISL ? weap->o_damage : weap->o_hurldmg);
+    }
+    else {
+	if (weap->o_type == RELIC) {
+	    switch (weap->o_which) {
+		case MUSTY_DAGGER:	cp = "1d4+1/1d4+1";
+		when YEENOGHU_FLAIL:	cp = "3d6/paralyze/confuse";
+		when HRUGGEK_MSTAR:	cp = "3d10";
+		when MING_STAFF:	cp = "1d8";
+		when ASMO_ROD:		cp = "2d8+1";
+		when ORCUS_WAND:	cp = "destroy";
+	    }
+	}
+	else cp = weap->o_damage;
+	/*
+	 * Drain a staff of striking
+	 */
+	if (weap->o_type == STICK && weap->o_which == WS_HIT
+	    && weap->o_charges == 0)
+		{
+		    strcpy(weap->o_damage,"0d0");
+		    weap->o_hplus = weap->o_dplus = 0;
+		}
+    }
+    for (;;)
+    {
+	int damage;
+	int hplus = prop_hplus;
+	int dplus = prop_dplus;
+
+	if (weap != NULL && weap->o_type == RELIC) {
+	    switch (weap->o_which) {
+		case MUSTY_DAGGER:
+		    if (att != &pstats || /* Not player or good stats */
+			(str_compute() > 15 && dex_compute() > 15)) {
+
+			hplus += 6;
+			dplus += 6;
+
+			/* Give an additional strength and dex bonus */
+			if (att == &pstats) {
+			    hplus += str_plus(str_compute()) +
+				     dext_plus(dex_compute());
+			    dplus += dext_plus(dex_compute()) +
+				     add_dam(str_compute());
+			}
+			else {
+			    hplus += str_plus(att->s_str) +
+				     dext_plus(att->s_dext);
+			    dplus += dext_plus(att->s_dext) +
+				     add_dam(att->s_str);
+			}
+		    }
+		    else {
+			hplus -= 3;
+			dplus -= 3;
+		    }
+		when YEENOGHU_FLAIL:
+		case HRUGGEK_MSTAR:
+		    hplus += 3;
+		    dplus += 3;
+		when MING_STAFF:
+		    hplus += 2;
+		    dplus += 2;
+	    }
+	}
+	else if (weap != NULL) {
+	    hplus += weap->o_hplus;
+	    dplus += weap->o_dplus;
+	}
+
+	/* Is attacker weak? */
+	if (on(*att_er, HASSTINK)) hplus -= 2;
+
+	if (att == &pstats)	/* Is the attacker the player? */
+	{
+	    hplus += hitweight();	/* adjust for encumberence */
+	    dplus += hung_dam();	/* adjust damage for hungry player */
+	    dplus += ring_value(R_ADDDAM);
+	}
+	if (back_stab || (weap && att != &pstats && on(*att_er, CANBSTAB)))
+	    hplus += 4;	/* add in pluses for backstabbing */
+
+	/* Get the damage */
+	while (isspace(*cp)) cp++;
+	if (!isdigit(*cp)) {
+	    if (strncmp(cp, "confuse", 7) == 0) ndice = CONF_DAMAGE;
+	    else if (strncmp(cp, "paralyze", 8) == 0) ndice = PARAL_DAMAGE;
+	    else if (strncmp(cp, "destroy", 7) == 0) ndice = DEST_DAMAGE;
+	    else ndice = 0;
+	    nsides = 0;
+	    nplus = 0;
+	}
+	else {
+	    char *oldcp;
+
+	    /* Get the number of damage dice */
+	    ndice = atoi(cp);
+	    if ((cp = strchr(cp, 'd')) == NULL)
+		break;
+
+	    /* Skip the 'd' and get the number of sides per die */
+	    nsides = atoi(++cp);
+
+	    /* Check for an addition -- save old place in case none is found */
+	    oldcp = cp;
+	    if ((cp = strchr(cp, '+')) != NULL) nplus = atoi(++cp);
+	    else {
+		nplus = 0;
+		cp = oldcp;
+	    }
+	}
+
+	if (def == &pstats) { /* Monster attacks player */
+	    def_arm = ac_compute() - dext_prot(dex_compute());
+	    hplus += str_plus(att->s_str)+dext_plus(att->s_dext);
+	}
+	else {	/* Player attacks monster */
+	    def_arm = def->s_arm - dext_prot(def->s_dext);
+	    hplus += str_plus(str_compute())+dext_plus(dex_compute());
+	}
+
+	if (swing(att_er->t_ctype, att->s_lvl, def_arm, hplus)) {
+	    register int proll;
+
+	    /* Take care of special effects */
+	    switch (ndice) {
+	      case CONF_DAMAGE:
+		if (def == &pstats) { /* Monster attacks player */
+		    if (!save(VS_MAGIC, &player, 0) && off(player, ISCLEAR)) {
+			msg("You feel disoriented.");
+			if (find_slot(unconfuse))
+			    lengthen(unconfuse, rnd(8)+HUHDURATION);
+			else
+			    fuse(unconfuse, 0, rnd(8)+HUHDURATION, AFTER);
+			turn_on(player, ISHUH);
+		    }
+		    else msg("You feel dizzy, but it quickly passes.");
+		}
+		/* Player hits monster */
+		else if (!save(VS_MAGIC, def_er, 0) && off(*def_er, ISCLEAR)) { 
+		    msg("The artifact warms with pleasure.");
+		    turn_on(*def_er, ISHUH);
+		}
+		did_hit = TRUE;
+	      when PARAL_DAMAGE:
+		if (def == &pstats) { /* Monster attacks player */
+		    if (!save(VS_MAGIC, &player, 0) && off(player, CANINWALL)) {
+			msg("You stiffen up.");
+			no_command += FREEZETIME;
+		    }
+		}
+		else if (!save(VS_MAGIC, def_er, 0)) { /* Player hits monster */
+		    msg("The artifact hums happily.");
+		    turn_off(*def_er, ISRUN);
+		    turn_on(*def_er, ISHELD);
+		}
+		did_hit = TRUE;
+	      when DEST_DAMAGE:
+		if (def == &pstats) { /* Monster attacks player */
+		    msg("You feel a tug at your life force.");
+		    if (!save(VS_MAGIC, &player, -4)) {
+			msg("The wand devours your soul.");
+			def->s_hpt = 0;
+		    }
+		}
+		/* Player hits monster */
+		else if (!save(VS_MAGIC, def_er, -4)) {
+		    msg("The artifact draws energy.");
+
+		    /* Give the player half the monster's hits */
+		    att->s_hpt += def->s_hpt/2;
+		    if (att->s_hpt > att_er->maxstats.s_hpt)
+			att->s_hpt = att_er->maxstats.s_hpt;
+
+		    /* Kill the monster */
+		    def->s_hpt = 0;
+		}
+		did_hit = TRUE;
+	      otherwise:
+		/* Heil's ankh always gives maximum damage */
+		if (att == &pstats && cur_relic[HEIL_ANKH])
+		    proll = ndice * nsides;
+		else proll = roll(ndice, nsides);
+
+		if (ndice + nsides > 0 && proll < 1)
+		    debug("Damage for %dd%d came out %d.",
+				ndice, nsides, proll);
+		damage = dplus + proll + nplus;
+		if (def == &pstats)
+		    damage += add_dam(att->s_str);
+		else
+		    damage += add_dam(str_compute());
+
+		/* Check for half damage monsters */
+		if (on(*def_er, HALFDAMAGE)) damage /= 2;
+
+		/* add in multipliers for backstabbing */
+		if (back_stab || 
+		    (weap && att != &pstats && on(*att_er, CANBSTAB))) {
+		    int mult = 2 + (att->s_lvl-1)/4; /* Normal multiplier */
+
+		    if (mult > 5 && att != &pstats) 
+			mult = 5;/*be nice with maximum of 5x for monsters*/
+		    if (weap->o_type == RELIC && weap->o_which == MUSTY_DAGGER)
+			mult++;
+		    damage *= mult;
+		}
+
+		/* Check for no-damage and division */
+		if (on(*def_er, BLOWDIVIDE)) {
+		    damage = 0;
+		    creat_mons(def_er, def_er->t_index, FALSE);
+		    light(&hero);
+		}
+		/* check for immunity to metal -- RELICS are always bad */
+		if (on(*def_er, NOMETAL) && weap != NULL &&
+		    weap->o_type != RELIC && weap->o_flags & ISMETAL) {
+		    damage = 0;
+		}
+
+		/*
+		 * If defender is wearing a cloak of displacement -- no damage
+		 * the first time. (unless its a hurled magic missile)
+		 */
+		if ( ((weap == NULL) || weap->o_type != MISSILE) &&
+		    def == &pstats				 &&	
+		    cur_misc[WEAR_CLOAK] != NULL		 &&
+		    cur_misc[WEAR_CLOAK]->o_which == MM_DISP &&
+		    off(*att_er, MISSEDDISP)) {
+		    damage = 0;
+		    did_hit = FALSE;
+		    turn_on(*att_er, MISSEDDISP);
+		    if (cansee(att_er->t_pos.y, att_er->t_pos.x) &&
+			!invisible(att_er))
+			msg("The %s looks amazed",
+				monsters[att_er->t_index].m_name);
+		}
+		else {
+		    def->s_hpt -= max(0, damage);	/* Do the damage */
+		    did_hit = TRUE;
+		}
+
+		vampiric_damage = damage;
+		if (def->s_hpt < 0)	/* only want REAL damage inflicted */
+		    vampiric_damage += def->s_hpt;
+                if (vampiric_damage < 0)
+                    vampiric_damage = 0;
+		if (att == &pstats && ISWEARING(R_VAMPREGEN) && !hurl) {
+		    if ((pstats.s_hpt += vampiric_damage/2) > max_stats.s_hpt)
+			pstats.s_hpt = max_stats.s_hpt;
+		}
+		debug ("hplus=%d dmg=%d", hplus, damage);
+	    }
+	}
+	if ((cp = strchr(cp, '/')) == NULL)
+	    break;
+	cp++;
+    }
+    return did_hit;
+}
+
+/*
+ * prname:
+ *	The print name of a combatant
+ */
+
+char *
+prname(who, upper)
+register char *who;
+bool upper;
+{
+    static char tbuf[LINELEN];
+
+    *tbuf = '\0';
+    if (who == 0)
+	strcpy(tbuf, "you"); 
+    else if (on(player, ISBLIND))
+	strcpy(tbuf, "it");
+    else
+    {
+	strcpy(tbuf, "the ");
+	strcat(tbuf, who);
+    }
+    if (upper)
+	*tbuf = toupper(*tbuf);
+    return tbuf;
+}
+
+/*
+ * hit:
+ *	Print a message to indicate a succesful hit
+ */
+
+hit(weapon, tp, er, ee, back_stab)
+register struct object *weapon;
+register struct thing *tp;
+register char *er, *ee;
+bool back_stab;
+{
+    register char *s = NULL;
+    char 
+    	          att_name[80],	/* Name of attacker */
+		  def_name[80];/* Name of defender */
+    bool see_monst = !invisible(tp);	/* Can the player see the monster? */
+
+    /* What do we call the attacker? */
+    if (er == NULL) {	/* Player is attacking */
+	strcpy(att_name, prname(er, TRUE));
+	strcpy(def_name, see_monst ? prname(ee, FALSE) : "something");
+    }
+    else {
+	strcpy(att_name, see_monst ? prname(er, TRUE) : "Something");
+
+	/* If the monster is using a weapon and we can see it, report it */
+	if (weapon != NULL && see_monst) {
+	    strcat(att_name, "'s ");
+	    strcat(att_name, weap_name(weapon));
+	}
+
+	strcpy(def_name, prname(ee, FALSE));
+    }
+
+    addmsg(att_name);
+    if (terse) {
+	if (back_stab)
+	    s = " backstab!";
+	else
+	    s = " hit.";
+    }
+    else {
+	if (back_stab)
+	    s = (er == 0 ? " have backstabbed " : " has backstabbed ");
+	else {
+	    switch (rnd(4))
+	    {
+		case 0: s = " scored an excellent hit on ";
+		when 1: s = " hit ";
+		when 2: s = (er == 0 ? " have injured " : " has injured ");
+		when 3: s = (er == 0 ? " swing and hit " : " swings and hits ");
+	    }
+	}
+    }
+    addmsg(s);
+    if (!terse)
+	addmsg(def_name);
+    endmsg();
+}
+
+/*
+ * miss:
+ *	Print a message to indicate a poor swing
+ */
+
+miss(weapon, tp, er, ee)
+register struct object *weapon;
+register struct thing *tp;
+register char *er, *ee;
+{
+    register char *s = NULL;
+    char
+    	          att_name[80],	/* Name of attacker */
+		  def_name[80];/* Name of defender */
+    bool see_monst = !invisible(tp);	/* Can the player see the monster? */
+
+    /* What do we call the attacker? */
+    if (er == NULL) {	/* Player is attacking */
+	strcpy(att_name, prname(er, TRUE));
+	strcpy(def_name, see_monst ? prname(ee, FALSE) : "something");
+    }
+    else {
+	strcpy(att_name, see_monst ? prname(er, TRUE) : "Something");
+
+	/* If the monster is using a weapon and we can see it, report it */
+	if (weapon != NULL && see_monst) {
+	    strcat(att_name, "'s ");
+	    strcat(att_name, weap_name(weapon));
+	}
+
+	strcpy(def_name, prname(ee, FALSE));
+    }
+
+    addmsg(att_name);
+    switch (terse ? 0 : rnd(4))
+    {
+	case 0: s = (er == 0 ? " miss" : " misses");
+	when 1: s = (er == 0 ? " swing and miss" : " swings and misses");
+	when 2: s = (er == 0 ? " barely miss" : " barely misses");
+	when 3: s = (er == 0 ? " don't hit" : " doesn't hit");
+    }
+    addmsg(s);
+    if (!terse)
+	addmsg(" %s", def_name);
+    endmsg();
+}
+
+/*
+ * dext_plus:
+ *	compute to-hit bonus for dexterity
+ */
+
+dext_plus(dexterity)
+register int dexterity;
+{
+	return (dexterity > 10 ? (dexterity-13)/3 : (dexterity-10)/3);
+}
+
+
+/*
+ * dext_prot:
+ *	compute armor class bonus for dexterity
+ */
+
+dext_prot(dexterity)
+register int dexterity;
+{
+    return ((dexterity-10)/2);
+}
+/*
+ * str_plus:
+ *	compute bonus/penalties for strength on the "to hit" roll
+ */
+
+str_plus(str)
+register short str;
+{
+    return((str-10)/3);
+}
+
+/*
+ * add_dam:
+ *	compute additional damage done for exceptionally high or low strength
+ */
+
+add_dam(str)
+register short str;
+{
+    return((str-9)/2);
+}
+
+/*
+ * hung_dam:
+ *	Calculate damage depending on players hungry state
+ */
+hung_dam()
+{
+	reg int howmuch = 0;
+
+	switch(hungry_state) {
+		case F_OKAY:
+		case F_HUNGRY:	howmuch = 0;
+		when F_WEAK:	howmuch = -1;
+		when F_FAINT:	howmuch = -2;
+	}
+	return howmuch;
+}
+
+/*
+ * thunk:
+ *	A missile hits a monster
+ */
+
+thunk(weap, tp, mname)
+register struct object *weap;
+register struct thing *tp;	/* Defender */
+register char *mname;
+{
+    char *def_name;	/* Name of defender */
+
+    /* What do we call the defender? */
+    if (!cansee(tp->t_pos.y, tp->t_pos.x) || invisible(tp))
+	def_name = "something";
+    else def_name = prname(mname, FALSE);
+
+    if (weap->o_type == WEAPON){
+	sprintf(outstring,"The %s hits %s", weaps[weap->o_which].w_name, def_name);
+	msg(outstring);
+    }
+    else if (weap->o_type == MISSILE){
+	sprintf(outstring,"The %s hits %s",ws_magic[weap->o_which].mi_name, def_name);
+	msg(outstring);
+    }
+    else
+	msg("You hit %s.", def_name);
+}
+
+/*
+ * mthunk:
+ *	 A missile from a monster hits the player
+ */
+
+m_thunk(weap, tp, mname)
+register struct object *weap;
+register struct thing *tp;
+register char *mname;
+{
+    char *att_name;	/* Name of attacker */
+
+    /* What do we call the attacker? */
+    if (!cansee(tp->t_pos.y, tp->t_pos.x) || invisible(tp))
+	att_name = "Something";
+    else att_name = prname(mname, TRUE);
+
+    if (weap->o_type == WEAPON){
+	sprintf(outstring,"%s's %s hits you.", att_name, weaps[weap->o_which].w_name);
+	msg(outstring);
+    }
+    else if (weap->o_type == MISSILE){
+	sprintf(outstring,"%s's %s hits you.", att_name, ws_magic[weap->o_which].mi_name);
+	msg(outstring);
+    }
+    else
+	msg("%s hits you.", att_name);
+}
+
+/*
+ * bounce:
+ *	A missile misses a monster
+ */
+
+bounce(weap, tp, mname)
+register struct object *weap;
+register struct thing *tp;	/* Defender */
+register char *mname;
+{
+    char *def_name;	/* Name of defender */
+
+    /* What do we call the defender? */
+    if (!cansee(tp->t_pos.y, tp->t_pos.x) || invisible(tp))
+	def_name = "something";
+    else def_name = prname(mname, FALSE);
+
+    if (weap->o_type == WEAPON){
+	sprintf(outstring,"The %s misses %s",weaps[weap->o_which].w_name, def_name);
+	msg(outstring);
+    }
+    else if (weap->o_type == MISSILE){
+	sprintf(outstring,"The %s misses %s",ws_magic[weap->o_which].mi_name, def_name);
+	msg(outstring);
+    }
+    else
+	msg("You missed %s.", def_name);
+}
+
+/*
+ * m_bounce:
+	  A missle from a monster misses the player
+ */
+
+m_bounce(weap, tp, mname)
+register struct object *weap;
+register struct thing *tp;
+register char *mname;
+{
+    char *att_name;	/* Name of attacker */
+
+    /* What do we call the attacker? */
+    if (!cansee(tp->t_pos.y, tp->t_pos.x) || invisible(tp))
+	att_name = "Something";
+    else att_name = prname(mname, TRUE);
+
+    if (weap->o_type == WEAPON){
+	sprintf(outstring,"%s's %s misses you.", att_name, weaps[weap->o_which].w_name);
+	msg(outstring);
+    }
+    else if (weap->o_type == MISSILE){
+	sprintf(outstring,"%s's %s misses you.", att_name, ws_magic[weap->o_which].mi_name);
+	msg(outstring);
+    }
+    else
+	msg("%s misses you.", att_name);
+}
+
+
+/*
+ * is_magic:
+ *	Returns true if an object radiates magic
+ */
+
+is_magic(obj)
+register struct object *obj;
+{
+    switch (obj->o_type)
+    {
+	case ARMOR:
+	    return obj->o_ac != armors[obj->o_which].a_class;
+	when WEAPON:
+	    return obj->o_hplus != 0 || obj->o_dplus != 0;
+	when POTION:
+	case SCROLL:
+	case STICK:
+	case RING:
+	case MM:
+	case RELIC:
+	    return TRUE;
+    }
+    return FALSE;
+}
+
+/*
+ * killed:
+ *	Called to put a monster to death
+ */
+
+killed(item, pr, points)
+register struct linked_list *item;
+bool pr, points;
+{
+    register struct thing *tp;
+    register struct linked_list *pitem, *nexti;
+    const char *monst;
+
+    tp = THINGPTR(item);
+
+    if (pr)
+    {
+	addmsg(terse ? "Defeated " : "You have defeated ");
+	if (on(player, ISBLIND))
+	    msg("it.");
+	else
+	{
+	    if (cansee(tp->t_pos.y, tp->t_pos.x) && !invisible(tp))
+		monst = monsters[tp->t_index].m_name;
+	    else {
+		if (terse) monst = "something";
+		else monst = "thing";
+	    }
+	    if (!terse)
+		addmsg("the ");
+	    msg("%s.", monst);
+	}
+    }
+
+    /* Take care of any residual effects of the monster */
+    check_residue(tp);
+
+    if (points) {
+	unsigned long test;	/* For overflow check */
+
+	test = pstats.s_exp + tp->t_stats.s_exp;
+
+	/* Do an overflow check before increasing experience */
+	if (test > pstats.s_exp) pstats.s_exp = test;
+
+	/*
+	 * Do adjustments if he went up a level
+	 */
+	check_level(TRUE);
+    }
+
+    /*
+     * Empty the monsters pack
+     */
+    pitem = tp->t_pack;
+
+    /*
+     * Get rid of the monster.
+     */
+    mvwaddch(mw, tp->t_pos.y, tp->t_pos.x, ' ');
+    mvwaddch(cw, tp->t_pos.y, tp->t_pos.x, tp->t_oldch); 
+    detach(mlist, item);
+    /*
+     * empty his pack
+     */
+    while (pitem != NULL)
+    {
+	nexti = next(tp->t_pack);
+	(OBJPTR(pitem))->o_pos = tp->t_pos;
+	detach(tp->t_pack, pitem);
+	if (points) 
+	    fall(pitem, FALSE);
+	else 
+	    o_discard(pitem);
+	pitem = nexti;
+    }
+    turn_on(*tp, ISDEAD);
+    attach(monst_dead, item);
+}
+
+
+/*
+ * Returns a pointer to the weapon the monster is wielding corresponding to
+ * the given thrown weapon.  If no thrown item is given, try to find any
+ * decent weapon.
+ */
+
+struct object *
+wield_weap(thrown, mp)
+struct object *thrown;
+struct thing *mp;
+{
+    int look_for = 0,	/* The projectile weapon we are looking for */
+	new_rate,	/* The rating of a prospective weapon */
+        cand_rate = -1; /* Rating of current candidate -- higher is better */
+    register struct linked_list *pitem;
+    register struct object *obj, *candidate = NULL;
+
+    if (thrown != NULL) {	/* Using a projectile weapon */
+      switch (thrown->o_which) {
+	case BOLT:	look_for = CROSSBOW;	/* Find the crossbow */
+	when ARROW:	look_for = BOW;		/* Find the bow */
+	when ROCK:	look_for = SLING;	/* find the sling */
+	otherwise:	return(NULL);
+      }
+    }
+    else if (off(*mp, ISUNIQUE) && off(*mp, CARRYWEAPON)) return(NULL);
+
+    for (pitem=mp->t_pack; pitem; pitem=next(pitem)) {
+	obj = OBJPTR(pitem);
+
+	/*
+	 * If we have a thrown weapon, just return the first match
+	 * we come to.
+	 */
+	if (thrown != NULL && obj->o_type == WEAPON && obj->o_which == look_for)
+	    return(obj);
+
+	/* If we have a usable RELIC, return it */
+	if (thrown == NULL && obj->o_type == RELIC) {
+	    switch (obj->o_which) {
+		case MUSTY_DAGGER:
+		case YEENOGHU_FLAIL:
+		case HRUGGEK_MSTAR:
+		case MING_STAFF:
+		case ASMO_ROD:
+		case ORCUS_WAND:
+		    return(obj);
+	    }
+	}
+
+	/* Otherwise if it's a usable weapon, it is a good candidate */
+	else if (thrown == NULL && obj->o_type == WEAPON) {
+	    switch (obj->o_which) {
+		case DAGGER:
+		    new_rate = 0;
+		when BATTLEAXE:
+		    new_rate = 1;
+		when MACE:
+		    new_rate = 2;
+		when SWORD:
+		    new_rate = 3;
+		when PIKE:
+		    new_rate = 4;
+		when HALBERD:
+		case SPETUM:
+		    new_rate = 6;
+		when BARDICHE:
+		    new_rate = 7;
+		when TRIDENT:
+		    new_rate = 8;
+		when BASWORD:
+		    new_rate = 9;
+		when TWOSWORD:
+		    new_rate = 10;
+		otherwise:
+		    new_rate = -1;
+	    }
+
+	    /* Only switch if this is better than the current candidate */
+	    if (new_rate > cand_rate) {
+		cand_rate = new_rate;
+		candidate = obj;
+	    }
+	}
+    }
+
+    return(candidate);
+}
+
+explode(tp)
+register struct thing *tp;
+{
+
+    register int x,y, damage;
+    struct linked_list *item;
+    struct thing *th;
+
+    msg("the %s explodes!", monsters[tp->t_index].m_name);
+    /*
+     * check to see if it got the hero
+     */
+     if (DISTANCE(hero.x, hero.y, tp->t_pos.x, tp->t_pos.y) <= 25) {
+	msg("the explosion hits you");
+	damage = roll(6,6);
+	if (save(VS_WAND, &player, 0))
+	    damage /= 2;
+	if ((pstats.s_hpt -= damage) <= 0)
+	    death(tp->t_index);
+    }
+
+    /*
+     * now check for monsters in vicinity
+     */
+     for (x = tp->t_pos.x-5; x<=tp->t_pos.x+5; x++) {
+	 if (x < 0 || x > COLS - 1) 
+	     continue;
+	 for (y = tp->t_pos.y-5; y<=tp->t_pos.y+5; y++) {
+	    if (y < 1 || y > LINES - 3)
+		continue;
+	    if (isalpha(mvwinch(mw, y, x))) {
+		if ((item = find_mons(y, x)) != NULL) {
+		    th = THINGPTR(item);
+		    if (th == tp) /* don't count gas spore */
+			continue;
+		    damage = roll(6, 6);
+		    if (save(VS_WAND, th, 0))
+			damage /= 2;
+		    if ((tp->t_stats.s_hpt -= damage) <= 0) {
+			msg("the explosion kills the %s",
+				monsters[th->t_index].m_name);
+			killed(item, FALSE, FALSE);
+		    }
+		}
+	    }
+	}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/init.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,497 @@
+/*
+ * global variable initializaton
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include <ctype.h>
+#include "rogue.h"
+#include "mach_dep.h"
+
+
+char *rainbow[NCOLORS] = {
+
+"amber",		"aquamarine",		"beige",
+"black",		"blue",			"brown",
+"clear",		"crimson",		"ecru",
+"gold",			"green",		"grey",
+"indigo",		"khaki",		"lavender",
+"magenta",		"orange",		"pink",
+"plaid",		"purple",		"red",
+"silver",		"saffron",		"scarlet",
+"tan",			"tangerine", 		"topaz",
+"turquoise",		"vermilion",		"violet",
+"white",		"yellow",
+};
+
+char *sylls[NSYLLS] = {
+    "a",   "ab",  "ag",  "aks", "ala", "an",  "ankh","app", "arg", "arze",
+    "ash", "ban", "bar", "bat", "bek", "bie", "bin", "bit", "bjor",
+    "blu", "bot", "bu",  "byt", "comp","con", "cos", "cre", "dalf",
+    "dan", "den", "do",  "e",   "eep", "el",  "eng", "er",  "ere", "erk",
+    "esh", "evs", "fa",  "fid", "for", "fri", "fu",  "gan", "gar",
+    "glen","gop", "gre", "ha",  "he",  "hyd", "i",   "ing", "ion", "ip",
+    "ish", "it",  "ite", "iv",  "jo",  "kho", "kli", "klis","la",  "lech",
+    "man", "mar", "me",  "mi",  "mic", "mik", "mon", "mung","mur",
+    "nej", "nelg","nep", "ner", "nes", "nes", "nih", "nin", "o",   "od",
+    "ood", "org", "orn", "ox",  "oxy", "pay", "pet", "ple", "plu", "po",
+    "pot", "prok","re",  "rea", "rhov","ri",  "ro",  "rog", "rok", "rol",
+    "sa",  "san", "sat", "see", "sef", "seh", "shu", "ski", "sna",
+    "sne", "snik","sno", "so",  "sol", "sri", "sta", "sun", "ta",
+    "tab", "tem", "ther","ti",  "tox", "trol","tue", "turs","u",
+    "ulk", "um",  "un",  "uni", "ur",  "val", "viv", "vly", "vom", "wah",
+    "wed", "werg","wex", "whon","wun", "xo",  "y",   "yot", "yu",
+    "zant","zap", "zeb", "zim", "zok", "zon", "zum",
+};
+
+char *stones[NSTONES] = {
+	"agate",		"alexandrite",		"amethyst",
+	"azurite",		"bloodstone",		"cairngorm",
+	"carnelian",		"chalcedony",		"chrysoberyl",
+	"chrysolite",		"chrysoprase",		"citrine",
+	"coral",		"diamond",		"emerald",
+	"garnet",		"heliotrope",		"hematite",
+	"hyacinth",		"jacinth",		"jade",
+	"jargoon",		"jasper",		"kryptonite",
+	"lapus lazuli",		"malachite",		"mocca stone",
+	"moonstone",		"obsidian",		"olivine",
+	"onyx",			"opal",			"pearl",
+	"peridot",		"quartz",		"rhodochrosite",
+	"rhodolite",		"ruby",			"sapphire",
+	"sardonyx",		"serpintine",		"spinel",
+	"tiger eye",		"topaz",		"tourmaline",
+	"turquoise",		"zircon",
+};
+
+char *wood[NWOOD] = {
+	"avocado wood",	"balsa",	"banyan",	"birch",
+	"cedar",	"cherry",	"cinnibar",	"dogwood",
+	"driftwood",	"ebony",	"eucalyptus",	"hemlock",
+	"ironwood",	"mahogany",	"manzanita",	"maple",
+	"oak",		"pine",		"redwood",	"rosewood",
+	"teak",		"walnut",	"zebra wood", 	"persimmon wood",
+};
+
+char *metal[NMETAL] = {
+	"aluminium",	"bone",		"brass",	"bronze",
+	"copper",	"chromium",	"iron",		"lead",
+	"magnesium",	"pewter",	"platinum",	"silver",
+	"steel",	"tin",		"titanium",	"zinc",
+};
+
+
+
+
+/*
+ * make sure all the percentages specified in the tables add up to the
+ * right amounts
+ */
+badcheck(name, magic, bound)
+char *name;
+register struct magic_item *magic;
+register int bound;
+{
+    register struct magic_item *end;
+
+    if (magic[bound - 1].mi_prob == 1000)
+	return;
+    printf("\nBad percentages for %s:\n", name);
+    for (end = &magic[bound] ; magic < end ; magic++)
+	printf("%4d%% %s\n", magic->mi_prob, magic->mi_name);
+    printf(retstr);
+    fflush(stdout);
+    while (getchar() != '\n')
+	continue;
+}
+
+/*
+ * init_colors:
+ *	Initialize the potion color scheme for this time
+ */
+
+init_colors()
+{
+    register int i, j;
+    bool used[NCOLORS];
+
+    for(i = 0; i < NCOLORS; i++)
+        used[i] = FALSE;
+
+    for (i = 0 ; i < MAXPOTIONS ; i++)
+    {
+	do
+	    j = rnd(NCOLORS);
+        until (!used[j]);
+        used[j] = TRUE;
+	p_colors[i] = rainbow[j];
+	p_know[i] = FALSE;
+	p_guess[i] = NULL;
+	if (i > 0)
+		p_magic[i].mi_prob += p_magic[i-1].mi_prob;
+    }
+    badcheck("potions", p_magic, MAXPOTIONS);
+}
+
+/*
+ * init_materials:
+ *	Initialize the construction materials for wands and staffs
+ */
+
+init_materials()
+{
+    register int i, j;
+    register char *str;
+    bool metused[NMETAL], woodused[NWOOD];
+
+    for(i = 0; i < NWOOD; i++)
+        woodused[i] = FALSE;
+
+    for(i = 0; i < NMETAL; i++)
+        metused[i] = FALSE;
+
+    for (i = 0 ; i < MAXSTICKS ; i++)
+    {
+        for (;;)
+	    if (rnd(100) > 50)
+	    { 
+                j = rnd(NMETAL);
+
+                if (!metused[j])
+                {
+                    ws_type[i] = "wand";
+                    str = metal[j];
+                    metused[j] = TRUE;
+                    break;
+                }
+            }
+            else
+            {
+                j = rnd(NWOOD);
+
+                if (!woodused[j])
+                {
+                    ws_type[i] = "staff";
+                    str = wood[j];
+                    woodused[j] = TRUE;
+                    break;
+                }
+            }
+
+        ws_made[i] = str;
+	ws_know[i] = FALSE;
+	ws_guess[i] = NULL;
+	if (i > 0)
+		ws_magic[i].mi_prob += ws_magic[i-1].mi_prob;
+    }
+    badcheck("sticks", ws_magic, MAXSTICKS);
+}
+
+/*
+ * do any initialization for miscellaneous magic
+ */
+
+init_misc()
+{
+    register int i;
+
+    for (i=0; i < MAXMM; i++) {
+	m_know[i] = FALSE;
+	m_guess[i] = NULL;
+	if (i > 0)
+	    m_magic[i].mi_prob += m_magic[i-1].mi_prob;
+    }
+
+    badcheck("miscellaneous magic", m_magic, MAXMM);
+}
+
+
+/*
+ * init_names:
+ *	Generate the names of the various scrolls
+ */
+
+init_names()
+{
+    register int nsyl;
+    register char *cp, *sp;
+    register int i, nwords;
+
+    for (i = 0 ; i < MAXSCROLLS ; i++)
+    {
+	cp = prbuf;
+	nwords = rnd(COLS/20) + 1 + (COLS > 40 ? 1 : 0);
+	while(nwords--)
+	{
+	    nsyl = rnd(3)+1;
+	    while(nsyl--)
+	    {
+		sp = sylls[rnd((sizeof sylls) / (sizeof (char *)))];
+		while(*sp)
+		    *cp++ = *sp++;
+	    }
+	    *cp++ = ' ';
+	}
+	*--cp = '\0';
+	s_names[i] = (char *) new(strlen(prbuf)+1);
+	s_know[i] = FALSE;
+	s_guess[i] = NULL;
+	strcpy(s_names[i], prbuf);
+	if (i > 0)
+		s_magic[i].mi_prob += s_magic[i-1].mi_prob;
+    }
+    badcheck("scrolls", s_magic, MAXSCROLLS);
+}
+
+/*
+ * init_player:
+ *	roll up the rogue
+ */
+
+init_player()
+{
+    int stat_total, ch = 0, wpt = 0, i, j;
+    struct linked_list *weap_item, *armor_item, *food_item;
+    struct object *obj;
+    char *class;
+
+    weap_item = armor_item = NULL;
+
+    if (char_type == -1) {
+	/* See what type character will be */
+	wclear(hw);
+	touchwin(hw);
+	mvwaddstr(hw,2,0,"[1] Fighter\n[2] Magician\n[3] Cleric\n[4] Thief");
+	mvwaddstr(hw, 0, 0, "What character class do you desire? ");
+	draw(hw);
+	char_type = (wgetch(hw) - '0');
+	while (char_type < 1 || char_type > 4) {
+	    mvwaddstr(hw,0,0,"Please enter a character type between 1 and 4: ");
+	    draw(hw);
+	    char_type = (wgetch(hw) - '0');
+	}
+	char_type--;
+    }
+    player.t_ctype = char_type;
+    player.t_quiet = 0;
+    pack = NULL;
+
+#ifdef WIZARD
+    /* 
+     * allow me to describe a super character 
+     */
+    if (wizard && md_getuid() == AUTHOR && strcmp(getenv("SUPER"),"YES") == 0) {
+	    pstats.s_str = 25;
+	    pstats.s_intel = 25;
+	    pstats.s_wisdom = 25;
+	    pstats.s_dext = 25;
+	    pstats.s_const = 25;
+	    pstats.s_charisma = 25;
+	    pstats.s_exp = 7500000L;
+	    pstats.s_lvl = 20;
+	    pstats.s_hpt = 500;
+	    pstats.s_carry = totalenc();
+	    strcpy(pstats.s_dmg,"3d4");
+	    if (player.t_ctype == C_FIGHTER)
+		weap_item = spec_item(WEAPON, TWOSWORD, 5, 5);
+	    else
+		weap_item = spec_item(WEAPON, SWORD, 5, 5);
+	    obj = OBJPTR(weap_item);
+	    obj->o_flags |= ISKNOW;
+	    add_pack(weap_item, TRUE, NULL);
+	    cur_weapon = obj;
+	    j = PLATE_ARMOR;
+	    if (player.t_ctype == C_THIEF)
+		j = STUDDED_LEATHER;
+	    armor_item = spec_item(ARMOR, j, 10, 0);
+	    obj = OBJPTR(armor_item);
+	    obj->o_flags |= (ISKNOW | ISPROT);
+	    obj->o_weight = armors[j].a_wght;
+	    add_pack(armor_item, TRUE, NULL);
+	    cur_armor = obj;
+	    purse += 10000;
+    }
+    else 
+#endif
+
+    {
+	wclear(hw);
+	do {
+	    if (armor_item != NULL) {
+		o_discard(armor_item);
+		armor_item = NULL;
+	    }
+	    if (weap_item != NULL) {
+		o_discard(weap_item);
+		weap_item = NULL;
+	    }
+	    pstats.s_lvl = 1;
+	    pstats.s_exp = 0L;
+	    pstats.s_hpt = 12 + rnd(10);
+	    pstats.s_str = 7 + rnd(5);
+	    pstats.s_intel = 7 + rnd(5);
+	    pstats.s_wisdom = 7 + rnd(5);
+	    pstats.s_dext = 7 + rnd(5);
+	    pstats.s_const = 14 + rnd(5);
+	    pstats.s_charisma = 7 + rnd(5);
+
+	    /* Now for the special ability */
+	    switch (char_type) {
+		case C_FIGHTER:  pstats.s_str	= (rnd(10) == 7) ? 18 : 16;
+		when C_MAGICIAN: pstats.s_intel	= (rnd(10) == 7) ? 18 : 16;
+		when C_CLERIC:   pstats.s_wisdom= (rnd(10) == 7) ? 18 : 16;
+		when C_THIEF:    pstats.s_dext	= (rnd(10) == 7) ? 18 : 16;
+	    }
+	    strcpy(pstats.s_dmg,"1d4");
+	    stat_total =pstats.s_str  + pstats.s_intel + pstats.s_wisdom +
+			pstats.s_dext + pstats.s_const;
+	    /*
+	     * since the player can re-roll stats at will, keep the maximum
+	     * to some reasonable limit
+	     */
+	    if (stat_total > MAXSTATS)
+		pstats.s_const -= (stat_total - MAXSTATS);
+	    pstats.s_carry = totalenc();
+
+	    /*
+	     * Give the rogue his weaponry.  
+	     */
+	    do {
+		i = rnd(8);	/* number of acceptable weapons */
+		switch(i) {
+		    case 0: ch = 25; wpt = MACE;
+		    when 1: ch = 25; wpt = SWORD;
+		    when 2: ch = 20; wpt = BATTLEAXE;
+		    when 3: ch = 20; wpt = TRIDENT;
+		    when 4: ch = 20; wpt = SPETUM;
+		    when 5: ch = 20; wpt = BARDICHE;
+		    when 6: ch = 15; wpt = PIKE;
+		    when 7: ch = 20; wpt = HALBERD;
+		}
+	    } while(rnd(100) > ch);
+	    if (player.t_ctype == C_FIGHTER)
+		wpt = TWOSWORD;
+	    weap_item = spec_item(WEAPON, wpt, rnd(2), rnd(2)+1);
+	    obj = OBJPTR(weap_item);
+	    obj->o_flags |= ISKNOW;
+	    /*
+	     * And his suit of armor.......
+	     * Thieves can only wear leather armor
+	     * fighters get better armor on an average
+	     */
+	    if (player.t_ctype == C_THIEF)
+		j = STUDDED_LEATHER;
+	    else {
+		if (player.t_ctype == C_FIGHTER)
+		    i = 50 + rnd(50);
+		else
+		    i = rnd(100);
+		j = 0;
+		while (armors[j].a_prob < i)
+		    j++;
+	    }
+	    armor_item = spec_item(ARMOR, j, 0, 0);
+	    obj = OBJPTR(armor_item);
+	    obj->o_flags |= ISKNOW;
+	    obj->o_weight = armors[j].a_wght;
+	    switch(player.t_ctype) {
+		case C_FIGHTER:	class = "fighter";
+		when C_MAGICIAN:class = "magic user";
+		when C_CLERIC:	class = "cleric";
+		when C_THIEF:	class = "thief";
+		otherwise:	class = "unknown";
+	    }
+	    wmove(hw, 2, 0);
+	    wprintw(hw, "You have rolled a %s with the following attributes:",class);
+	    wmove(hw,4,0);
+	    wprintw(hw, "    Int: %2d", pstats.s_intel);
+	    wprintw(hw, "    Str: %2d", pstats.s_str);
+	    wprintw(hw, "    Wis: %2d", pstats.s_wisdom); 
+	    wprintw(hw, "    Dex: %2d", pstats.s_dext);
+	    wprintw(hw, "  Const: %2d", pstats.s_const);
+	    wclrtoeol(hw);
+	    wmove(hw, 6, 0);
+	    wprintw(hw, "     Hp: %2d", pstats.s_hpt);
+	    wclrtoeol(hw);
+	    mvwaddstr(hw, 8, 5, inv_name(OBJPTR(weap_item), FALSE));
+	    wclrtoeol(hw);
+	    mvwaddstr(hw, 9, 5, inv_name(OBJPTR(armor_item), FALSE));
+	    wclrtoeol(hw);
+	    mvwaddstr(hw,0,0,"Would you like to re-roll the character? ");
+	    draw(hw);
+	} while(wgetch(hw) == 'y');
+
+	obj = OBJPTR(weap_item);
+	add_pack(weap_item, TRUE, NULL);
+	cur_weapon = obj;
+	obj = OBJPTR(armor_item);
+	add_pack(armor_item, TRUE, NULL);
+	cur_armor = obj;
+    }
+    /*
+     * Give him some food
+     */
+    food_item = spec_item(FOOD, 0, 0, 0);
+    obj = OBJPTR(food_item);
+    obj->o_weight = things[TYP_FOOD].mi_wght;
+    add_pack(food_item, TRUE, NULL);
+    pstats.s_arm = 10;
+    max_stats = pstats;
+}
+
+
+
+
+
+
+/*
+ * init_stones:
+ *	Initialize the ring stone setting scheme for this time
+ */
+
+init_stones()
+{
+    register int i, j;
+    bool used[NSTONES];
+
+    for (i = 0; i < NSTONES; i++)
+        used[i] = FALSE;
+
+    for (i = 0 ; i < MAXRINGS ; i++)
+    {
+	do
+            j = rnd(NSTONES);
+        until (!used[j]);
+
+        used[j] = TRUE;
+	r_stones[i] = stones[j];
+	r_know[i] = FALSE;
+	r_guess[i] = NULL;
+	if (i > 0)
+		r_magic[i].mi_prob += r_magic[i-1].mi_prob;
+    }
+    badcheck("rings", r_magic, MAXRINGS);
+}
+
+/*
+ * init_things
+ *	Initialize the probabilities for types of things
+ */
+init_things()
+{
+    register struct magic_item *mp;
+
+    for (mp = &things[1] ; mp < &things[NUMTHINGS] ; mp++)
+	mp->mi_prob += (mp-1)->mi_prob;
+    badcheck("things", things, NUMTHINGS);
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/io.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,489 @@
+/*
+ * Various input/output functions
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include <ctype.h>
+#include <stdarg.h>
+#include "rogue.h"
+
+/*
+ * msg:
+ *	Display a message at the top of the screen.
+ */
+
+static char msgbuf[BUFSIZ];
+static int newpos = 0;
+
+/*VARARGS1*/
+msg(char *fmt, ...)
+{
+    va_list ap;
+    /*
+     * if the string is "", just clear the line
+     */
+    if (*fmt == '\0')
+    {
+	overwrite(cw,msgw);
+	wmove(msgw, 0, 0);
+	clearok(msgw, FALSE);
+	draw(msgw);
+	mpos = 0;
+	return;
+    }
+    /*
+     * otherwise add to the message and flush it out
+     */
+    va_start(ap,fmt);
+    doadd(fmt, ap);
+    va_end(ap);
+    endmsg();
+}
+
+/*
+ * add things to the current message
+ */
+addmsg(char *fmt, ...)
+{
+    va_list ap;
+    va_start(ap,fmt);
+    doadd(fmt, ap);
+    va_end(ap);
+}
+
+/*
+ * Display a new msg (giving him a chance to see the previous one if it
+ * is up there with the --More--)
+ */
+endmsg()
+{
+    strncpy(huh, msgbuf, sizeof(huh));
+
+    huh[ sizeof(huh) - 1 ] = 0;
+
+    if (mpos)
+    {
+	wmove(msgw, 0, mpos);
+	waddstr(msgw, morestr);
+	draw(cw);
+	draw(msgw);
+	wait_for(msgw,' ');
+	overwrite(cw,msgw);
+	wmove(msgw,0,0);
+	touchwin(cw);
+    }
+    else {
+	overwrite(cw,msgw);
+	wmove(msgw,0,0);
+    }
+    waddstr(msgw, msgbuf);
+    mpos = newpos;
+    newpos = 0;
+    msgbuf[0] = '\0';
+    draw(cw);
+    clearok(msgw, FALSE);
+    draw(msgw);
+}
+
+doadd(char *fmt, va_list ap)
+{
+    /*
+     * Do the sprintf into newmsg and append to msgbuf
+     */
+
+    vsnprintf(&msgbuf[newpos], sizeof(msgbuf)-newpos-1, fmt, ap);
+
+    newpos = strlen(msgbuf);
+}
+
+/*
+ * step_ok:
+ *	returns true if it is ok for type to step on ch
+ *	flgptr will be NULL if we don't know what the monster is yet!
+ */
+
+step_ok(y, x, can_on_monst, flgptr)
+register int y, x, can_on_monst;
+register struct thing *flgptr;
+{
+    /* can_on_monst = MONSTOK if all we care about are physical obstacles */
+    register struct linked_list *item;
+    char ch;
+
+    /* What is here?  Don't check monster window if MONSTOK is set */
+    if (can_on_monst == MONSTOK) ch = CCHAR( mvinch(y, x) );
+    else ch = CCHAR( winat(y, x) );
+
+    switch (ch)
+    {
+	case ' ':
+	case '|':
+	case '-':
+	case SECRETDOOR:
+	    if (flgptr && on(*flgptr, CANINWALL)) return(TRUE);
+	    return FALSE;
+	when SCROLL:
+	    if (can_on_monst == MONSTOK) return(TRUE); /* Not a real obstacle */
+	    /*
+	     * If it is a scroll, it might be a scare monster scroll
+	     * so we need to look it up to see what type it is.
+	     */
+	    if (flgptr && flgptr->t_ctype == C_MONSTER) {
+		item = find_obj(y, x);
+		if (item != NULL &&
+		    (OBJPTR(item))->o_which==S_SCARE &&
+		    (flgptr == NULL || flgptr->t_stats.s_intel < 16))
+			return(FALSE); /* All but smart ones are scared */
+	    }
+	    return(TRUE);
+	otherwise:
+	    return (!isalpha(ch));
+    }
+}
+/*
+ * shoot_ok:
+ *	returns true if it is ok for type to shoot over ch
+ */
+
+shoot_ok(ch)
+{
+    switch (ch)
+    {
+	case ' ':
+	case '|':
+	case '-':
+	case SECRETDOOR:
+	case FOREST:
+	    return FALSE;
+	default:
+	    return (!isalpha(ch));
+    }
+}
+
+/*
+ * readchar:
+ *	flushes stdout so that screen is up to date and then returns
+ *	getchar.
+ */
+
+readchar()
+{
+    int ch;
+
+    ch = md_readchar(cw);
+
+    if ((ch == 3) || (ch == 0))
+    {
+        quit(0);
+        return(27);
+    }
+
+    return(ch);
+}
+
+/*
+ * status:
+ *	Display the important stats line.  Keep the cursor where it was.
+ */
+
+status(display)
+bool display;	/* is TRUE, display unconditionally */
+{
+    register struct stats *stat_ptr, *max_ptr;
+    register int oy = 0, ox = 0, temp;
+    register char *pb;
+    static char buf[LINELEN];
+    static int hpwidth = 0, s_hungry = -1;
+    static int s_lvl = -1, s_pur, s_hp = -1, s_str, maxs_str, 
+		s_ac = 0;
+    static short s_intel, s_dext, s_wisdom, s_const, s_charisma;
+    static short maxs_intel, maxs_dext, maxs_wisdom, maxs_const, maxs_charisma;
+    static unsigned long s_exp = 0;
+    static int s_carry, s_pack;
+    bool first_line=FALSE;
+
+    /* Use a mini status version if we have a small window */
+    if (COLS < 80) {
+	ministat();
+	return;
+    }
+
+    stat_ptr = &pstats;
+    max_ptr  = &max_stats;
+
+    /*
+     * If nothing has changed in the first line, then skip it
+     */
+    if (!display				&&
+	s_lvl == level				&& 
+	s_intel == stat_ptr->s_intel		&&
+	s_wisdom == stat_ptr->s_wisdom		&&
+	s_dext == dex_compute()			&& 
+	s_const == stat_ptr->s_const		&&
+	s_charisma == stat_ptr->s_charisma	&&
+	s_str == str_compute()			&& 
+	s_pack == stat_ptr->s_pack		&&
+	s_carry == stat_ptr->s_carry		&&
+	maxs_intel == max_ptr->s_intel		&& 
+	maxs_wisdom == max_ptr->s_wisdom	&&
+	maxs_dext == max_ptr->s_dext		&& 
+	maxs_const == max_ptr->s_const		&&
+	maxs_charisma == max_ptr->s_charisma	&&
+	maxs_str == max_ptr->s_str		) goto line_two;
+
+    /* Display the first line */
+    first_line = TRUE;
+    getyx(cw, oy, ox);
+    sprintf(buf, "Int:%d(%d)  Str:%d", stat_ptr->s_intel,
+    	max_ptr->s_intel, str_compute());
+
+    /* Maximum strength */
+    pb = &buf[strlen(buf)];
+    sprintf(pb, "(%d)", max_ptr->s_str);
+
+    pb = &buf[strlen(buf)];
+    sprintf(pb, "  Wis:%d(%d)  Dxt:%d(%d)  Const:%d(%d)  Carry:%d(%d)",
+	stat_ptr->s_wisdom,max_ptr->s_wisdom,dex_compute(),max_ptr->s_dext,
+	stat_ptr->s_const,max_ptr->s_const,stat_ptr->s_pack/10,
+	stat_ptr->s_carry/10);
+
+    /* Update first line status */
+    s_intel = stat_ptr->s_intel;
+    s_wisdom = stat_ptr->s_wisdom;
+    s_dext = dex_compute();
+    s_const = stat_ptr->s_const;
+    s_charisma = stat_ptr->s_charisma;
+    s_str = str_compute();
+    s_pack = stat_ptr->s_pack;
+    s_carry = stat_ptr->s_carry;
+    maxs_intel = max_ptr->s_intel;
+    maxs_wisdom = max_ptr->s_wisdom;
+    maxs_dext = max_ptr->s_dext;
+    maxs_const = max_ptr->s_const;
+    maxs_charisma = max_ptr->s_charisma;
+    maxs_str = max_ptr->s_str;
+
+    /* Print the line */
+    mvwaddstr(cw, LINES - 2, 0, buf);
+    wclrtoeol(cw);
+
+    /*
+     * If nothing has changed since the last status, don't
+     * bother.
+     */
+line_two: 
+    if (!display					&&
+	s_hp == stat_ptr->s_hpt				&& 
+	s_exp == stat_ptr->s_exp			&& 
+        s_pur == purse					&& 
+	s_ac == ac_compute() - dext_prot(s_dext)	&&
+	s_lvl == level 					&& 
+	s_hungry == hungry_state			) return;
+	
+    if (!first_line) getyx(cw, oy, ox);
+    if (s_hp != max_ptr->s_hpt)
+    {
+	temp = s_hp = max_ptr->s_hpt;
+	for (hpwidth = 0; temp; hpwidth++)
+	    temp /= 10;
+    }
+    sprintf(buf, "Lvl:%d  Au:%d  Hp:%*d(%*d)  Ac:%d  Exp:%d/%lu  %s",
+	level, purse, hpwidth, stat_ptr->s_hpt, hpwidth, max_ptr->s_hpt,
+	ac_compute() - dext_prot(s_dext),stat_ptr->s_lvl, stat_ptr->s_exp, 
+	cnames[player.t_ctype][min(stat_ptr->s_lvl-1, 10)]);
+
+    /*
+     * Save old status
+     */
+    s_lvl = level;
+    s_pur = purse;
+    s_hp = stat_ptr->s_hpt;
+    s_exp = stat_ptr->s_exp; 
+    s_ac = ac_compute() - dext_prot(s_dext);
+    mvwaddstr(cw, LINES - 1, 0, buf);
+    switch (hungry_state)
+    {
+	case F_OKAY: ;
+	when F_HUNGRY:
+	    waddstr(cw, "  Hungry");
+	when F_WEAK:
+	    waddstr(cw, "  Weak");
+	when F_FAINT:
+	    waddstr(cw, "  Fainting");
+    }
+    wclrtoeol(cw);
+    s_hungry = hungry_state;
+    wmove(cw, oy, ox);
+}
+
+ministat()
+{
+    register int oy, ox, temp;
+    static char buf[LINELEN];
+    static int hpwidth = 0;
+    static int s_lvl = -1, s_pur, s_hp = -1;
+
+    /*
+     * If nothing has changed since the last status, don't
+     * bother.
+     */
+    if (s_hp == pstats.s_hpt && s_pur == purse && s_lvl == level)
+	    return;
+	
+    getyx(cw, oy, ox);
+    if (s_hp != max_stats.s_hpt)
+    {
+	temp = s_hp = max_stats.s_hpt;
+	for (hpwidth = 0; temp; hpwidth++)
+	    temp /= 10;
+    }
+    sprintf(buf, "Lv: %d  Au: %-5d  Hp: %*d(%*d)",
+	level, purse, hpwidth, pstats.s_hpt, hpwidth, max_stats.s_hpt);
+
+    /*
+     * Save old status
+     */
+    s_lvl = level;
+    s_pur = purse;
+    s_hp = pstats.s_hpt;
+    mvwaddstr(cw, LINES - 1, 0, buf);
+    wclrtoeol(cw);
+    wmove(cw, oy, ox);
+}
+
+/*
+ * wait_for
+ *	Sit around until the guy types the right key
+ */
+
+wait_for(win,ch)
+WINDOW *win;
+register char ch;
+{
+    register char c;
+
+    if (ch == '\n')
+        while ((c = wgetch(win)) != '\n' && c != '\r')
+	    continue;
+    else
+        while (wgetch(win) != ch)
+	    continue;
+}
+
+/*
+ * show_win:
+ *	function used to display a window and wait before returning
+ */
+
+show_win(scr, message)
+register WINDOW *scr;
+char *message;
+{
+    mvwaddstr(scr, 0, 0, message);
+    touchwin(scr);
+    wmove(scr, hero.y, hero.x);
+    draw(scr);
+    wait_for(scr,' ');
+    clearok(cw, TRUE);
+    touchwin(cw);
+}
+
+/*
+ * dbotline:
+ *	Displays message on bottom line and waits for a space to return
+ */
+dbotline(scr,message)
+WINDOW *scr;
+char *message;
+{
+	mvwaddstr(scr,LINES-1,0,message);
+	draw(scr);
+	wait_for(scr,' ');	
+}
+
+
+/*
+ * restscr:
+ *	Restores the screen to the terminal
+ */
+restscr(scr)
+WINDOW *scr;
+{
+	clearok(scr,TRUE);
+	touchwin(scr);
+}
+
+/*
+ * netread:
+ *	Read a byte, short, or long machine independently
+ *	Always returns the value as an unsigned long.
+ */
+
+unsigned long
+netread(error, size, stream)
+int *error;
+int size;
+FILE *stream;
+{
+    unsigned long result = 0L,	/* What we read in */
+		  partial;	/* Partial value */
+    int nextc,	/* The next byte */
+	i;	/* To index through the result a byte at a time */
+
+    /* Be sure we have a right sized chunk */
+    if (size < 1 || size > 4) {
+	*error = 1;
+	return(0L);
+    }
+
+    for (i=0; i<size; i++) {
+	nextc = getc(stream);
+	if (nextc == EOF) {
+	    *error = 1;
+	    return(0L);
+	}
+	else {
+	    partial = (unsigned long) (nextc & 0xff);
+	    partial <<= 8*i;
+	    result |= partial;
+	}
+    }
+
+    *error = 0;
+    return(result);
+}
+
+
+
+/*
+ * netwrite:
+ *	Write out a byte, short, or long machine independently.
+ */
+
+netwrite(value, size, stream)
+unsigned long value;	/* What to write */
+int size;	/* How much to write out */
+FILE *stream;	/* Where to write it */
+{
+    int i;	/* Goes through value one byte at a time */
+    char outc;	/* The next character to be written */
+
+    /* Be sure we have a right sized chunk */
+    if (size < 1 || size > 4) return(0);
+
+    for (i=0; i<size; i++) {
+	outc = (char) ((value >> (8 * i)) & 0xff);
+	putc(outc, stream);
+    }
+    return(size);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/list.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,185 @@
+/*
+ * Functions for dealing with linked lists of goodies
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include <stdlib.h>
+#include "curses.h"
+#include "rogue.h"
+
+/*
+ * detach:
+ *	Takes an item out of whatever linked list it might be in
+ */
+
+_detach(list, item)
+register struct linked_list **list, *item;
+{
+    if (*list == item)
+	*list = next(item);
+    if (prev(item) != NULL) item->l_prev->l_next = next(item);
+    if (next(item) != NULL) item->l_next->l_prev = prev(item);
+    item->l_next = NULL;
+    item->l_prev = NULL;
+}
+
+/*
+ * _attach:
+ *	add an item to the head of a list
+ */
+
+_attach(list, item)
+register struct linked_list **list, *item;
+{
+    if (*list != NULL)
+    {
+	item->l_next = *list;
+	(*list)->l_prev = item;
+	item->l_prev = NULL;
+    }
+    else
+    {
+	item->l_next = NULL;
+	item->l_prev = NULL;
+    }
+
+    *list = item;
+}
+
+/*
+ * o_free_list:
+ *	Throw the whole object list away
+ */
+
+_o_free_list(ptr)
+register struct linked_list **ptr;
+{
+    register struct linked_list *item;
+
+    while (*ptr != NULL)
+    {
+	item = *ptr;
+	*ptr = next(item);
+	o_discard(item);
+    }
+}
+
+/*
+ * o_discard:
+ *	free up an item and its object(and maybe contents)
+ */
+
+o_discard(item)
+register struct linked_list *item;
+{
+    register struct object *obj;
+    obj = OBJPTR(item);
+    if (obj->contents != NULL)
+	o_free_list(obj->contents);
+    total -= 2;
+    FREE(item->l_data);
+    FREE(item);
+}
+
+/*
+ * t_free_list:
+ *	Throw the whole thing list away
+ */
+
+_t_free_list(ptr)
+register struct linked_list **ptr;
+{
+    register struct linked_list *item;
+
+    while (*ptr != NULL)
+    {
+	item = *ptr;
+	*ptr = next(item);
+	t_discard(item);
+    }
+}
+
+/*
+ * t_discard:
+ *	free up an item and its thing
+ */
+
+t_discard(item)
+struct linked_list *item;
+{
+    total -= 2;
+    FREE(item->l_data);
+    FREE(item);
+}
+
+/*
+ * destroy_item:
+ *	get rid of an item structure -- don't worry about contents
+ */
+
+destroy_item(item)
+register struct linked_list *item;
+{
+    total--;
+    FREE(item);
+}
+
+/*
+ * new_item
+ *	get a new item with a specified size
+ */
+
+struct linked_list *
+new_item(size)
+int size;
+{
+    register struct linked_list *item;
+
+    if ((item = (struct linked_list *) new(sizeof *item)) == NULL)
+	msg("Ran out of memory for header after %d items", total);
+    if ((item->l_data = new(size)) == NULL)
+	msg("Ran out of memory for data after %d items", total);
+    item->l_next = item->l_prev = NULL;
+    return item;
+}
+
+/*
+ * creat_item:
+ *	Create just an item structure -- don't make any contents
+ */
+
+struct linked_list *
+creat_item()
+{
+    register struct linked_list *item;
+
+    if ((item = (struct linked_list *) new(sizeof *item)) == NULL)
+	msg("Ran out of memory for header after %d items", total);
+    item->l_next = item->l_prev = NULL;
+    return item;
+}
+
+char *
+new(size)
+int size;
+{
+    register char *space = ALLOC(size);
+    static char errbuf[LINELEN];
+
+    if (space == NULL) {
+	sprintf(errbuf,"Rogue ran out of memory (used = %d, wanted = %d).",
+		md_memused(), size);
+	fatal(errbuf);
+    }
+    total++;
+    return space;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/mach_dep.h	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,64 @@
+/*
+ * machine dependicies
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+/*
+ * define that the wizard commands exist
+ */
+#define WIZARD	1
+
+/*
+ * define if you want to limit scores to one per class per userid
+ */
+#undef LIMITSCORE 
+
+/*
+ * where scorefile should live
+ */
+#define SCOREFILE	"/bnr/contrib/lib/rogue/scorefile"
+
+/*
+ * Variables for checking to make sure the system isn't too loaded
+ * for people to play
+ */
+
+#undef	MAXUSERS	/*40*/	/* max number of users for this game */
+#undef	MAXLOAD		/*40*/	/* 10 * max 15 minute load average */
+
+#undef	CHECKTIME	/*15*/	/* number of minutes between load checks */
+				/* if not defined checks are only on startup */
+
+#ifdef MAXLOAD
+#define	LOADAV			/* defined if rogue should provide loadav() */
+
+#ifdef LOADAV
+#define	NAMELIST	"/unix"	/* where the system namelist lives */
+#endif
+#endif
+
+#ifdef MAXUSERS
+#define	UCOUNT			/* defined if rogue should provide ucount() */
+
+#ifdef UCOUNT
+#define UTMP	"/etc/utmp"	/* where utmp file lives */
+#endif
+#endif
+
+#undef AUTHOR /*212*/
+
+/*
+ * define the current author of the program for "special handling"
+ */
+#ifndef AUTHOR
+#define AUTHOR 0	/* Default to root if not specified above */
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/main.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,530 @@
+/* 
+ * Rogue
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include <signal.h>
+#include <time.h>
+#include "mach_dep.h"
+#include "network.h"
+#include "rogue.h"
+
+#ifdef CHECKTIME
+static int num_checks;		/* times we've gone over in checkout() */
+#endif
+
+/*
+ * fruits that you get at startup
+ */
+static char *funfruit[] = {
+	"candleberry",	"caprifig",	"dewberry",	"elderberry",
+	"gooseberry",	"guanabana",	"hagberry",	"ilama",
+	"imbu",		"jaboticaba",	"jujube",	"litchi",	
+	"mombin",	"pitanga",	"prickly pear", "rambutan",
+	"sapodilla",	"soursop",	"sweetsop",	"whortleberry",
+	"jellybean",	"apple",	"strawberry",	"blueberry",
+	"peach",	"banana"
+};
+#define NFRUIT (sizeof(funfruit) / sizeof (char *))
+
+main(argc, argv, envp)
+char **argv;
+char **envp;
+{
+    register char *env;
+    int lowtime;
+    time_t now;
+    char *roguedir = md_getroguedir();
+
+    md_init();
+
+    /*
+     * get home and options from environment
+     */
+
+    strncpy(home,md_gethomedir(),LINELEN);
+
+    /* Get default save file */
+    strcpy(file_name, home);
+    strcat(file_name, "arogue58.sav");
+
+    /* Get default score file */
+    strcpy(score_file, roguedir);
+
+    if (*score_file)
+        strcat(score_file,"/");
+
+    strcat(score_file, "arogue58.scr");
+
+    if ((env = getenv("ROGUEOPTS")) != NULL)
+	parse_opts(env);
+
+    if (whoami[0] == '\0')
+        strucpy(whoami, md_getusername(), strlen(md_getusername()));
+
+    if (env == NULL || fruit[0] == '\0') {
+	md_srand((long)(getpid()+time(0)));
+	strcpy(fruit, funfruit[rnd(NFRUIT)]);
+    }
+
+    /*
+     * check for print-score option
+     */
+    if (argc == 2 && strcmp(argv[1], "-s") == 0)
+    {
+	waswizard = TRUE;
+	score(0, SCOREIT, 0);
+	exit(0);
+    }
+
+#ifdef NUMNET
+    /*
+     * Check for a network update
+     */
+    if (argc == 2 && strcmp(argv[1], "-u") == 0) {
+	unsigned long netread();
+	int errcheck, errors = 0;
+	unsigned long amount;
+	short monster;
+
+	/* Read in the amount and monster values to pass to score */
+	amount = netread(&errcheck, sizeof(unsigned long), stdin);
+	if (errcheck) errors++;
+
+	monster = (short) netread(&errcheck, sizeof(short), stdin);
+	if (errcheck) errors++;
+
+	/* Now do the update if there were no errors */
+	if (errors) exit(1);
+	else {
+	    score(amount, UPDATE, monster);
+	    exit(0);
+	}
+    }
+#endif
+
+#ifdef WIZARD
+    /*
+     * Check to see if he is a wizard
+     */
+    if (argc >= 2 && argv[1][0] == '\0')
+	if (strcmp(PASSWD, md_crypt(md_getpass("Wizard's password: "), "Si")) == 0)
+	{
+	    printf("Hail Mighty Wizard\n");
+	    wizard = TRUE;
+	    argv++;
+	    argc--;
+	}
+#endif
+
+#if MAXLOAD|MAXUSERS
+    if (too_much() && !wizard && !author())
+    {
+	printf("Sorry, %s, but the system is too loaded now.\n", whoami);
+	printf("Try again later.  Meanwhile, why not enjoy a%s %s?\n",
+	    vowelstr(fruit), fruit);
+	exit(1);
+    }
+#endif
+    if (argc == 2)
+	if (!restore(argv[1], envp)) /* Note: restore will never return */
+	    exit(1);
+    lowtime = (int) time(&now);
+    dnum = (wizard && getenv("SEED") != NULL ?
+	atoi(getenv("SEED")) :
+	lowtime + getpid());
+    if (wizard)
+	printf("Hello %s, welcome to dungeon #%d\n", whoami, dnum);
+    else
+	printf("Hello %s, just a moment while I dig the dungeon...\n", whoami);
+    fflush(stdout);
+    seed = dnum;
+    md_srand(seed);
+
+    init_things();			/* Set up probabilities of things */
+    init_colors();			/* Set up colors of potions */
+    init_stones();			/* Set up stone settings of rings */
+    init_materials();			/* Set up materials of wands */
+    initscr();				/* Start up cursor package */
+    init_names();			/* Set up names of scrolls */
+    init_misc();			/* Set up miscellaneous magic */
+    if (LINES < 24 || COLS < 80) {
+	printf("\nERROR: screen size to small for rogue\n");
+	byebye(-1);
+    }
+
+    if ((whoami == NULL) || (*whoami == '\0') || (strcmp(whoami,"dosuser")==0))
+    {
+        echo();
+        mvaddstr(23,2,"Rogue's Name? ");
+        wgetnstr(stdscr,whoami,LINELEN);
+        noecho();
+    }
+
+    if ((whoami == NULL) || (*whoami == '\0'))
+        strcpy(whoami,"Rodney");
+
+    setup();
+    /*
+     * Set up windows
+     */
+    cw = newwin(LINES, COLS, 0, 0);
+    mw = newwin(LINES, COLS, 0, 0);
+    hw = newwin(LINES, COLS, 0, 0);
+    msgw = newwin(4, COLS, 0, 0);
+    keypad(cw,1);
+    keypad(msgw,1);
+
+    init_player();			/* Roll up the rogue */
+    waswizard = wizard;
+    new_level(NORMLEV);			/* Draw current level */
+    /*
+     * Start up daemons and fuses
+     */
+    daemon(doctor, &player, AFTER);
+    fuse(swander, 0, WANDERTIME, AFTER);
+    daemon(stomach, 0, AFTER);
+    daemon(runners, 0, AFTER);
+    if (player.t_ctype == C_THIEF)
+	daemon(trap_look, 0, AFTER);
+
+    /* Choose a quest item */
+    quest_item = rnd(MAXRELIC);
+    msg("You have been quested to retrieve the %s....",
+	rel_magic[quest_item].mi_name);
+    mpos = 0;
+    playit();
+}
+
+/*
+ * endit:
+ *	Exit the program abnormally.
+ */
+void
+endit(int sig)
+{
+    NOOP(sig);
+
+    fatal("Ok, if you want to exit that badly, I'll have to allow it\n");
+}
+
+/*
+ * fatal:
+ *	Exit the program, printing a message.
+ */
+
+fatal(s)
+char *s;
+{
+    clear();
+    move(LINES-2, 0);
+    printw("%s", s);
+    draw(stdscr);
+    endwin();
+    printf("\n");	/* So the cursor doesn't stop at the end of the line */
+    exit(0);
+}
+
+/*
+ * rnd:
+ *	Pick a very random number.
+ */
+
+rnd(range)
+register int range;
+{
+    return(range == 0 ? 0 : md_rand() % range);
+}
+
+/*
+ * roll:
+ *	roll a number of dice
+ */
+
+roll(number, sides)
+register int number, sides;
+{
+    register int dtotal = 0;
+
+    while(number--)
+	dtotal += rnd(sides)+1;
+    return dtotal;
+}
+# ifdef SIGTSTP
+/*
+ * handle stop and start signals
+ */
+void
+tstp(int a)
+{
+    mvcur(0, COLS - 1, LINES - 1, 0);
+    endwin();
+    fflush(stdout);
+    kill(0, SIGTSTP);
+    signal(SIGTSTP, tstp);
+    raw();
+    noecho();
+    keypad(cw,1);
+    clearok(curscr, TRUE);
+    touchwin(cw);
+    draw(cw);
+    md_flushinp();
+}
+# endif
+
+setup()
+{
+#ifdef CHECKTIME
+    int  checkout();
+#endif
+
+#ifndef DUMP
+#ifdef SIGHUP
+    signal(SIGHUP, auto_save);
+#endif
+    signal(SIGILL, bugkill);
+#ifdef SIGTRAP
+    signal(SIGTRAP, bugkill);
+#endif
+#ifdef SIGIOT
+    signal(SIGIOT, bugkill);
+#endif
+#if 0
+    signal(SIGEMT, bugkill);
+    signal(SIGFPE, bugkill);
+    signal(SIGBUS, bugkill);
+    signal(SIGSEGV, bugkill);
+    signal(SIGSYS, bugkill);
+    signal(SIGPIPE, bugkill);
+#endif
+    signal(SIGTERM, auto_save);
+#endif
+
+    signal(SIGINT, quit);
+#ifndef DUMP
+#ifdef SIGQUIT
+    signal(SIGQUIT, endit);
+#endif
+#endif
+#ifdef SIGTSTP
+    signal(SIGTSTP, tstp);
+#endif
+#ifdef CHECKTIME
+    if (!author())
+    {
+	signal(SIGALRM, checkout);
+	alarm(CHECKTIME * 60);
+	num_checks = 0;
+    }
+#endif
+    crmode();				/* Cbreak mode */
+    noecho();				/* Echo off */
+}
+
+/*
+ * playit:
+ *	The main loop of the program.  Loop until the game is over,
+ * refreshing things and looking at the proper times.
+ */
+
+playit()
+{
+    register char *opts;
+
+
+    /*
+     * parse environment declaration of options
+     */
+    if ((opts = getenv("ROGUEOPTS")) != NULL)
+	parse_opts(opts);
+
+
+    player.t_oldpos = hero;
+    oldrp = roomin(&hero);
+    after = TRUE;
+    while (playing)
+	command();			/* Command execution */
+    endit(0);
+}
+
+#if MAXLOAD|MAXUSERS
+/*
+ * see if the system is being used too much for this game
+ */
+too_much()
+{
+#ifdef MAXLOAD
+	double avec[3];
+#endif
+
+#ifdef MAXLOAD
+	loadav(avec);
+	return (avec[2] > (MAXLOAD / 10.0));
+#else
+	return (ucount() > MAXUSERS);
+#endif
+}
+#endif
+
+/*
+ * author:
+ *	See if a user is an author of the program
+ */
+author()
+{
+	switch (md_getuid()) {
+#if AUTHOR
+		case AUTHOR:
+#endif
+		case 0:
+			return TRUE;
+		default:
+			return FALSE;
+	}
+}
+
+
+#ifdef CHECKTIME
+checkout()
+{
+	static char *msgs[] = {
+	"The system is too loaded for games. Please leave in %d minutes",
+	"Please save your game.  You have %d minutes",
+	"This is your last chance. You had better leave in %d minutes",
+	};
+	int checktime;
+
+	signal(SIGALRM, checkout);
+	if (!holiday() && !author()) {
+	    wclear(cw);
+	    mvwaddstr(cw, LINES / 2, 0,
+		"Game time is over. Your game is being saved.\n\n");
+	    draw(cw);
+	    auto_save();		/* NO RETURN */
+	}
+	if (too_much())	{
+	    if (num_checks >= 3)
+		fatal("You didn't listen, so now you are DEAD !!\n");
+	    checktime = CHECKTIME / (num_checks + 1);
+		chmsg(msgs[num_checks++], checktime);
+		alarm(checktime * 60);
+	}
+	else {
+	    if (num_checks) {
+		chmsg("The load has dropped. You have a reprieve.");
+		num_checks = 0;
+	    }
+	    alarm(CHECKTIME * 60);
+	}
+}
+
+/*
+ * checkout()'s version of msg.  If we are in the middle of a shell, do a
+ * printf instead of a msg to avoid the refresh.
+ */
+chmsg(fmt, arg)
+char *fmt;
+int arg;
+{
+	if (in_shell) {
+		printf(fmt, arg);
+		putchar('\n');
+		fflush(stdout);
+	}
+	else
+		msg(fmt, arg);
+}
+#endif
+
+#ifdef LOADAV
+
+#include <nlist.h>
+
+struct nlist avenrun =
+{
+	"_avenrun"
+};
+
+loadav(avg)
+reg double *avg;
+{
+	reg int kmem;
+
+	if ((kmem = open("/dev/kmem", 0)) < 0)
+		goto bad;
+	nlist(NAMELIST, &avenrun);
+	if (avenrun.n_type == 0) {
+bad:
+		avg[0] = avg[1] = avg[2] = 0.0;
+		return;
+	}
+	lseek(kmem, (long) avenrun.n_value, 0);
+	read(kmem, avg, 3 * sizeof (double));
+}
+#endif
+
+#ifdef UCOUNT
+/*
+ * ucount:
+ *	Count the number of people on the system
+ */
+#include <sys/types.h>
+#include <utmp.h>
+struct utmp buf;
+ucount()
+{
+	reg struct utmp *up;
+	reg FILE *utmp;
+	reg int count;
+
+	if ((utmp = fopen(UTMP, "r")) == NULL)
+	    return 0;
+
+	up = &buf;
+	count = 0;
+	while (fread(up, 1, sizeof (*up), utmp) > 0)
+		if (buf.ut_type == USER_PROCESS)
+			count++;
+	fclose(utmp);
+	return count;
+}
+#endif
+
+/*
+ * holiday:
+ *	Returns TRUE when it is a good time to play rogue
+ */
+holiday()
+{
+	time_t now;
+	struct tm *localtime();
+	reg struct tm *ntime;
+
+	time(&now);			/* get the current time */
+	ntime = localtime(&now);
+	if(ntime->tm_wday == 0 || ntime->tm_wday == 6)
+		return TRUE;		/* OK on Sat & Sun */
+	if(ntime->tm_hour < 8 || ntime->tm_hour >= 17)
+		return TRUE;		/* OK before 8AM & after 5PM */
+	if(ntime->tm_yday <= 7 || ntime->tm_yday >= 350)
+		return TRUE;		/* OK during Christmas */
+#if 0 /* not for now */
+	if (access("/usr/tmp/.ryes",0) == 0)
+	    return TRUE;		/* if author permission */
+#endif
+
+	return FALSE;			/* All other times are bad */
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/maze.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,369 @@
+/*
+ * maze
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Super-Rogue"
+ * Copyright (C) 1984 Robert D. Kindelberger
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include <stdlib.h>
+#include "curses.h"
+#include "rogue.h"
+
+struct cell {
+	char y_pos;
+	char x_pos;
+};
+
+struct bordercells {
+	char num_pos;		/* number of frontier cells next to you */
+	struct cell conn[4];	/* the y,x position of above cell */
+} border_cells;
+
+static char	*frontier, 
+		*bits;
+static int	maze_lines, 
+		maze_cols;
+char		*moffset(), 
+		*foffset();
+
+
+/*
+ * crankout:
+ *	Does actual drawing of maze to window
+ */
+crankout()
+{
+	reg int x, y;
+
+	for (y = 0; y < LINES - 3; y++) {
+		move(y + 1, 0);
+		for (x = 0; x < COLS - 1; x++) {
+			if (*moffset(y, x)) {		/* here is a wall */
+				if(y==0 || y==LINES-4) /* top or bottom line */
+					addch('-');
+				else if(x==0 || x==COLS-2) /* left | right side */
+					addch('|');
+				else if (y % 2 == 0 && x % 2 == 0) {
+					if(*moffset(y, x-1) || *moffset(y, x+1))
+						addch('-');
+					else
+						addch('|');
+				}
+				else if (y % 2 == 0)
+					addch('-');
+				else
+					addch('|');
+			}
+			else
+				addch(FLOOR);
+		}
+	}
+}
+
+/*
+ * domaze:
+ *	Draw the maze on this level.
+ */
+do_maze()
+{
+	reg int least;
+	reg struct room *rp;
+	reg struct linked_list *item;
+	reg struct object *obj;
+	int cnt;
+	bool treas;
+	coord tp;
+
+	for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) {
+		rp->r_flags = ISGONE;		/* kill all rooms */
+		rp->r_fires = NULL;		/* no fires */
+	}
+	rp = &rooms[0];				/* point to only room */
+	rp->r_flags = ISDARK;			/* mazes always dark */
+	rp->r_pos.x = 0;			/* room fills whole screen */
+	rp->r_pos.y = 1;
+	rp->r_max.x = COLS - 1;
+	rp->r_max.y = LINES - 3;
+	draw_maze();				/* put maze into window */
+	/*
+	 * add some gold to make it worth looking for 
+	 */
+	item = spec_item(GOLD, NULL, NULL, NULL);
+	obj = OBJPTR(item);
+	obj->o_count *= (rnd(10) + 1);		/* add in one large hunk */
+	attach(lvl_obj, item);
+	cnt = 0;
+	do {
+	    rnd_pos(rp, &tp);
+	} until (mvinch(tp.y, tp.x) == FLOOR || cnt++ > 5000);
+	mvaddch(tp.y, tp.x, GOLD);
+	obj->o_pos = tp;
+	/*
+	 * add in some food to make sure he has enough
+	 */
+	item = spec_item(FOOD, NULL, NULL, NULL);
+	obj = OBJPTR(item);
+	attach(lvl_obj, item);
+	do {
+	    rnd_pos(rp, &tp);
+	} until (mvinch(tp.y, tp.x) == FLOOR || cnt++ > 5000);
+	mvaddch(tp.y, tp.x, FOOD);
+	obj->o_pos = tp;
+	if (rnd(100) < 10) {			/* 10% for treasure maze */
+		treas = TRUE;
+		least = 6;
+		debug("treasure maze");
+	}
+	else {					/* normal maze level */
+		least = 1;
+		treas = FALSE;
+	}
+	genmonsters(least, treas);
+}
+
+
+/*
+ * draw_maze:
+ *	Generate and draw the maze on the screen
+ */
+draw_maze()
+{
+	reg int i, j, more;
+	reg char *ptr;
+
+	maze_lines = (LINES - 3) / 2;
+	maze_cols = (COLS - 1) / 2;
+	bits = ALLOC((LINES - 3) * (COLS - 1));
+	frontier = ALLOC(maze_lines * maze_cols);
+	ptr = frontier;
+	while (ptr < (frontier + (maze_lines * maze_cols)))
+		*ptr++ = TRUE;
+	for (i = 0; i < LINES - 3; i++) {
+		for (j = 0; j < COLS - 1; j++) {
+			if (i % 2 == 1 && j % 2 == 1)
+				*moffset(i, j) = FALSE;		/* floor */
+			else
+				*moffset(i, j) = TRUE;		/* wall */
+		}
+	}
+	for (i = 0; i < maze_lines; i++) {
+		for (j = 0; j < maze_cols; j++) {
+			do
+				more = findcells(i,j);
+			while(more != 0);
+		}
+	}
+	crankout();
+	FREE(frontier);
+	FREE(bits);
+}
+
+/*
+ * findcells:
+ *	Figure out cells to open up 
+ */
+findcells(y,x)
+reg int x, y;
+{
+	reg int rtpos, i;
+
+	*foffset(y, x) = FALSE;
+	border_cells.num_pos = 0;
+	if (y < maze_lines - 1) {				/* look below */
+		if (*foffset(y + 1, x)) {
+			border_cells.conn[border_cells.num_pos].y_pos = y + 1;
+			border_cells.conn[border_cells.num_pos].x_pos = x;
+			border_cells.num_pos += 1;
+		}
+	}
+	if (y > 0) {					/* look above */
+		if (*foffset(y - 1, x)) {
+			border_cells.conn[border_cells.num_pos].y_pos = y - 1;
+			border_cells.conn[border_cells.num_pos].x_pos = x;
+			border_cells.num_pos += 1;
+
+		}
+	}
+	if (x < maze_cols - 1) {				/* look right */
+		if (*foffset(y, x + 1)) {
+			border_cells.conn[border_cells.num_pos].y_pos = y;
+			border_cells.conn[border_cells.num_pos].x_pos = x + 1;
+			border_cells.num_pos += 1;
+		}
+	}
+	if (x > 0) {					/* look left */
+		if (*foffset(y, x - 1)) {
+			border_cells.conn[border_cells.num_pos].y_pos = y;
+			border_cells.conn[border_cells.num_pos].x_pos = x - 1;
+			border_cells.num_pos += 1;
+
+		}
+	}
+	if (border_cells.num_pos == 0)		/* no neighbors available */
+		return 0;
+	else {
+		i = rnd(border_cells.num_pos);
+		rtpos = border_cells.num_pos - 1;
+		rmwall(border_cells.conn[i].y_pos, border_cells.conn[i].x_pos, y, x);
+		return rtpos;
+	}
+}
+
+/*
+ * foffset:
+ *	Calculate memory address for frontier
+ */
+char *
+foffset(y, x)
+int y, x;
+{
+
+	return (frontier + (y * maze_cols) + x);
+}
+
+
+/*
+ * Maze_view:
+ *	Returns true if the player can see the specified location within
+ *	the confines of a maze (within one column or row)
+ */
+
+bool
+maze_view(y, x)
+int y, x;
+{
+    register int start, goal, delta, ycheck = 0, xcheck = 0, absy, absx, see_radius;
+    register bool row;
+    char ch;	/* What we are standing on (or near) */
+
+    /* Get the absolute value of y and x differences */
+    absy = hero.y - y;
+    absx = hero.x - x;
+    if (absy < 0) absy = -absy;
+    if (absx < 0) absx = -absx;
+
+    /* If we are standing in a wall, we can see a bit more */
+    switch (ch = CCHAR( winat(hero.y, hero.x) )) {
+	case '|':
+	case '-':
+	case WALL:
+	case SECRETDOOR:
+	case DOOR:
+	    see_radius = 2;
+	otherwise:
+	    see_radius = 1;
+    }
+
+    /* Must be within one or two rows or columns */
+    if (absy > see_radius && absx > see_radius) return(FALSE);
+
+    if (absx > see_radius) {		/* Go along row */
+	start = hero.x;
+	goal = x;
+	ycheck = hero.y;
+	row = TRUE;
+    }
+    else {			/* Go along column */
+	start = hero.y;
+	goal = y;
+	xcheck = hero.x;
+	row = FALSE;
+    }
+
+    if (start <= goal) delta = 1;
+    else delta = -1;
+
+    /* Start one past where we are standing */
+    if (start != goal) start += delta;
+
+    /* If we are in a wall, we want to look in the area outside the wall */
+    if (see_radius > 1) {
+	if (row) {
+	    /* See if above us it okay first */
+	    switch (winat(ycheck, start)) {
+		case '|':
+		case '-':
+		case WALL:
+		case DOOR:
+		case SECRETDOOR:
+		    /* No good, try one up */
+		    if (y > hero.y) ycheck++;
+		    else ycheck--;
+		otherwise:
+		    see_radius = 1;	/* Just look straight over the row */
+	    }
+	}
+	else {
+	    /* See if above us it okay first */
+	    switch (winat(start, xcheck)) {
+		case '|':
+		case '-':
+		case WALL:
+		case DOOR:
+		case SECRETDOOR:
+		    /* No good, try one over */
+		    if (x > hero.x) xcheck++;
+		    else xcheck--;
+		otherwise:
+		    see_radius = 1;	/* Just look straight up the column */
+	    }
+	}
+    }
+
+    /* Check boundary again */
+    if (absy > see_radius && absx > see_radius) return(FALSE);
+
+    while (start != goal) {
+	if (row) xcheck = start;
+	else ycheck = start;
+	switch (winat(ycheck, xcheck)) {
+	    case '|':
+	    case '-':
+	    case WALL:
+	    case DOOR:
+	    case SECRETDOOR:
+		return(FALSE);
+	}
+	start += delta;
+    }
+    return(TRUE);
+}
+
+
+/*
+ * moffset:
+ *	Calculate memory address for bits
+ */
+char *
+moffset(y, x)
+int y, x;
+{
+
+	return (bits + (y * (COLS - 1)) + x);
+}
+
+
+
+
+/*
+ * rmwall:
+ *	Removes appropriate walls from the maze
+ */
+rmwall(newy, newx, oldy, oldx)
+int newy, newx, oldy, oldx;
+{
+	reg int xdif,ydif;
+	
+	xdif = newx - oldx;
+	ydif = newy - oldy;
+
+	*moffset((oldy * 2) + ydif + 1, (oldx * 2) + xdif + 1) = FALSE;
+	findcells(newy, newx);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/mdport.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,1194 @@
+/*
+    mdport.c - Machine Dependent Code for Porting Unix/Curses games
+
+    Copyright (C) 2005 Nicholas J. Kisseberth
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name(s) of the author(s) nor the names of other contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+*/
+
+#if defined(_WIN32)
+#include <Windows.h>
+#include <Lmcons.h>
+#include <process.h>
+#include <shlobj.h>
+#include <sys/types.h>
+#undef MOUSE_MOVED
+#elif defined(__DJGPP__)
+#include <process.h>
+#else
+#include <pwd.h>
+#include <sys/utsname.h>
+#include <unistd.h>
+#endif
+
+#include <stdlib.h>
+
+#if defined(_WIN32) && !defined(__MINGW32__)
+#define PATH_MAX MAX_PATH
+#endif
+
+#include <curses.h>
+
+#if defined(__INTERIX) || defined(__MSYS__)
+#include <term.h>
+#else
+#ifdef NCURSES_VERSION
+#include <ncurses/term.h>
+#endif
+#endif
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <signal.h>
+
+#define MOD_MOVE(c) (toupper(c) )
+
+void
+md_init()
+{
+#ifdef __INTERIX
+    char *term;
+
+    term = getenv("TERM");
+
+    if (term == NULL)
+        setenv("TERM","interix");
+#endif
+#if defined(__DJGPP__) || defined(_WIN32)
+    _fmode = _O_BINARY;
+#endif
+#if defined(__CYGWIN__) || defined(__MSYS__)
+    ESCDELAY=250;
+#endif
+}
+
+int
+md_hasclreol()
+{
+#ifndef	attron
+    return(!CE);
+#elif !defined(__PDCURSES__)
+    return(clr_eol != NULL);
+#else
+    return(TRUE);
+#endif
+}
+
+#ifdef	attron
+# define	_puts(s)	tputs(s, 0, md_putchar);
+# define	SO		enter_standout_mode
+# define	SE		exit_standout_mode
+#endif
+
+int
+md_putchar(int c)
+{
+    putchar(c);
+}
+
+static int md_standout_mode = 0;
+
+int
+md_raw_standout()
+{
+#ifdef _WIN32
+    CONSOLE_SCREEN_BUFFER_INFO csbiInfo; 
+    HANDLE hStdout;
+    int fgattr,bgattr;
+
+    if (md_standout_mode == 0)
+    {
+        hStdout = GetStdHandle(STD_OUTPUT_HANDLE); 
+        GetConsoleScreenBufferInfo(hStdout, &csbiInfo);
+        fgattr = (csbiInfo.wAttributes & 0xF);
+        bgattr = (csbiInfo.wAttributes & 0xF0);
+        SetConsoleTextAttribute(hStdout,(fgattr << 4) | (bgattr >> 4));
+        md_standout_mode = 1;
+    }
+#elif !defined(__PDCURSES__)
+    _puts(SO);
+    fflush(stdout);
+#endif
+}
+
+int
+md_raw_standend()
+{
+#ifdef _WIN32
+    CONSOLE_SCREEN_BUFFER_INFO csbiInfo; 
+    HANDLE hStdout;
+    int fgattr,bgattr;
+
+    if (md_standout_mode == 1)
+    {
+        hStdout = GetStdHandle(STD_OUTPUT_HANDLE); 
+        GetConsoleScreenBufferInfo(hStdout, &csbiInfo);
+        fgattr = (csbiInfo.wAttributes & 0xF);
+        bgattr = (csbiInfo.wAttributes & 0xF0);
+        SetConsoleTextAttribute(hStdout,(fgattr << 4) | (bgattr >> 4));
+        md_standout_mode = 0;
+    }
+#elif !defined(__PDCURSES__)
+    _puts(SE);
+    fflush(stdout);
+#endif
+}
+
+int
+md_unlink_open_file(char *file, int inf)
+{
+#ifdef _WIN32
+    close(inf);
+    chmod(file, 0600);
+    return( _unlink(file) );
+#else
+    return(unlink(file));
+#endif
+}
+
+int
+md_unlink(char *file)
+{
+#ifdef _WIN32
+    chmod(file, 0600);
+    return( _unlink(file) );
+#else
+    return(unlink(file));
+#endif
+}
+
+int
+md_creat(char *file, int mode)
+{
+    int fd;
+#ifdef _WIN32
+    mode = _S_IREAD | _S_IWRITE;
+#endif
+    fd = open(file,O_CREAT | O_EXCL | O_WRONLY, mode);
+
+    return(fd);
+}
+
+
+int
+md_normaluser()
+{
+#ifndef _WIN32
+    setuid(getuid());
+    setgid(getgid());
+#endif
+}
+
+int
+md_getuid()
+{
+#ifndef _WIN32
+    return( getuid() );
+#else
+    return(42);
+#endif
+}
+
+char *
+md_getusername()
+{
+    static char login[80];
+    char *l = NULL;
+#ifdef _WIN32
+    LPSTR mybuffer;
+    DWORD size = UNLEN + 1;
+    TCHAR buffer[UNLEN + 1];
+
+    mybuffer = buffer;
+    GetUserName(mybuffer,&size);
+    l = mybuffer;
+#endif
+#if !defined(_WIN32) && !defined(DJGPP)
+    struct passwd *pw;
+
+    pw = getpwuid(getuid());
+
+    l = pw->pw_name;
+#endif
+
+    if ((l == NULL) || (*l == '\0'))
+        if ( (l = getenv("USERNAME")) == NULL )
+            if ( (l = getenv("LOGNAME")) == NULL )
+                if ( (l = getenv("USER")) == NULL )
+                    l = "nobody";
+
+    strncpy(login,l,80);
+    login[79] = 0;
+
+    return(login);
+}
+
+char *
+md_gethomedir()
+{
+    static char homedir[PATH_MAX];
+    char *h = NULL;
+    size_t len;
+#if defined(_WIN32)
+    TCHAR szPath[PATH_MAX];
+#endif
+#if defined(_WIN32) || defined(DJGPP)
+        char slash = '\\';
+#else
+    char slash = '/';
+    struct passwd *pw;
+    pw = getpwuid(getuid());
+
+    h = pw->pw_dir;
+
+    if (strcmp(h,"/") == 0)
+        h = NULL;
+#endif
+    homedir[0] = 0;
+#ifdef _WIN32
+    if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, szPath)))
+        h = szPath;
+#endif
+
+    if ( (h == NULL) || (*h == '\0') )
+        if ( (h = getenv("HOME")) == NULL )
+            if ( (h = getenv("HOMEDRIVE")) == NULL)
+                h = "";
+            else
+            {
+                strncpy(homedir,h,PATH_MAX-1);
+                homedir[PATH_MAX-1] = 0;
+
+                if ( (h = getenv("HOMEPATH")) == NULL)
+                    h = "";
+            }
+
+
+    len = strlen(homedir);
+    strncat(homedir,h,PATH_MAX-len-1);
+    len = strlen(homedir);
+
+    if ((len > 0) && (homedir[len-1] != slash)) {
+        homedir[len] = slash;
+        homedir[len+1] = 0;
+    }
+
+    return(homedir);
+}
+
+int
+md_sleep(int s)
+{
+#ifdef _WIN32
+    _sleep(s);
+#else
+    sleep(s);
+#endif
+}
+
+char *
+md_getshell()
+{
+    static char shell[PATH_MAX];
+    char *s = NULL;
+#ifdef _WIN32
+    char *def = "C:\\WINDOWS\\SYSTEM32\\CMD.EXE";
+#elif defined(__DJGPP__)
+    char *def = "C:\\COMMAND.COM";
+#else
+    char *def = "/bin/sh";
+    struct passwd *pw;
+    pw = getpwuid(getuid());
+    s = pw->pw_shell;
+#endif
+    if ((s == NULL) || (*s == '\0'))
+        if ( (s = getenv("COMSPEC")) == NULL)
+            if ( (s = getenv("SHELL")) == NULL)
+                if ( (s = getenv("SystemRoot")) == NULL)
+                    s = def;
+
+    strncpy(shell,s,PATH_MAX);
+    shell[PATH_MAX-1] = 0;
+
+    return(shell);
+}
+
+int
+md_shellescape()
+{
+#if (!defined(_WIN32) && !defined(__DJGPP__))
+    int ret_status;
+    int pid;
+    void (*myquit)(int);
+    void (*myend)(int);
+#endif
+    char *sh;
+
+    sh = md_getshell();
+
+#if defined(_WIN32)
+    return((int)_spawnl(_P_WAIT,sh,"shell",NULL,0));
+#elif defined(__DJGPP__)
+    return ( spawnl(P_WAIT,sh,"shell",NULL,0) );
+#else
+    while((pid = fork()) < 0)
+        sleep(1);
+
+    if (pid == 0) /* Shell Process */
+    {
+        /*
+         * Set back to original user, just in case
+         */
+        setuid(getuid());
+        setgid(getgid());
+        execl(sh == NULL ? "/bin/sh" : sh, "shell", "-i", 0);
+        perror("No shelly");
+        _exit(-1);
+    }
+    else /* Application */
+    {
+	myend = signal(SIGINT, SIG_IGN);
+#ifdef SIGQUIT
+        myquit = signal(SIGQUIT, SIG_IGN);
+#endif  
+        while (wait(&ret_status) != pid)
+            continue;
+	    
+        signal(SIGINT, myquit);
+#ifdef SIGQUIT
+        signal(SIGQUIT, myend);
+#endif
+    }
+
+    return(ret_status);
+#endif
+}
+
+int
+directory_exists(char *dirname)
+{
+    struct stat sb;
+
+    if (stat(dirname, &sb) == 0) /* path exists */
+        return (sb.st_mode & S_IFDIR);
+
+    return(0);
+}
+
+char *
+md_getroguedir()
+{
+    static char path[1024];
+    char *end,*home;
+
+    if ( (home = getenv("ROGUEHOME")) != NULL)
+    {
+        if (*home)
+        {
+            strncpy(path, home, PATH_MAX - 20);
+
+            end = &path[strlen(path)-1];
+
+            while( (end >= path) && ((*end == '/') || (*end == '\\')))
+                *end-- = '\0';
+
+            if (directory_exists(path))
+                return(path);
+        }
+    }
+
+    if (directory_exists("/var/games/roguelike"))
+        return("/var/games/roguelike");
+    if (directory_exists("/var/lib/roguelike"))
+        return("/var/lib/roguelike");
+    if (directory_exists("/var/roguelike"))
+        return("/var/roguelike");
+    if (directory_exists("/usr/games/lib"))
+        return("/usr/games/lib");
+    if (directory_exists("/games/roguelik"))
+        return("/games/roguelik");
+
+    return("");
+}
+
+char *
+md_getrealname(int uid)
+{
+    static char uidstr[20];
+#if !defined(_WIN32) && !defined(DJGPP)
+    struct passwd *pp;
+
+	if ((pp = getpwuid(uid)) == NULL)
+    {
+        sprintf(uidstr,"%d", uid);
+        return(uidstr);
+    }
+	else
+	    return(pp->pw_name);
+#else
+   sprintf(uidstr,"%d", uid);
+   return(uidstr);
+#endif
+}
+
+extern char *xcrypt(char *key, char *salt);
+
+char *
+md_crypt(char *key, char *salt)
+{
+    return( xcrypt(key,salt) );
+}
+
+char *
+md_getpass(prompt)
+char *prompt;
+{
+#ifdef _WIN32
+    static char password_buffer[9];
+    char *p = password_buffer;
+    int c, count = 0;
+    int max_length = 9;
+
+    fflush(stdout);
+    /* If we can't prompt, abort */
+    if (fputs(prompt, stderr) < 0)
+    {
+        *p = '\0';
+        return NULL;
+    }
+
+    for(;;)
+    {
+        /* Get a character with no echo */
+        c = _getch();
+
+        /* Exit on interrupt (^c or ^break) */
+        if (c == '\003' || c == 0x100)
+            exit(1);
+
+        /* Terminate on end of line or file (^j, ^m, ^d, ^z) */
+        if (c == '\r' || c == '\n' || c == '\004' || c == '\032')
+            break;
+
+        /* Back up on backspace */
+        if (c == '\b')
+        {
+            if (count)
+                count--;
+            else if (p > password_buffer)
+                p--;
+            continue;
+        }
+
+        /* Ignore DOS extended characters */
+        if ((c & 0xff) != c)
+            continue;
+
+        /* Add to password if it isn't full */
+        if (p < password_buffer + max_length - 1)
+            *p++ = c;
+        else
+            count++;
+    }
+   *p = '\0';
+
+   fputc('\n', stderr);
+
+   return password_buffer;
+#else
+   return( (char *) getpass(prompt) );
+#endif
+}
+
+
+int md_endian = 0x01020304;
+
+unsigned long int
+md_ntohl(unsigned long int x)
+{
+#ifdef _WIN32
+    if ( *((char *)&md_endian) == 0x01 )
+        return(x);
+    else
+        return( ((x & 0x000000ffU) << 24) |
+                ((x & 0x0000ff00U) <<  8) |
+                ((x & 0x00ff0000U) >>  8) |
+                ((x & 0xff000000U) >> 24) );
+#else
+    return( ntohl(x) );
+#endif
+}
+
+unsigned long int
+md_htonl(unsigned long int x)
+{
+#ifdef _WIN32
+    if ( *((char *)&md_endian) == 0x01 )
+        return(x);
+    else
+        return( ((x & 0x000000ffU) << 24) |
+                ((x & 0x0000ff00U) <<  8) |
+                ((x & 0x00ff0000U) >>  8) |
+                ((x & 0xff000000U) >> 24) );
+#else
+    return( htonl(x) );
+#endif
+}
+
+int
+md_rand()
+{
+#ifdef _WIN32
+    return(rand());
+#else
+    return(lrand48() & 0x7fffffff);
+#endif
+}
+
+int
+md_srand(seed)
+register int seed;
+{
+#ifdef _WIN32
+    srand(seed);
+#else
+    srand48(seed);
+#endif
+}
+
+long
+md_memused()
+{
+#ifdef _WIN32
+    MEMORYSTATUS stat;
+
+    GlobalMemoryStatus(&stat);
+
+    return((long)stat.dwTotalPageFile);
+#else
+    return( (long)sbrk(0) );
+#endif
+}
+
+char *
+md_gethostname()
+{
+    static char nodename[80];
+    char *n = NULL;
+#if !defined(_WIN32) && !defined(__DJGPP__)
+    struct utsname ourname;
+
+    if (uname(&ourname) == 0)
+        n = ourname.nodename;
+#endif
+    if ((n == NULL) || (*n == '\0'))
+        if ( (n = getenv("COMPUTERNAME")) == NULL)
+            if ( (n = getenv("HOSTNAME")) == NULL)
+                n = "localhost";
+
+    strncpy(nodename, n, 80);
+    nodename[79] = 0;
+
+    return(nodename);
+}
+
+int
+md_erasechar()
+{
+#ifdef BSD
+    return(_tty.sg_erase); /* process erase character */
+#elif defined(USG5_0)
+    return(_tty.c_cc[VERASE]); /* process erase character */
+#else /* USG5_2 .... curses */
+    return( erasechar() ); /* process erase character */
+#endif
+}
+
+int
+md_killchar()
+{
+#ifdef BSD
+    return(_tty.sg_kill);
+#elif defined(USG5_0)
+    return(_tty.c_cc[VKILL]);
+#else /* USG5_2 ..... curses */
+    return( killchar() );
+#endif
+}
+
+/*
+ * unctrl:
+ *	Print a readable version of a certain character
+ */
+
+char *
+md_unctrl(ch)
+char ch;
+{
+#if USG5_0
+    extern char *_unctrl[];		/* Defined in curses library */
+
+    return _unctrl[ch&0177];
+#else
+    return( unctrl(ch) );
+#endif
+}
+
+void
+md_flushinp()
+{
+#ifdef BSD
+    ioctl(0, TIOCFLUSH);
+#elif defined(USG5_0)
+    ioctl(_tty_ch,TCFLSH,0)
+#else /* USG5_2.... curses */
+    flushinp();
+#endif
+}
+
+/*
+    Cursor/Keypad Support
+
+    Sadly Cursor/Keypad support is less straightforward than it should be.
+
+    The various terminal emulators/consoles choose to differentiate the
+    cursor and keypad keys (with modifiers) in different ways (if at all!).
+    Furthermore they use different code set sequences for each key only
+    a subset of which the various curses libraries recognize. Partly due
+    to incomplete termcap/terminfo entries and partly due to inherent
+    limitations of those terminal capability databases.
+
+    I give curses first crack at decoding the sequences. If it fails to decode
+    it we check for common ESC-prefixed sequences.
+
+    All cursor/keypad results are translated into standard rogue movement
+    commands.
+
+    Unmodified keys are translated to walk commands: hjklyubn
+    Modified (shift,control,alt) are translated to run commands: HJKLYUBN
+
+    Console and supported (differentiated) keys
+    Interix:  Cursor Keys, Keypad, Ctl-Keypad
+    Cygwin:   Cursor Keys, Keypad, Alt-Cursor Keys
+    MSYS:     Cursor Keys, Keypad, Ctl-Cursor Keys, Ctl-Keypad
+    Win32:    Cursor Keys, Keypad, Ctl/Shift/Alt-Cursor Keys, Ctl/Alt-Keypad
+    DJGPP:    Cursor Keys, Keypad, Ctl/Shift/Alt-Cursor Keys, Ctl/Alt-Keypad
+
+    Interix Console (raw, ncurses)
+    ==============================
+    normal      shift           ctrl        alt
+    ESC [D,     ESC F^,         ESC [D,     ESC [D          /# Left         #/
+    ESC [C,     ESC F$,         ESC [C,     ESC [C          /# Right        #/
+    ESC [A,     ESC F-,         local win,  ESC [A          /# Up           #/
+    ESC [B,     ESC F+,         local win,  ESC [B          /# Down         #/
+    ESC [H,     ESC [H,         ESC [H,     ESC [H          /# Home         #/
+    ESC [S,     local win,      ESC [S,     ESC [S          /# Page Up      #/
+    ESC [T,     local win,      ESC [T,     ESC [T          /# Page Down    #/
+    ESC [U,     ESC [U,         ESC [U,     ESC [U          /# End          #/
+    ESC [D,     ESC F^,         ESC [D,     O               /# Keypad Left  #/
+    ESC [C,     ESC F$,         ESC [C,     O               /# Keypad Right #/
+    ESC [A,     ESC [A,         ESC [-1,    O               /# Keypad Up    #/
+    ESC [B,     ESC [B,         ESC [-2,    O               /# Keypad Down  #/
+    ESC [H,     ESC [H,         ESC [-263,  O               /# Keypad Home  #/
+    ESC [S,     ESC [S,         ESC [-19,   O               /# Keypad PgUp  #/
+    ESC [T,     ESC [T,         ESC [-20,   O               /# Keypad PgDn  #/
+    ESC [U,     ESC [U,         ESC [-21,   O               /# Keypad End   #/
+    nothing,    nothing,        nothing,    O               /# Kaypad 5     #/
+
+    Interix Console (term=interix, ncurses)
+    ==============================
+    KEY_LEFT,   ESC F^,         KEY_LEFT,   KEY_LEFT        /# Left         #/
+    KEY_RIGHT,  ESC F$,         KEY_RIGHT,  KEY_RIGHT       /# Right        #/
+    KEY_UP,     0x146,          local win,  KEY_UP          /# Up           #/
+    KEY_DOWN,   0x145,          local win,  KEY_DOWN        /# Down         #/
+    ESC [H,     ESC [H,         ESC [H,     ESC [H          /# Home         #/
+    KEY_PPAGE,  local win,      KEY_PPAGE,  KEY_PPAGE       /# Page Up      #/
+    KEY_NPAGE,  local win,      KEY_NPAGE,  KEY_NPAGE       /# Page Down    #/
+    KEY_LL,     KEY_LL,         KEY_LL,     KEY_LL          /# End          #/
+    KEY_LEFT,   ESC F^,         ESC [-4,    O               /# Keypad Left  #/
+    KEY_RIGHT,  ESC F$,         ESC [-3,    O               /# Keypad Right #/
+    KEY_UP,     KEY_UP,         ESC [-1,    O               /# Keypad Up    #/
+    KEY_DOWN,   KEY_DOWN,       ESC [-2,    O               /# Keypad Down  #/
+    ESC [H,     ESC [H,         ESC [-263,  O               /# Keypad Home  #/
+    KEY_PPAGE,  KEY_PPAGE,      ESC [-19,   O               /# Keypad PgUp  #/
+    KEY_NPAGE,  KEY_NPAGE,      ESC [-20,   O               /# Keypad PgDn  #/
+    KEY_LL,     KEY_LL,         ESC [-21,   O               /# Keypad End   #/
+    nothing,    nothing,        nothing,    O               /# Keypad 5     #/
+
+    Cygwin Console (raw, ncurses)
+    ==============================
+    normal      shift           ctrl        alt
+    ESC [D,     ESC [D,         ESC [D,     ESC ESC [D      /# Left         #/
+    ESC [C,     ESC [C,         ESC [C,     ESC ESC [C      /# Rght         #/
+    ESC [A,     ESC [A,         ESC [A,     ESC ESC [A      /# Up           #/
+    ESC [B,     ESC [B,         ESC [B,     ESC ESC [B      /# Down         #/
+    ESC [1~,    ESC [1~,        ESC [1~,    ESC ESC [1~     /# Home         #/
+    ESC [5~,    ESC [5~,        ESC [5~,    ESC ESC [5~     /# Page Up      #/
+    ESC [6~,    ESC [6~,        ESC [6~,    ESC ESC [6~     /# Page Down    #/
+    ESC [4~,    ESC [4~,        ESC [4~,    ESC ESC [4~     /# End          #/
+    ESC [D,     ESC [D,         ESC [D,     ESC ESC [D,O    /# Keypad Left  #/
+    ESC [C,     ESC [C,         ESC [C,     ESC ESC [C,O    /# Keypad Right #/
+    ESC [A,     ESC [A,         ESC [A,     ESC ESC [A,O    /# Keypad Up    #/
+    ESC [B,     ESC [B,         ESC [B,     ESC ESC [B,O    /# Keypad Down  #/
+    ESC [1~,    ESC [1~,        ESC [1~,    ESC ESC [1~,O   /# Keypad Home  #/
+    ESC [5~,    ESC [5~,        ESC [5~,    ESC ESC [5~,O   /# Keypad PgUp  #/
+    ESC [6~,    ESC [6~,        ESC [6~,    ESC ESC [6~,O   /# Keypad PgDn  #/
+    ESC [4~,    ESC [4~,        ESC [4~,    ESC ESC [4~,O   /# Keypad End   #/
+    ESC [-71,   nothing,        nothing,    O               /# Keypad 5     #/
+
+    Cygwin Console (term=cygwin, ncurses)
+    ==============================
+    KEY_LEFT,   KEY_LEFT,       KEY_LEFT,   ESC-260         /# Left         #/
+    KEY_RIGHT,  KEY_RIGHT,      KEY_RIGHT,  ESC-261         /# Rght         #/
+    KEY_UP,     KEY_UP,         KEY_UP,     ESC-259         /# Up           #/
+    KEY_DOWN,   KEY_DOWN,       KEY_DOWN,   ESC-258         /# Down         #/
+    KEY_HOME,   KEY_HOME,       KEY_HOME,   ESC-262         /# Home         #/
+    KEY_PPAGE,  KEY_PPAGE,      KEY_PPAGE,  ESC-339         /# Page Up      #/
+    KEY_NPAGE,  KEY_NPAGE,      KEY_NPAGE,  ESC-338         /# Page Down    #/
+    KEY_END,    KEY_END,        KEY_END,    ESC-360         /# End          #/
+    KEY_LEFT,   KEY_LEFT,       KEY_LEFT,   ESC-260,O       /# Keypad Left  #/
+    KEY_RIGHT,  KEY_RIGHT,      KEY_RIGHT,  ESC-261,O       /# Keypad Right #/
+    KEY_UP,     KEY_UP,         KEY_UP,     ESC-259,O       /# Keypad Up    #/
+    KEY_DOWN,   KEY_DOWN,       KEY_DOWN,   ESC-258,O       /# Keypad Down  #/
+    KEY_HOME,   KEY_HOME,       KEY_HOME,   ESC-262,O       /# Keypad Home  #/
+    KEY_PPAGE,  KEY_PPAGE,      KEY_PPAGE,  ESC-339,O       /# Keypad PgUp  #/
+    KEY_NPAGE,  KEY_NPAGE,      KEY_NPAGE,  ESC-338,O       /# Keypad PgDn  #/
+    KEY_END,    KEY_END,        KEY_END,    ESC-360,O       /# Keypad End   #/
+    ESC [G,     nothing,        nothing,    O               /# Keypad 5     #/
+
+    MSYS Console (raw, ncurses)
+    ==============================
+    normal      shift           ctrl        alt
+    ESC OD,     ESC [d,         ESC Od      nothing         /# Left         #/
+    ESC OE,     ESC [e,         ESC Oe,     nothing         /# Right        #/
+    ESC OA,     ESC [a,         ESC Oa,     nothing         /# Up           #/
+    ESC OB,     ESC [b,         ESC Ob,     nothing         /# Down         #/
+    ESC [7~,    ESC [7$,        ESC [7^,    nothing         /# Home         #/
+    ESC [5~,    local window,   ESC [5^,    nothing         /# Page Up      #/
+    ESC [6~,    local window,   ESC [6^,    nothing         /# Page Down    #/
+    ESC [8~,    ESC [8$,        ESC [8^,    nothing         /# End          #/
+    ESC OD,     ESC [d,         ESC Od      O               /# Keypad Left  #/
+    ESC OE,     ESC [c,         ESC Oc,     O               /# Keypad Right #/
+    ESC OA,     ESC [a,         ESC Oa,     O               /# Keypad Up    #/
+    ESC OB,     ESC [b,         ESC Ob,     O               /# Keypad Down  #/
+    ESC [7~,    ESC [7$,        ESC [7^,    O               /# Keypad Home  #/
+    ESC [5~,    local window,   ESC [5^,    O               /# Keypad PgUp  #/
+    ESC [6~,    local window,   ESC [6^,    O               /# Keypad PgDn  #/
+    ESC [8~,    ESC [8$,        ESC [8^,    O               /# Keypad End   #/
+    11,         11,             11,         O               /# Keypad 5     #/
+
+    MSYS Console (term=rxvt, ncurses)
+    ==============================
+    normal      shift           ctrl        alt
+    KEY_LEFT,   KEY_SLEFT,      514         nothing         /# Left         #/
+    KEY_RIGHT,  KEY_SRIGHT,     516,        nothing         /# Right        #/
+    KEY_UP,     518,            519,        nothing         /# Up           #/
+    KEY_DOWN,   511,            512,        nothing         /# Down         #/
+    KEY_HOME,   KEY_SHOME,      ESC [7^,    nothing         /# Home         #/
+    KEY_PPAGE,  local window,   ESC [5^,    nothing         /# Page Up      #/
+    KEY_NPAGE,  local window,   ESC [6^,    nothing         /# Page Down    #/
+    KEY_END,    KEY_SEND,       KEY_EOL,    nothing         /# End          #/
+    KEY_LEFT,   KEY_SLEFT,      514         O               /# Keypad Left  #/
+    KEY_RIGHT,  KEY_SRIGHT,     516,        O               /# Keypad Right #/
+    KEY_UP,     518,            519,        O               /# Keypad Up    #/
+    KEY_DOWN,   511,            512,        O               /# Keypad Down  #/
+    KEY_HOME,   KEY_SHOME,      ESC [7^,    O               /# Keypad Home  #/
+    KEY_PPAGE,  local window,   ESC [5^,    O               /# Keypad PgUp  #/
+    KEY_NPAGE,  local window,   ESC [6^,    O               /# Keypad PgDn  #/
+    KEY_END,    KEY_SEND,       KEY_EOL,    O               /# Keypad End   #/
+    11,         11,             11,         O               /# Keypad 5     #/
+
+    Win32 Console (raw, pdcurses)
+   DJGPP Console (raw, pdcurses)
+   ==============================
+   normal      shift           ctrl        alt
+   260,        391,            443,        493             /# Left         #/
+   261,        400,            444,        492             /# Right        #/
+   259,        547,            480,        490             /# Up           #/
+   258,        548,            481,        491             /# Down         #/
+   262,        388,            447,        524             /# Home         #/
+   339,        396,            445,        526             /# Page Up      #/
+   338,        394,            446,        520             /# Page Down    #/
+   358,        384,            448,        518             /# End          #/
+   452,        52('4'),        511,        521             /# Keypad Left  #/
+   454,        54('6'),        513,        523             /# Keypad Right #/
+   450,        56('8'),        515,        525             /# Keypad Up    #/
+   456,        50('2'),        509,        519             /# Keypad Down  #/
+   449,        55('7'),        514,        524             /# Keypad Home  #/
+   451,        57('9'),        516,        526             /# Keypad PgUp  #/
+   457,        51('3'),        510,        520             /# Keypad PgDn  #/
+   455,        49('1'),        508,        518             /# Keypad End   #/
+   453,        53('5'),        512,        522             /# Keypad 5     #/
+
+   Win32 Console (pdcurses, MSVC/MingW32)
+   DJGPP Console (pdcurses)
+   ==============================
+   normal      shift           ctrl        alt
+   KEY_LEFT,   KEY_SLEFT,      CTL_LEFT,   ALT_LEFT        /# Left         #/
+   KEY_RIGHT,  KEY_SRIGHT,     CTL_RIGHT,  ALT_RIGHT       /# Right        #/
+   KEY_UP,     KEY_SUP,        CTL_UP,     ALT_UP          /# Up           #/
+   KEY_DOWN,   KEY_SDOWN,      CTL_DOWN,   ALT_DOWN        /# Down         #/
+   KEY_HOME,   KEY_SHOME,      CTL_HOME,   ALT_HOME        /# Home         #/
+   KEY_PPAGE,  KEY_SPREVIOUS,  CTL_PGUP,   ALT_PGUP        /# Page Up      #/
+   KEY_NPAGE,  KEY_SNEXTE,     CTL_PGDN,   ALT_PGDN        /# Page Down    #/
+   KEY_END,    KEY_SEND,       CTL_END,    ALT_END         /# End          #/
+   KEY_B1,     52('4'),        CTL_PAD4,   ALT_PAD4        /# Keypad Left  #/
+   KEY_B3,     54('6'),        CTL_PAD6,   ALT_PAD6        /# Keypad Right #/
+   KEY_A2,     56('8'),        CTL_PAD8,   ALT_PAD8        /# Keypad Up    #/
+   KEY_C2,     50('2'),        CTL_PAD2,   ALT_PAD2        /# Keypad Down  #/
+   KEY_A1,     55('7'),        CTL_PAD7,   ALT_PAD7        /# Keypad Home  #/
+   KEY_A3,     57('9'),        CTL_PAD9,   ALT_PAD9        /# Keypad PgUp  #/
+   KEY_C3,     51('3'),        CTL_PAD3,   ALT_PAD3        /# Keypad PgDn  #/
+   KEY_C1,     49('1'),        CTL_PAD1,   ALT_PAD1        /# Keypad End   #/
+   KEY_B2,     53('5'),        CTL_PAD5,   ALT_PAD5        /# Keypad 5     #/
+
+   Windows Telnet (raw)
+   ==============================
+   normal      shift           ctrl        alt
+   ESC [D,     ESC [D,         ESC [D,     ESC [D          /# Left         #/
+   ESC [C,     ESC [C,         ESC [C,     ESC [C          /# Right        #/
+   ESC [A,     ESC [A,         ESC [A,     ESC [A          /# Up           #/
+   ESC [B,     ESC [B,         ESC [B,     ESC [B          /# Down         #/
+   ESC [1~,    ESC [1~,        ESC [1~,    ESC [1~         /# Home         #/
+   ESC [5~,    ESC [5~,        ESC [5~,    ESC [5~         /# Page Up      #/
+   ESC [6~,    ESC [6~,        ESC [6~,    ESC [6~         /# Page Down    #/
+   ESC [4~,    ESC [4~,        ESC [4~,    ESC [4~         /# End          #/
+   ESC [D,     ESC [D,         ESC [D,     ESC [D          /# Keypad Left  #/
+   ESC [C,     ESC [C,         ESC [C,     ESC [C          /# Keypad Right #/
+   ESC [A,     ESC [A,         ESC [A,     ESC [A          /# Keypad Up    #/
+   ESC [B,     ESC [B,         ESC [B,     ESC [B          /# Keypad Down  #/
+   ESC [1~,    ESC [1~,        ESC [1~,    ESC [1~         /# Keypad Home  #/
+   ESC [5~,    ESC [5~,        ESC [5~,    ESC [5~         /# Keypad PgUp  #/
+   ESC [6~,    ESC [6~,        ESC [6~,    ESC [6~         /# Keypad PgDn  #/
+   ESC [4~,    ESC [4~,        ESC [4~,    ESC [4~         /# Keypad End   #/
+   nothing,    nothing,        nothing,    nothing         /# Keypad 5     #/
+
+   Windows Telnet (term=xterm)
+   ==============================
+   normal      shift           ctrl        alt
+   KEY_LEFT,   KEY_LEFT,       KEY_LEFT,   KEY_LEFT        /# Left         #/
+   KEY_RIGHT,  KEY_RIGHT,      KEY_RIGHT,  KEY_RIGHT       /# Right        #/
+   KEY_UP,     KEY_UP,         KEY_UP,     KEY_UP          /# Up           #/
+   KEY_DOWN,   KEY_DOWN,       KEY_DOWN,   KEY_DOWN        /# Down         #/
+   ESC [1~,    ESC [1~,        ESC [1~,    ESC [1~         /# Home         #/
+   KEY_PPAGE,  KEY_PPAGE,      KEY_PPAGE,  KEY_PPAGE       /# Page Up      #/
+   KEY_NPAGE,  KEY_NPAGE,      KEY_NPAGE,  KEY_NPAGE       /# Page Down    #/
+   ESC [4~,    ESC [4~,        ESC [4~,    ESC [4~         /# End          #/
+    KEY_LEFT,   KEY_LEFT,       KEY_LEFT,   O               /# Keypad Left  #/
+    KEY_RIGHT,  KEY_RIGHT,      KEY_RIGHT,  O               /# Keypad Right #/
+    KEY_UP,     KEY_UP,         KEY_UP,     O               /# Keypad Up    #/
+    KEY_DOWN,   KEY_DOWN,       KEY_DOWN,   O               /# Keypad Down  #/
+    ESC [1~,    ESC [1~,        ESC [1~,    ESC [1~         /# Keypad Home  #/
+    KEY_PPAGE,  KEY_PPAGE,      KEY_PPAGE,  KEY_PPAGE       /# Keypad PgUp  #/
+    KEY_NPAGE,  KEY_NPAGE,      KEY_NPAGE,  KEY_NPAGE       /# Keypad PgDn  #/
+    ESC [4~,    ESC [4~,        ESC [4~,    O               /# Keypad End   #/
+    ESC [-71,   nothing,        nothing,    O               /# Keypad 5     #/
+
+    PuTTY
+    ==============================
+    normal      shift           ctrl        alt
+    ESC [D,     ESC [D,         ESC OD,     ESC [D          /# Left         #/
+    ESC [C,     ESC [C,         ESC OC,     ESC [C          /# Right        #/
+    ESC [A,     ESC [A,         ESC OA,     ESC [A          /# Up           #/
+    ESC [B,     ESC [B,         ESC OB,     ESC [B          /# Down         #/
+    ESC [1~,    ESC [1~,        local win,  ESC [1~         /# Home         #/
+    ESC [5~,    local win,      local win,  ESC [5~         /# Page Up      #/
+    ESC [6~,    local win,      local win,  ESC [6~         /# Page Down    #/
+    ESC [4~,    ESC [4~,        local win,  ESC [4~         /# End          #/
+    ESC [D,     ESC [D,         ESC [D,     O               /# Keypad Left  #/
+    ESC [C,     ESC [C,         ESC [C,     O               /# Keypad Right #/
+    ESC [A,     ESC [A,         ESC [A,     O               /# Keypad Up    #/
+    ESC [B,     ESC [B,         ESC [B,     O               /# Keypad Down  #/
+    ESC [1~,    ESC [1~,        ESC [1~,    O               /# Keypad Home  #/
+    ESC [5~,    ESC [5~,        ESC [5~,    O               /# Keypad PgUp  #/
+    ESC [6~,    ESC [6~,        ESC [6~,    O               /# Keypad PgDn  #/
+    ESC [4~,    ESC [4~,        ESC [4~,    O               /# Keypad End   #/
+    nothing,    nothing,        nothing,    O               /# Keypad 5     #/
+
+    PuTTY
+    ==============================
+    normal      shift           ctrl        alt
+    KEY_LEFT,   KEY_LEFT,       ESC OD,     ESC KEY_LEFT    /# Left         #/
+    KEY_RIGHT   KEY_RIGHT,      ESC OC,     ESC KEY_RIGHT   /# Right        #/
+    KEY_UP,     KEY_UP,         ESC OA,     ESC KEY_UP      /# Up           #/
+    KEY_DOWN,   KEY_DOWN,       ESC OB,     ESC KEY_DOWN    /# Down         #/
+    ESC [1~,    ESC [1~,        local win,  ESC ESC [1~     /# Home         #/
+    KEY_PPAGE   local win,      local win,  ESC KEY_PPAGE   /# Page Up      #/
+    KEY_NPAGE   local win,      local win,  ESC KEY_NPAGE   /# Page Down    #/
+    ESC [4~,    ESC [4~,        local win,  ESC ESC [4~     /# End          #/
+    ESC Ot,     ESC Ot,         ESC Ot,     O               /# Keypad Left  #/
+    ESC Ov,     ESC Ov,         ESC Ov,     O               /# Keypad Right #/
+    ESC Ox,     ESC Ox,         ESC Ox,     O               /# Keypad Up    #/
+    ESC Or,     ESC Or,         ESC Or,     O               /# Keypad Down  #/
+    ESC Ow,     ESC Ow,         ESC Ow,     O               /# Keypad Home  #/
+    ESC Oy,     ESC Oy,         ESC Oy,     O               /# Keypad PgUp  #/
+    ESC Os,     ESC Os,         ESC Os,     O               /# Keypad PgDn  #/
+    ESC Oq,     ESC Oq,         ESC Oq,     O               /# Keypad End   #/
+    ESC Ou,     ESC Ou,         ESC Ou,     O               /# Keypad 5     #/
+*/
+
+#define M_NORMAL 0
+#define M_ESC    1
+#define M_KEYPAD 2
+#define M_TRAIL  3
+
+int
+md_readchar(WINDOW *win)
+{
+    int ch = 0;
+    int lastch = 0;
+    int mode = M_NORMAL;
+    int mode2 = M_NORMAL;
+
+    for(;;)
+    {
+        ch = wgetch(win);
+
+        if (ch == ERR)      /* timed out waiting for valid sequence */
+        {                   /* flush input so far and start over    */
+            mode = M_NORMAL;
+            nocbreak();
+            raw();
+            ch = 27;
+            break;
+        }
+
+        if (mode == M_TRAIL)
+        {
+            if (ch == '^')              /* msys console  : 7,5,6,8: modified*/
+                ch = MOD_MOVE( toupper(lastch) );
+
+            if (ch == '~')              /* cygwin console: 1,5,6,4: normal  */
+                ch = tolower(lastch);   /* windows telnet: 1,5,6,4: normal  */
+                                        /* msys console  : 7,5,6,8: normal  */
+
+            if (mode2 == M_ESC)         /* cygwin console: 1,5,6,4: modified*/
+                ch = MOD_MOVE( toupper(ch) );
+
+            break;
+        }
+
+        if (mode == M_ESC)
+        {
+            if (ch == 27)
+            {
+                mode2 = M_ESC;
+                continue;
+            }
+
+            if ((ch == 'F') || (ch == 'O') || (ch == '['))
+            {
+                mode = M_KEYPAD;
+                continue;
+            }
+
+
+            switch(ch)
+            {
+                /* Cygwin Console   */
+                /* PuTTY            */
+                case KEY_LEFT : ch = MOD_MOVE('H'); break;
+                case KEY_RIGHT: ch = MOD_MOVE('L'); break;
+                case KEY_UP   : ch = MOD_MOVE('K'); break;
+                case KEY_DOWN : ch = MOD_MOVE('J'); break;
+                case KEY_HOME : ch = MOD_MOVE('Y'); break;
+                case KEY_PPAGE: ch = MOD_MOVE('U'); break;
+                case KEY_NPAGE: ch = MOD_MOVE('N'); break;
+                case KEY_END  : ch = MOD_MOVE('B'); break;
+
+                default: break;
+            }
+
+            break;
+        }
+
+        if (mode == M_KEYPAD)
+        {
+            switch(ch)
+            {
+                /* ESC F - Interix Console codes */
+                case   '^': ch = MOD_MOVE('H'); break;      /* Shift-Left       */
+                case   '$': ch = MOD_MOVE('L'); break;      /* Shift-Right      */
+
+                /* ESC [ - Interix Console codes */
+                case   'H': ch = 'y'; break;            /* Home             */
+                case     1: ch = MOD_MOVE('K'); break;      /* Ctl-Keypad Up    */
+                case     2: ch = MOD_MOVE('J'); break;      /* Ctl-Keypad Down  */
+                case     3: ch = MOD_MOVE('L'); break;      /* Ctl-Keypad Right */
+                case     4: ch = MOD_MOVE('H'); break;      /* Ctl-Keypad Left  */
+                case   263: ch = MOD_MOVE('Y'); break;      /* Ctl-Keypad Home  */
+                case    19: ch = MOD_MOVE('U'); break;      /* Ctl-Keypad PgUp  */
+                case    20: ch = MOD_MOVE('N'); break;      /* Ctl-Keypad PgDn  */
+                case    21: ch = MOD_MOVE('B'); break;      /* Ctl-Keypad End   */
+
+                /* ESC [ - Cygwin Console codes */
+                case   'G': ch = '.'; break;            /* Keypad 5         */
+                case   '7': lastch = 'Y'; mode=M_TRAIL; break;  /* Ctl-Home */
+                case   '5': lastch = 'U'; mode=M_TRAIL; break;  /* Ctl-PgUp */
+                case   '6': lastch = 'N'; mode=M_TRAIL; break;  /* Ctl-PgDn */
+
+                /* ESC [ - Win32 Telnet, PuTTY */
+                case   '1': lastch = 'y'; mode=M_TRAIL; break;  /* Home     */
+                case   '4': lastch = 'b'; mode=M_TRAIL; break;  /* End      */
+
+                /* ESC O - PuTTY */
+                case   'D': ch = MOD_MOVE('H'); break;
+                case   'C': ch = MOD_MOVE('L'); break;
+                case   'A': ch = MOD_MOVE('K'); break;
+                case   'B': ch = MOD_MOVE('J'); break;
+                case   't': ch = 'h'; break;
+                case   'v': ch = 'l'; break;
+                case   'x': ch = 'k'; break;
+                case   'r': ch = 'j'; break;
+                case   'w': ch = 'y'; break;
+                case   'y': ch = 'u'; break;
+                case   's': ch = 'n'; break;
+                case   'q': ch = 'b'; break;
+                case   'u': ch = '.'; break;
+            }
+
+            if (mode != M_KEYPAD)
+                continue;
+        }
+
+        if (ch == 27)
+        {
+            halfdelay(1);
+            mode = M_ESC;
+            continue;
+        }
+
+        switch(ch)
+        {
+            case KEY_LEFT   : ch = 'h'; break;
+            case KEY_DOWN   : ch = 'j'; break;
+            case KEY_UP     : ch = 'k'; break;
+            case KEY_RIGHT  : ch = 'l'; break;
+            case KEY_HOME   : ch = 'y'; break;
+            case KEY_PPAGE  : ch = 'u'; break;
+            case KEY_END    : ch = 'b'; break;
+#ifdef KEY_LL
+            case KEY_LL     : ch = 'b'; break;
+#endif
+            case KEY_NPAGE  : ch = 'n'; break;
+
+#ifdef KEY_B1
+            case KEY_B1     : ch = 'h'; break;
+            case KEY_C2     : ch = 'j'; break;
+            case KEY_A2     : ch = 'k'; break;
+            case KEY_B3     : ch = 'l'; break;
+#endif
+            case KEY_A1     : ch = 'y'; break;
+            case KEY_A3     : ch = 'u'; break;
+            case KEY_C1     : ch = 'b'; break;
+            case KEY_C3     : ch = 'n'; break;
+            /* next should be '.', but for problem with putty/linux */
+            case KEY_B2     : ch = 'u'; break;
+
+#ifdef KEY_SLEFT
+            case KEY_SRIGHT  : ch = MOD_MOVE('L'); break;
+            case KEY_SLEFT   : ch = MOD_MOVE('H'); break;
+#ifdef KEY_SUP
+            case KEY_SUP     : ch = MOD_MOVE('K'); break;
+            case KEY_SDOWN   : ch = MOD_MOVE('J'); break;
+#endif
+            case KEY_SHOME   : ch = MOD_MOVE('Y'); break;
+            case KEY_SPREVIOUS:ch = MOD_MOVE('U'); break;
+            case KEY_SEND    : ch = MOD_MOVE('B'); break;
+            case KEY_SNEXT   : ch = MOD_MOVE('N'); break;
+#endif
+            case 0x146       : ch = MOD_MOVE('K'); break;   /* Shift-Up     */
+            case 0x145       : ch = MOD_MOVE('J'); break;   /* Shift-Down   */
+
+#ifdef CTL_RIGHT
+            case CTL_RIGHT   : ch = MOD_MOVE('L'); break;
+            case CTL_LEFT    : ch = MOD_MOVE('H'); break;
+            case CTL_UP      : ch = MOD_MOVE('K'); break;
+            case CTL_DOWN    : ch = MOD_MOVE('J'); break;
+            case CTL_HOME    : ch = MOD_MOVE('Y'); break;
+            case CTL_PGUP    : ch = MOD_MOVE('U'); break;
+            case CTL_END     : ch = MOD_MOVE('B'); break;
+            case CTL_PGDN    : ch = MOD_MOVE('N'); break;
+#endif
+#ifdef KEY_EOL
+            case KEY_EOL     : ch = MOD_MOVE('B'); break;
+#endif
+
+#ifndef CTL_PAD1
+            /* MSYS rxvt console */
+            case 511         : ch = MOD_MOVE('J'); break; /* Shift Dn */
+            case 512         : ch = MOD_MOVE('J'); break; /* Ctl Down */
+            case 514         : ch = MOD_MOVE('H'); break; /* Ctl Left */
+            case 516         : ch = MOD_MOVE('L'); break; /* Ctl Right*/
+            case 518         : ch = MOD_MOVE('K'); break; /* Shift Up */
+            case 519         : ch = MOD_MOVE('K'); break; /* Ctl Up   */
+#endif
+
+#ifdef CTL_PAD1
+            case CTL_PAD1   : ch = MOD_MOVE('B'); break;
+            case CTL_PAD2   : ch = MOD_MOVE('J'); break;
+            case CTL_PAD3   : ch = MOD_MOVE('N'); break;
+            case CTL_PAD4   : ch = MOD_MOVE('H'); break;
+            case CTL_PAD5   : ch = '.'; break;
+            case CTL_PAD6   : ch = MOD_MOVE('L'); break;
+            case CTL_PAD7   : ch = MOD_MOVE('Y'); break;
+            case CTL_PAD8   : ch = MOD_MOVE('K'); break;
+            case CTL_PAD9   : ch = MOD_MOVE('U'); break;
+#endif
+
+#ifdef ALT_RIGHT
+            case ALT_RIGHT  : ch = MOD_MOVE('L'); break;
+            case ALT_LEFT   : ch = MOD_MOVE('H'); break;
+            case ALT_DOWN   : ch = MOD_MOVE('J'); break;
+            case ALT_HOME   : ch = MOD_MOVE('Y'); break;
+            case ALT_PGUP   : ch = MOD_MOVE('U'); break;
+            case ALT_END    : ch = MOD_MOVE('B'); break;
+            case ALT_PGDN   : ch = MOD_MOVE('N'); break;
+#endif
+
+#ifdef ALT_PAD1
+            case ALT_PAD1   : ch = MOD_MOVE('B'); break;
+            case ALT_PAD2   : ch = MOD_MOVE('J'); break;
+            case ALT_PAD3   : ch = MOD_MOVE('N'); break;
+            case ALT_PAD4   : ch = MOD_MOVE('H'); break;
+            case ALT_PAD5   : ch = '.'; break;
+            case ALT_PAD6   : ch = MOD_MOVE('L'); break;
+            case ALT_PAD7   : ch = MOD_MOVE('Y'); break;
+            case ALT_PAD8   : ch = MOD_MOVE('K'); break;
+            case ALT_PAD9   : ch = MOD_MOVE('U'); break;
+#endif
+        }
+
+        break;
+    }
+
+    nocbreak();     /* disable halfdelay mode if on */
+    raw();
+
+    return(ch & 0x7F);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/misc.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,736 @@
+/*
+ * routines dealing specifically with miscellaneous magic
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include <ctype.h>
+#include "rogue.h"
+
+/*
+ * See if a monster has some magic it can use.  Use it and return TRUE if so.
+ */
+bool
+m_use_item(monster, monst_pos, defend_pos)
+register struct thing *monster;
+register coord *monst_pos, *defend_pos;
+{
+    register struct linked_list *pitem;
+    register struct object *obj;
+    register coord *shoot_dir = can_shoot(monst_pos, defend_pos);
+    int dist=DISTANCE(monst_pos->y, monst_pos->x, defend_pos->y, defend_pos->x);
+
+    for (pitem=monster->t_pack; pitem; pitem=next(pitem)) {
+	obj = OBJPTR(pitem);
+	if (obj->o_type != RELIC) continue;	/* Only care about relics now */
+	switch (obj->o_which) {
+	    case MING_STAFF: {
+		static struct object missile = {
+		  MISSILE, {0,0}, "", 0, "", "0d4 " , NULL, 0, WS_MISSILE, 100, 1
+		};
+
+		if (shoot_dir != NULL) {
+		    sprintf(missile.o_hurldmg, "%dd4", monster->t_stats.s_lvl);
+		    do_motion(&missile, shoot_dir->y, shoot_dir->x, monster);
+		    hit_monster(unc(missile.o_pos), &missile, monster);
+		    return(TRUE);
+		}
+	    }
+	    when ASMO_ROD:
+		/* The bolt must be able to reach the defendant */
+		if (shoot_dir != NULL && dist < BOLT_LENGTH * BOLT_LENGTH) {
+		    char *name;
+
+		    switch (rnd(3)) { /* Select a function */
+			case 0:	   name = "lightning bolt";
+			when 1:	   name = "flame";
+			otherwise: name = "ice";
+		    }
+		    shoot_bolt(	monster, 
+				*monst_pos, 
+				*shoot_dir, 
+				FALSE, 
+				monster->t_index, 
+				name, 
+				roll(monster->t_stats.s_lvl,6));
+		    return(TRUE);
+		}
+	    when BRIAN_MANDOLIN:
+		/* The defendant must be the player and within 2 spaces */
+		if (ce(*defend_pos, hero) && dist < 9 && no_command == 0 &&
+		    rnd(100) < 33) {
+		    if (!save(VS_MAGIC, &player, -4) &&
+			!ISWEARING(R_ALERT)) {
+			msg("Some beautiful music enthralls you.");
+			no_command += FREEZETIME;
+		    }
+		    else msg("You wince at a sour note.");
+		    return(TRUE);
+		}
+	    when GERYON_HORN:
+		/* The defendant must be the player and within 2 spaces */
+		if (ce(*defend_pos, hero) && dist < 9 &&
+		    (off(player, ISFLEE) || player.t_dest != &monster->t_pos)
+		    && rnd(100) < 33) {
+		    if (!ISWEARING(R_HEROISM) &&
+			!save(VS_MAGIC, &player, -4)) {
+			    turn_on(player, ISFLEE);
+			    player.t_dest = &monster->t_pos;
+			    msg("A shrill blast terrifies you.");
+		    }
+		    else msg("A shrill blast sends chills up your spine.");
+		    return(TRUE);
+		}
+	}
+    }
+    return(FALSE);
+}
+ 
+/*
+ * add something to the contents of something else
+ */
+put_contents(bag, item)
+register struct object *bag;		/* the holder of the items */
+register struct linked_list *item;	/* the item to put inside  */
+{
+    register struct linked_list *titem;
+    register struct object *tobj;
+
+    bag->o_ac++;
+    tobj = OBJPTR(item);
+    for (titem = bag->contents; titem != NULL; titem = next(titem)) {
+	if ((OBJPTR(titem))->o_which == tobj->o_which)
+	    break;
+    }
+    if (titem == NULL) {	/* if not a duplicate put at beginning */
+	attach(bag->contents, item);
+    }
+    else {
+	item->l_prev = titem;
+	item->l_next = titem->l_next;
+	if (next(titem) != NULL) 
+	    (titem->l_next)->l_prev = item;
+	titem->l_next = item;
+    }
+}
+
+/*
+ * remove something from something else
+ */
+take_contents(bag, item)
+register struct object *bag;		/* the holder of the items */
+register struct linked_list *item;
+{
+
+    if (bag->o_ac <= 0) {
+	msg("Nothing to take out");
+	return;
+    }
+    bag->o_ac--;
+    detach(bag->contents, item);
+    if (!add_pack(item, FALSE, NULL))
+	put_contents(bag, item);
+}
+
+
+do_bag(item)
+register struct linked_list *item;
+{
+
+    register struct linked_list *titem = NULL;
+    register struct object *obj;
+    bool doit = TRUE;
+
+    obj = OBJPTR(item);
+    while (doit) {
+	msg("What do you want to do? (* for a list): ");
+	mpos = 0;
+	switch (readchar()) {
+	    case EOF:
+	    case ESCAPE:
+		msg ("");
+		doit = FALSE;
+	    when '1':
+		inventory(obj->contents, ALL);
+
+	    when '2':
+		if (obj->o_ac >= MAXCONTENTS) {
+		    msg("the %s is full", m_magic[obj->o_which].mi_name);
+		    break;
+		}
+		switch (obj->o_which) {
+		case MM_BEAKER: titem = get_item(pack, "put in", POTION);
+		when MM_BOOK:   titem = get_item(pack, "put in", SCROLL);
+		}
+		if (titem == NULL)
+		    break;
+		detach(pack, titem);
+		inpack--;
+		put_contents(obj, titem);
+	    
+	    when '3':
+		titem = get_item(obj->contents,"take out",ALL);
+		if (titem == NULL)
+		    break;
+		take_contents(obj, titem);
+		
+	    when '4': 
+		switch (obj->o_which) {
+		case MM_BEAKER: 
+		    titem = get_item(obj->contents,"quaff",ALL);
+		    if (titem == NULL)
+			break;
+		    obj->o_ac--;
+		    detach(obj->contents, titem);
+		    quaff((OBJPTR(titem))->o_which, 
+			  (OBJPTR(titem))->o_flags & (ISCURSED | ISBLESSED),
+			  TRUE);
+		    o_discard(titem);
+		when MM_BOOK:   
+		    if (on(player, ISBLIND)) {
+			msg("You can't see to read anything");
+			break;
+		    }
+		    titem = get_item(obj->contents,"read",ALL);
+		    if (titem == NULL)
+			break;
+		    obj->o_ac--;
+		    detach(obj->contents, titem);
+		    read_scroll((OBJPTR(titem))->o_which, 
+			        (OBJPTR(titem))->o_flags & (ISCURSED|ISBLESSED),
+				TRUE);
+		    o_discard(titem);
+		}
+		doit = FALSE;
+
+	    otherwise:
+		wclear(hw);
+		touchwin(hw);
+		mvwaddstr(hw,0,0,"The following operations are available:");
+		mvwaddstr(hw,2,0,"[1]\tInventory\n");
+		wprintw(hw,"[2]\tPut something in the %s\n",
+			m_magic[obj->o_which].mi_name);
+		wprintw(hw,"[3]\tTake something out of the %s\n",
+			m_magic[obj->o_which].mi_name);
+		switch(obj->o_which) {
+		    case MM_BEAKER: waddstr(hw,"[4]\tQuaff a potion\n");
+		    when MM_BOOK:   waddstr(hw,"[4]\tRead a scroll\n");
+		}
+		waddstr(hw,"[ESC]\tLeave this menu\n");
+		mvwaddstr(hw, LINES-1, 0, spacemsg);
+		draw(hw);
+		wait_for (hw,' ');
+		clearok(cw, TRUE);
+		touchwin(cw);
+	}
+    }
+}
+
+do_panic()
+{
+    register int x,y;
+    register struct linked_list *mon;
+    register struct thing *th;
+
+    for (x = hero.x-2; x <= hero.x+2; x++) {
+	for (y = hero.y-2; y <= hero.y+2; y++) {
+	    if (y < 1 || x < 0 || y > LINES - 3  || x > COLS - 1) 
+		continue;
+	    if (isalpha(mvwinch(mw, y, x))) {
+		if ((mon = find_mons(y, x)) != NULL) {
+		    th = THINGPTR(mon);
+		    if (!on(*th, ISUNDEAD) && !save(VS_MAGIC, th, 0)) {
+			turn_on(*th, ISFLEE);
+			turn_on(*th, WASTURNED);
+
+			/* If monster was suffocating, stop it */
+			if (on(*th, DIDSUFFOCATE)) {
+			    turn_off(*th, DIDSUFFOCATE);
+			    extinguish(suffocate);
+			}
+
+			/* If monster held us, stop it */
+			if (on(*th, DIDHOLD) && (--hold_count == 0))
+				turn_off(player, ISHELD);
+			turn_off(*th, DIDHOLD);
+		    }
+		    runto(th, &hero);
+		}
+	    }
+	}
+    }
+}
+
+/*
+ * print miscellaneous magic bonuses
+ */
+char *
+misc_name(obj)
+register struct object *obj;
+{
+    static char buf[LINELEN];
+    char buf1[LINELEN];
+
+    buf[0] = '\0';
+    buf1[0] = '\0';
+    if (!(obj->o_flags & ISKNOW))
+	return (m_magic[obj->o_which].mi_name);
+    switch (obj->o_which) {
+	case MM_BRACERS:
+	case MM_PROTECT:
+	    strcat(buf, num(obj->o_ac, 0));
+	    strcat(buf, " ");
+    }
+    switch (obj->o_which) {
+	case MM_G_OGRE:
+	case MM_G_DEXTERITY:
+	case MM_JEWEL:
+	case MM_STRANGLE:
+	case MM_R_POWERLESS:
+	case MM_DANCE:
+	    if (obj->o_flags & ISCURSED)
+		strcat(buf, "cursed ");
+    }
+    strcat(buf, m_magic[obj->o_which].mi_name);
+    switch (obj->o_which) {
+	case MM_JUG:
+	    if (obj->o_ac == JUG_EMPTY)
+		strcat(buf1, " [empty]");
+	    else if (p_know[obj->o_ac])
+		sprintf(buf1, " [containing a potion of %s (%s)]",
+			p_magic[obj->o_ac].mi_name,
+			p_colors[obj->o_ac]);
+	    else sprintf(buf1, " [containing a%s %s liquid]", 
+			vowelstr(p_colors[obj->o_ac]),
+			p_colors[obj->o_ac]);
+	when MM_BEAKER:		
+	case MM_BOOK: {
+	    sprintf(buf1, " [containing %d]", obj->o_ac);
+	}
+	when MM_OPEN:
+	case MM_HUNGER:
+	    sprintf(buf1, " [%d ring%s]", obj->o_charges, 
+			  obj->o_charges == 1 ? "" : "s");
+	when MM_DRUMS:
+	    sprintf(buf1, " [%d beat%s]", obj->o_charges, 
+			  obj->o_charges == 1 ? "" : "s");
+	when MM_DISAPPEAR:
+	case MM_CHOKE:
+	    sprintf(buf1, " [%d pinch%s]", obj->o_charges, 
+			  obj->o_charges == 1 ? "" : "es");
+	when MM_KEOGHTOM:
+	    sprintf(buf1, " [%d application%s]", obj->o_charges, 
+			  obj->o_charges == 1 ? "" : "s");
+	when MM_SKILLS:
+	    switch (obj->o_ac) {
+	    case C_MAGICIAN:	strcpy(buf1, " [magic user]");
+	    when C_FIGHTER:	strcpy(buf1, " [fighter]");
+	    when C_CLERIC:	strcpy(buf1, " [cleric]");
+	    when C_THIEF:	strcpy(buf1, " [thief]");
+	    }
+    }
+    strcat (buf, buf1);
+    return buf;
+}
+
+use_emori()
+{
+    char selection;	/* Cloak function */
+    int state = 0;	/* Menu state */
+
+    msg("What do you want to do? (* for a list): ");
+    do {
+	selection = tolower(readchar());
+	switch (selection) {
+	    case '*':
+	      if (state != 1) {
+		wclear(hw);
+		touchwin(hw);
+		mvwaddstr(hw, 2, 0,  "[1] Fly\n[2] Stop flying\n");
+		waddstr(hw,	     "[3] Turn invisible\n[4] Turn Visible\n");
+		mvwaddstr(hw, 0, 0, "What do you want to do? ");
+		draw(hw);
+		state = 1;	/* Now in prompt window */
+	      }
+	      break;
+
+	    case ESCAPE:
+		if (state == 1) {
+		    clearok(cw, TRUE); /* Set up for redraw */
+		    touchwin(cw);
+		}
+		msg("");
+
+		after = FALSE;
+		return;
+
+	    when '1':
+	    case '2':
+	    case '3':
+	    case '4':
+		if (state == 1) {	/* In prompt window */
+		    clearok(cw, TRUE); /* Set up for redraw */
+		    touchwin(cw);
+		}
+
+		msg("");
+
+		state = 2;	/* Finished */
+		break;
+
+	    default:
+		if (state == 1) {	/* In the prompt window */
+		    mvwaddstr(hw, 0, 0,
+				"Please enter a selection between 1 and 4:  ");
+		    draw(hw);
+		}
+		else {	/* Normal window */
+		    mpos = 0;
+		    msg("Please enter a selection between 1 and 4:  ");
+		}
+	}
+    } while (state != 2);
+
+    /* We now must have a selection between 1 and 4 */
+    switch (selection) {
+	case '1':	/* Fly */
+	    if (on(player, ISFLY)) {
+		extinguish(land);	/* Extinguish in case of potion */
+		msg("%slready flying.", terse ? "A" : "You are a");
+	    }
+	    else {
+		msg("You feel lighter than air!");
+		turn_on(player, ISFLY);
+	    }
+	when '2':	/* Stop flying */
+	    if (off(player, ISFLY))
+		msg("%sot flying.", terse ? "N" : "You are n");
+	    else {
+		if (find_slot(land))
+		    msg("%sot flying by the cloak.",
+			terse ? "N" : "You are n");
+		else land();
+	    }
+	when '3':	/* Turn invisible */
+	    if (off(player, ISINVIS)) {
+		turn_on(player, ISINVIS);
+		msg("You have a tingling feeling all over your body");
+		PLAYER = IPLAYER;
+		light(&hero);
+	    }
+	    else {
+		extinguish(appear);	/* Extinguish in case of potion */
+		extinguish(dust_appear);/* dust of disappearance        */
+		msg("%slready invisible.", terse ? "A" : "You are a");
+	    }
+	when '4':	/* Turn visible */
+	    if (off(player, ISINVIS))
+		msg("%sot invisible.", terse ? "N" : "You are n");
+	    else {
+		if (find_slot(appear) || find_slot(dust_appear))
+		    msg("%sot invisible by the cloak.",
+			terse ? "N" : "You are n");
+		else appear();
+	    }
+    }
+}
+
+use_mm(which)
+int which;
+{
+    register struct object *obj = NULL;
+    register struct linked_list *item = NULL;
+    bool cursed, blessed, is_mm;
+    char buf[LINELEN];
+
+    cursed = FALSE;
+    is_mm = FALSE;
+
+    if (which < 0) {	/* A real miscellaneous magic item  */
+	is_mm = TRUE;
+	item = get_item(pack, "use", USEABLE);
+	/*
+	 * Make certain that it is a micellaneous magic item
+	 */
+	if (item == NULL)
+	    return;
+
+	obj = OBJPTR(item);
+	cursed = (obj->o_flags & ISCURSED) != 0;
+	blessed = (obj->o_flags & ISBLESSED) != 0;
+	which = obj->o_which;
+    }
+
+    if (obj->o_type == RELIC) {		/* An artifact */
+	is_mm = FALSE;
+	switch (obj->o_which) {
+	    case EMORI_CLOAK:
+		use_emori();
+	    when BRIAN_MANDOLIN:
+		/* Put monsters around us to sleep */
+		read_scroll(S_HOLD, 0, FALSE);
+	    when GERYON_HORN:
+		/* Chase close monsters away */
+		msg("The horn blasts a shrill tone.");
+		do_panic();
+	    when HEIL_ANKH:
+	    case YENDOR_AMULET:
+		/* Nothing happens by this mode */
+		msg("Nothing happens.");
+	}
+    }
+    else switch (which) {		/* Miscellaneous Magic */
+	/*
+	 * the jug of alchemy manufactures potions when you drink
+	 * the potion it will make another after a while
+	 */
+	case MM_JUG:
+	    if (obj->o_ac == JUG_EMPTY) {
+		msg("The jug is empty");
+		break;
+	    }
+	    quaff (obj->o_ac, NULL, FALSE);
+	    obj->o_ac = JUG_EMPTY;
+	    fuse (alchemy, obj, ALCHEMYTIME, AFTER);
+	    if (!(obj->o_flags & ISKNOW))
+	        whatis(item);
+
+	/*
+	 * the beaker of plentiful potions is used to hold potions
+	 * the book of infinite spells is used to hold scrolls
+	 */
+	when MM_BEAKER:
+	case MM_BOOK:
+	    do_bag(item);
+
+	/*
+	 * the chime of opening opens up secret doors
+	 */
+	when MM_OPEN:
+	{
+	    register struct linked_list *exit;
+	    register struct room *rp;
+	    register coord *cp;
+
+	    if (obj->o_charges <= 0) {
+		msg("The chime is cracked!");
+		break;
+	    }
+	    obj->o_charges--;
+	    msg("chime... chime... hime... ime... me... e...");
+	    if ((rp = roomin(&hero)) == NULL) {
+		search(FALSE, TRUE); /* Non-failing search for door */
+		break;
+	    }
+	    for (exit = rp->r_exit; exit != NULL; exit = next(exit)) {
+		cp = DOORPTR(exit);
+		if (winat(cp->y, cp->x) == SECRETDOOR) {
+		    mvaddch (cp->y, cp->x, DOOR);
+		    if (cansee (cp->y, cp->x))
+			mvwaddch(cw, cp->y, cp->x, DOOR);
+		}
+	    }
+	}
+
+	/*
+	 * the chime of hunger just makes the hero hungry
+	 */
+	when MM_HUNGER:
+	    if (obj->o_charges <= 0) {
+		msg("The chime is cracked!");
+		break;
+	    }
+	    obj->o_charges--;
+	    food_left = MORETIME + 5;
+	    msg(terse ? "Getting hungry" : "You are starting to get hungry");
+	    hungry_state = F_HUNGRY;
+	    aggravate();
+
+	/*
+	 * the drums of panic make all creatures within two squares run
+	 * from the hero in panic unless they save or they are mindless
+	 * undead
+	 */
+	when MM_DRUMS:
+	    if (obj->o_charges <= 0) {
+		msg("The drum is broken!");
+		break;
+	    }
+	    obj->o_charges--;
+	/*
+	 * dust of disappearance makes the player invisible for a while
+	 */
+	when MM_DISAPPEAR:
+	    m_know[MM_DISAPPEAR] = TRUE;
+	    if (obj->o_charges <= 0) {
+		msg("No more dust!");
+		break;
+	    }
+	    obj->o_charges--;
+	    msg("aaAAACHOOOooo. Cough. Cough. Sneeze. Sneeze.");
+	    if (!find_slot(dust_appear)) {
+		turn_on(player, ISINVIS);
+		fuse(dust_appear, 0, DUSTTIME, AFTER);
+		PLAYER = IPLAYER;
+		light(&hero);
+	    }
+	    else lengthen(dust_appear, DUSTTIME);
+
+	/*
+	 * dust of choking and sneezing can kill the hero if he misses
+	 * the save
+	 */
+	when MM_CHOKE:
+	    m_know[MM_CHOKE] = TRUE;
+	    if (obj->o_charges <= 0) {
+		msg("No more dust!");
+		break;
+	    }
+	    obj->o_charges--;
+	    msg("aaAAACHOOOooo. Cough. Cough. Sneeze. Sneeze.");
+	    if (!save(VS_POISON, &player, 0)) {
+		msg ("You choke to death!!! --More--");
+		pstats.s_hpt = -1; /* in case he hangs up the phone */
+		wait_for(cw,' ');
+		death(D_CHOKE);
+	    }
+	    else {
+		msg("You begin to cough and choke uncontrollably");
+		if (find_slot(unchoke))
+		    lengthen(unchoke, DUSTTIME);
+		else
+		    fuse(unchoke, 0, DUSTTIME, AFTER);
+		turn_on(player, ISHUH);
+		turn_on(player, ISBLIND);
+		light(&hero);
+	    }
+		
+	when MM_KEOGHTOM:
+	    /*
+	     * this is a very powerful healing ointment
+	     * but it takes a while to put on...
+	     */
+	    if (obj->o_charges <= 0) {
+		msg("The jar is empty!");
+		break;
+	    }
+	    obj->o_charges--;
+	    waste_time();
+	    if (on(player, HASDISEASE)) {
+		extinguish(cure_disease);
+		cure_disease();
+		msg(terse ? "You feel yourself improving."
+			  : "You begin to feel yourself improving again.");
+	    }
+	    if (on(player, HASINFEST)) {
+		turn_off(player, HASINFEST);
+		infest_dam = 0;
+		msg(terse ? "You feel yourself improving."
+			  : "You begin to feel yourself improving again.");
+	    }
+	    if (on(player, DOROT)) {
+		msg("You feel your skin returning to normal.");
+		turn_off(player, DOROT);
+	    }
+	    pstats.s_hpt += roll(pstats.s_lvl, 6);
+	    if (pstats.s_hpt > max_stats.s_hpt)
+		pstats.s_hpt = max_stats.s_hpt;
+	    sight();
+	    msg("You begin to feel much better.");
+		
+	/*
+	 * The book has a character class associated with it.
+	 * if your class matches that of the book, it will raise your 
+	 * level by one. If your class does not match the one of the book, 
+	 * it change your class to that of book.
+	 * Note that it takes a while to read.
+	 */
+	when MM_SKILLS:
+	    detach (pack, item);
+	    inpack--;
+	    waste_time();
+	    waste_time();
+	    waste_time();
+	    waste_time();
+	    waste_time();
+	    if (obj->o_ac == player.t_ctype) {
+		msg("You feel more skillful");
+		raise_level(TRUE);
+	    }
+	    else {
+		/*
+		 * reset his class and then use check_level to reset hit
+		 * points and the right level for his exp pts
+		 * drop exp pts by 10%
+		 */
+		long save;
+
+		msg("You feel like a whole new person!");
+		/*
+		 * if he becomes a thief he has to have leather armor
+		 */
+		if (obj->o_ac == C_THIEF			&&
+		    cur_armor != NULL				&&
+		    cur_armor->o_which != LEATHER		&&
+		    cur_armor->o_which != STUDDED_LEATHER ) 
+			cur_armor->o_which = STUDDED_LEATHER;
+		/*
+		 * if he's changing from a fighter then may have to change
+		 * his sword since only fighter can use two-handed
+		 * and bastard swords
+		 */
+		if (player.t_ctype == C_FIGHTER			&&
+		    cur_weapon != NULL				&&
+		    cur_weapon->o_type == WEAPON		&&
+		   (cur_weapon->o_which== BASWORD		||
+		    cur_weapon->o_which== TWOSWORD )) 
+			cur_weapon->o_which = SWORD;
+
+		/*
+		 * if he was a thief then take out the trap_look() daemon
+		 */
+		if (player.t_ctype == C_THIEF)
+		    kill_daemon(trap_look);
+		/*
+		 * if he becomes a thief then add the trap_look() daemon
+		 */
+		if (obj->o_ac == C_THIEF)
+		    daemon(trap_look, 0, AFTER);
+		char_type = player.t_ctype = obj->o_ac;
+		save = pstats.s_hpt;
+		max_stats.s_hpt = pstats.s_hpt = 0;
+		max_stats.s_lvl = pstats.s_lvl = 0; 
+		max_stats.s_exp = pstats.s_exp -= pstats.s_exp/10;
+		check_level(TRUE);
+		if (pstats.s_hpt > save) /* don't add to current hits */
+		    pstats.s_hpt = save;
+	    }
+
+	otherwise:
+	    msg("What a strange magic item you have!");
+    }
+    status(FALSE);
+    if (is_mm && m_know[which] && m_guess[which]) {
+	free(m_guess[which]);
+	m_guess[which] = NULL;
+    }
+    else if (is_mm && 
+	     !m_know[which] && 
+	     askme &&
+	     (obj->o_flags & ISKNOW) == 0 &&
+	     m_guess[which] == NULL) {
+	msg(terse ? "Call it: " : "What do you want to call it? ");
+	if (get_str(buf, cw) == NORM) {
+	    m_guess[which] = new((unsigned int) strlen(buf) + 1);
+	    strcpy(m_guess[which], buf);
+	}
+    }
+    if (item != NULL && which == MM_SKILLS)
+	o_discard(item);
+    updpack(TRUE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/monsters.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,1034 @@
+/*
+ * File with various monster functions in it
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include "rogue.h"
+#include <ctype.h>
+#include <string.h>
+
+
+/*
+ * Check_residue takes care of any effect of the monster 
+ */
+check_residue(tp)
+register struct thing *tp;
+{
+    /*
+     * Take care of special abilities
+     */
+    if (on(*tp, DIDHOLD) && (--hold_count == 0)) turn_off(player, ISHELD);
+
+    /* If it has lowered player, give him back a level */
+    if (on(*tp, DIDDRAIN)) raise_level(FALSE);
+
+    /* If frightened of this monster, stop */
+    if (on(player, ISFLEE) &&
+	player.t_dest == &tp->t_pos) turn_off(player, ISFLEE);
+
+    /* If monster was suffocating player, stop it */
+    if (on(*tp, DIDSUFFOCATE)) extinguish(suffocate);
+
+    /* If something with fire, may darken */
+    if (on(*tp, HASFIRE)) {
+	register struct room *rp=roomin(&tp->t_pos);
+	register struct linked_list *fire_item;
+
+	if (rp) {
+	    for (fire_item = rp->r_fires; fire_item != NULL;
+		 fire_item = next(fire_item)) {
+		if (THINGPTR(fire_item) == tp) {
+		    detach(rp->r_fires, fire_item);
+		    destroy_item(fire_item);
+		    if (rp->r_fires == NULL) {
+			rp->r_flags &= ~HASFIRE;
+			if (cansee(tp->t_pos.y, tp->t_pos.x)) light(&hero);
+		    }
+		    break;
+		}
+	    }
+	}
+    }
+}
+
+/*
+ * Creat_mons creates the specified monster -- any if 0 
+ */
+
+bool
+creat_mons(person, monster, report)
+struct thing *person;	/* Where to create next to */
+short monster;
+bool report;
+{
+    struct linked_list *nitem;
+    register struct thing *tp;
+    struct room *rp;
+    coord *mp;
+
+    if (levtype == POSTLEV)
+	return(FALSE);
+    if ((mp = fallpos(&(person->t_pos), FALSE, 2)) != NULL) {
+	nitem = new_item(sizeof (struct thing));
+	new_monster(nitem,
+		    monster == 0 ? randmonster(FALSE, FALSE)
+				 : monster,
+		    mp,
+		    TRUE);
+	tp = THINGPTR(nitem);
+	runto(tp, &hero);
+	tp->t_no_move = 1;	/* since it just got here, it is disoriented */
+	carry_obj(tp, monsters[tp->t_index].m_carry/2); /* only half chance */
+	if (on(*tp, HASFIRE)) {
+	    rp = roomin(&tp->t_pos);
+	    if (rp) {
+		register struct linked_list *fire_item;
+
+		/* Put the new fellow in the room list */
+		fire_item = creat_item();
+		ldata(fire_item) = (char *) tp;
+		attach(rp->r_fires, fire_item);
+
+		rp->r_flags |= HASFIRE;
+	    }
+	}
+
+	/* 
+	 * If we can see this monster, set oldch to ' ' to make light()
+	 * think the creature used to be invisible (ie. not seen here)
+	 */
+	if (cansee(tp->t_pos.y, tp->t_pos.x)) tp->t_oldch = ' ';
+	return(TRUE);
+    }
+    if (report) msg("You hear a faint cry of anguish in the distance.");
+    return(FALSE);
+}
+
+/*
+ * Genmonsters:
+ *	Generate at least 'least' monsters for this single room level.
+ *	'Treas' indicates whether this is a "treasure" level.
+ */
+
+void
+genmonsters(least, treas)
+register int least;
+bool treas;
+{
+    reg int i;
+    reg struct room *rp = &rooms[0];
+    reg struct linked_list *item;
+    reg struct thing *mp;
+    coord tp;
+
+    for (i = 0; i < level + least; i++) {
+	    if (!treas && rnd(100) < 50)	/* put in some little buggers */
+		    continue;
+	    /*
+	     * Put the monster in
+	     */
+	    item = new_item(sizeof *mp);
+	    mp = THINGPTR(item);
+	    do {
+		    rnd_pos(rp, &tp);
+	    } until(mvwinch(stdscr, tp.y, tp.x) == FLOOR);
+
+	    new_monster(item, randmonster(FALSE, FALSE), &tp, FALSE);
+	    /*
+	     * See if we want to give it a treasure to carry around.
+	     */
+	    carry_obj(mp, monsters[mp->t_index].m_carry);
+
+	    /* Is it going to give us some light? */
+	    if (on(*mp, HASFIRE)) {
+		register struct linked_list *fire_item;
+
+		fire_item = creat_item();
+		ldata(fire_item) = (char *) mp;
+		attach(rp->r_fires, fire_item);
+		rp->r_flags |= HASFIRE;
+	    }
+    }
+}
+
+/*
+ * id_monst returns the index of the monster given its letter
+ */
+
+short
+id_monst(monster)
+register char monster;
+{
+    register short result;
+
+    result = NLEVMONS*vlevel;
+    if (result > NUMMONST) result = NUMMONST;
+
+    for(; result>0; result--)
+	if (monsters[result].m_appear == monster) return(result);
+    for (result=(NLEVMONS*vlevel)+1; result <= NUMMONST; result++)
+	if (monsters[result].m_appear == monster) return(result);
+    return(0);
+}
+
+
+/*
+ * new_monster:
+ *	Pick a new monster and add it to the list
+ */
+
+new_monster(item, type, cp, max_monster)
+struct linked_list *item;
+short type;
+register coord *cp;
+bool max_monster;
+{
+    register struct thing *tp;
+    register struct monster *mp;
+    register char *ip, *hitp;
+    register int i, min_intel, max_intel;
+    register int num_dice, num_sides=8, num_extra=0;
+
+    attach(mlist, item);
+    tp = THINGPTR(item);
+    tp->t_turn = TRUE;
+    tp->t_pack = NULL;
+    tp->t_index = type;
+    tp->t_wasshot = FALSE;
+    tp->t_type = monsters[type].m_appear;
+    tp->t_ctype = C_MONSTER;
+    tp->t_no_move = 0;
+    tp->t_doorgoal = 0;
+    tp->t_quiet = 0;
+    tp->t_pos = tp->t_oldpos = *cp;
+    tp->t_oldch = CCHAR( mvwinch(cw, cp->y, cp->x) );
+    mvwaddch(mw, cp->y, cp->x, tp->t_type);
+    mp = &monsters[tp->t_index];
+
+    /* Figure out monster's hit points */
+    hitp = mp->m_stats.s_hpt;
+    num_dice = atoi(hitp);
+    if ((hitp = strchr(hitp, 'd')) != NULL) {
+	num_sides = atoi(++hitp);
+	if ((hitp = strchr(hitp, '+')) != NULL)
+	    num_extra = atoi(++hitp);
+    }
+
+    tp->t_stats.s_lvl = mp->m_stats.s_lvl;
+    tp->t_stats.s_arm = mp->m_stats.s_arm;
+    strncpy(tp->t_stats.s_dmg,mp->m_stats.s_dmg,sizeof(tp->t_stats.s_dmg));
+    tp->t_stats.s_str = mp->m_stats.s_str;
+    if (vlevel > HARDER) { /* the deeper, the meaner we get */
+	 tp->t_stats.s_lvl += (vlevel - HARDER);
+	 num_dice += (vlevel - HARDER)/2;
+    }
+    if (max_monster)
+	tp->t_stats.s_hpt = num_dice * num_sides + num_extra;
+    else
+	tp->t_stats.s_hpt = roll(num_dice, num_sides) + num_extra;
+    tp->t_stats.s_exp = mp->m_stats.s_exp + mp->m_add_exp*tp->t_stats.s_hpt;
+
+    /*
+     * just initailize others values to something reasonable for now
+     * maybe someday will *really* put these in monster table
+     */
+    tp->t_stats.s_wisdom = 8 + rnd(4);
+    tp->t_stats.s_dext = 8 + rnd(4);
+    tp->t_stats.s_const = 8 + rnd(4);
+    tp->t_stats.s_charisma = 8 + rnd(4);
+
+    /* Set the initial flags */
+    for (i=0; i<16; i++) tp->t_flags[i] = 0;
+    for (i=0; i<MAXFLAGS; i++)
+	turn_on(*tp, mp->m_flags[i]);
+
+    /* suprising monsters don't always surprise you */
+    if (!max_monster		&& on(*tp, CANSURPRISE) && 
+	off(*tp, ISUNIQUE)	&& rnd(100) < 20)
+	    turn_off(*tp, CANSURPRISE);
+
+    /* If this monster is unique, gen it */
+    if (on(*tp, ISUNIQUE)) mp->m_normal = FALSE;
+
+    /* 
+     * if is it the quartermaster, then compute his level and exp pts
+     * based on the level. This will make it fair when thieves try to
+     * steal and give them reasonable experience if they succeed.
+     */
+    if (on(*tp, CANSELL)) {	
+	tp->t_stats.s_exp = vlevel * 100;
+	tp->t_stats.s_lvl = vlevel/2 + 1;
+	attach(tp->t_pack, new_thing(ALL));
+    }
+
+    /* Normally scared monsters have a chance to not be scared */
+    if (on(*tp, ISFLEE) && (rnd(4) == 0)) turn_off(*tp, ISFLEE);
+
+    /* Figure intelligence */
+    min_intel = atoi(mp->m_intel);
+    if ((ip = (char *) strchr(mp->m_intel, '-')) == NULL)
+	tp->t_stats.s_intel = min_intel;
+    else {
+	max_intel = atoi(++ip);
+	if (max_monster)
+	    tp->t_stats.s_intel = max_intel;
+	else
+	    tp->t_stats.s_intel = min_intel + rnd(max_intel - min_intel);
+    }
+    if (vlevel > HARDER) 
+	 tp->t_stats.s_intel += ((vlevel - HARDER)/2);
+    tp->maxstats = tp->t_stats;
+
+    /* If the monster can shoot, it may have a weapon */
+    if (on(*tp, CANSHOOT) && ((rnd(100) < (22 + vlevel)) || max_monster)) {
+	struct linked_list *item1;
+	register struct object *cur, *cur1;
+
+	item = new_item(sizeof *cur);
+	item1 = new_item(sizeof *cur1);
+	cur = OBJPTR(item);
+	cur1 = OBJPTR(item1);
+	cur->o_hplus = (rnd(4) < 3) ? 0
+				    : (rnd(3) + 1) * ((rnd(3) < 2) ? 1 : -1);
+	cur->o_dplus = (rnd(4) < 3) ? 0
+				    : (rnd(3) + 1) * ((rnd(3) < 2) ? 1 : -1);
+	cur1->o_hplus = (rnd(4) < 3) ? 0
+				    : (rnd(3) + 1) * ((rnd(3) < 2) ? 1 : -1);
+	cur1->o_dplus = (rnd(4) < 3) ? 0
+				    : (rnd(3) + 1) * ((rnd(3) < 2) ? 1 : -1);
+	strcpy(cur->o_damage,"0d0");
+        strcpy(cur->o_hurldmg,"0d0");
+	strcpy(cur1->o_damage,"0d0");
+        strcpy(cur1->o_hurldmg,"0d0");
+	cur->o_ac = cur1->o_ac = 11;
+	cur->o_count = cur1->o_count = 1;
+	cur->o_group = cur1->o_group = 0;
+	cur->contents = cur1->contents = NULL;
+	if ((cur->o_hplus <= 0) && (cur->o_dplus <= 0)) cur->o_flags = ISCURSED;
+	if ((cur1->o_hplus <= 0) && (cur1->o_dplus <= 0))
+	    cur1->o_flags = ISCURSED;
+	cur->o_flags = cur1->o_flags = 0;
+	cur->o_type = cur1->o_type = WEAPON;
+	cur->o_mark[0] = cur1->o_mark[0] = '\0';
+
+	/* The monster may use a crossbow, sling, or an arrow */
+	i = rnd(100);
+	if (i < 10) {
+	    cur->o_which = CROSSBOW;
+	    cur1->o_which = BOLT;
+	    init_weapon(cur, CROSSBOW);
+	    init_weapon(cur1, BOLT);
+	}
+	else if (i < 70) {
+	    cur->o_which = BOW;
+	    cur1->o_which = ARROW;
+	    init_weapon(cur, BOW);
+	    init_weapon(cur1, ARROW);
+	}
+	else {
+	    cur->o_which = SLING;
+	    cur1->o_which = ROCK;
+	    init_weapon(cur, SLING);
+	    init_weapon(cur1, ROCK);
+	}
+
+	attach(tp->t_pack, item);
+	attach(tp->t_pack, item1);
+    }
+
+
+    if (ISWEARING(R_AGGR))
+	runto(tp, &hero);
+    if (on(*tp, ISDISGUISE))
+    {
+	char mch = 0;
+
+	if (tp->t_pack != NULL)
+	    mch = (OBJPTR(tp->t_pack))->o_type;
+	else
+	    switch (rnd(10)) {
+		case 0: mch = GOLD;
+		when 1: mch = POTION;
+		when 2: mch = SCROLL;
+		when 3: mch = FOOD;
+		when 4: mch = WEAPON;
+		when 5: mch = ARMOR;
+		when 6: mch = RING;
+		when 7: mch = STICK;
+		when 8: mch = monsters[randmonster(FALSE, FALSE)].m_appear;
+		when 9: mch = MM;
+	    }
+	tp->t_disguise = mch;
+    }
+}
+
+/*
+ * randmonster:
+ *	Pick a monster to show up.  The lower the level,
+ *	the meaner the monster.
+ */
+
+short
+randmonster(wander, no_unique)
+register bool wander, no_unique;
+{
+    register int d, cur_level, range, i; 
+
+    /* 
+     * Do we want a merchant? Merchant is always in place 'NUMMONST' 
+     */
+    if (wander && monsters[NUMMONST].m_wander && rnd(100) < 3) return NUMMONST;
+
+    cur_level = vlevel;
+    range = 4*NLEVMONS;
+    i = 0;
+    do
+    {
+	if (i++ > range*10) { /* just in case all have be genocided */
+	    i = 0;
+	    if (--cur_level <= 0)
+		fatal("Rogue could not find a monster to make");
+	}
+	d = NLEVMONS*(cur_level - 1) + (rnd(range) - (range - 1 - NLEVMONS));
+	if (d < 1)
+	    d = rnd(NLEVMONS) + 1;
+	if (d > NUMMONST - NUMUNIQUE - 1) {
+	    if (no_unique)
+		d = rnd(range) + (NUMMONST - NUMUNIQUE - 1) - (range - 1);
+	    else if (d > NUMMONST - 1)
+		d = rnd(range+NUMUNIQUE) + (NUMMONST-1) - (range+NUMUNIQUE-1);
+	}
+    }
+    while  (wander ? !monsters[d].m_wander || !monsters[d].m_normal 
+		   : !monsters[d].m_normal);
+    return d;
+}
+
+/* Sell displays a menu of goods from which the player may choose
+ * to purchase something.
+ */
+
+sell(tp)
+register struct thing *tp;
+{
+    register struct linked_list *item;
+    register struct object *obj;
+    register int i, j, min_worth, nitems, goods = 0, chance, which_item;
+    char buffer[LINELEN];
+    struct {
+	int which;
+	int plus1, plus2;
+	int count;
+	int worth;
+	char *name;
+    } selection[10];
+
+    min_worth = 100000;
+    item = find_mons(tp->t_pos.y, tp->t_pos.x); /* Get pointer to monster */
+
+    /* Select the items */
+    nitems = rnd(6) + 5;
+
+    for (i=0; i<nitems; i++) {
+	selection[i].worth = selection[i].plus1
+			   = selection[i].plus2
+			   = selection[i].which
+			   = selection[i].count
+			   = 0;
+    }
+    switch (rnd(9)) {
+	/* Armor */
+	case 0:
+	case 1:
+	    goods = ARMOR;
+	    for (i=0; i<nitems; i++) {
+		chance = rnd(100);
+		for (j = 0; j < MAXARMORS; j++)
+		    if (chance < armors[j].a_prob)
+			break;
+		if (j == MAXARMORS) {
+		    debug("Picked a bad armor %d", chance);
+		    j = 0;
+		}
+		selection[i].which = j;
+		selection[i].count = 1;
+		if (rnd(100) < 40) selection[i].plus1 = rnd(5) + 1;
+		else selection[i].plus1 = 0;
+		selection[i].name = armors[j].a_name;
+
+		/* Calculate price */
+		selection[i].worth = armors[j].a_worth;
+		selection[i].worth += 
+			2 * s_magic[S_ALLENCH].mi_worth * selection[i].plus1;
+		if (min_worth > selection[i].worth)
+		    min_worth = selection[i].worth;
+	    }
+	    break;
+
+	/* Weapon */
+	case 2:
+	case 3:
+	    goods = WEAPON;
+	    for (i=0; i<nitems; i++) {
+		selection[i].which = rnd(MAXWEAPONS);
+		selection[i].count = 1;
+		if (rnd(100) < 35) {
+		    selection[i].plus1 = rnd(3);
+		    selection[i].plus2 = rnd(3);
+		}
+		else {
+		    selection[i].plus1 = 0;
+		    selection[i].plus2 = 0;
+		}
+		if (weaps[selection[i].which].w_flags & ISMANY)
+		    selection[i].count = rnd(15) + 5;
+		selection[i].name = weaps[selection[i].which].w_name;
+		/*
+		 * note: use "count" before adding in the enchantment cost
+		 * 	 of an item. This will keep the price of arrows 
+		 * 	 and such to a reasonable price.
+		 */
+		j = selection[i].plus1 + selection[i].plus2;
+		selection[i].worth = weaps[selection[i].which].w_worth;
+		selection[i].worth *= selection[i].count;
+		selection[i].worth += 2 * s_magic[S_ALLENCH].mi_worth * j;
+		if (min_worth > selection[i].worth)
+		    min_worth = selection[i].worth;
+	    }
+	    break;
+
+	/* Staff or wand */
+	case 4:
+	    goods = STICK;
+	    for (i=0; i<nitems; i++) {
+		selection[i].which = pick_one(ws_magic, MAXSTICKS);
+		selection[i].plus1 = rnd(11) + 5;	/* Charges */
+		selection[i].count = 1;
+		selection[i].name = ws_magic[selection[i].which].mi_name;
+		selection[i].worth = ws_magic[selection[i].which].mi_worth;
+		selection[i].worth += 20 * selection[i].plus1;
+		if (min_worth > selection[i].worth)
+		    min_worth = selection[i].worth;
+	    }
+	    break;
+
+	/* Ring */
+	case 5:
+	    goods = RING;
+	    for (i=0; i<nitems; i++) {
+		selection[i].which = pick_one(r_magic, MAXRINGS);
+		selection[i].plus1 = rnd(2) + 1;  /* Armor class */
+		selection[i].count = 1;
+		if (rnd(100) < r_magic[selection[i].which].mi_bless + 10)
+		    selection[i].plus1 += rnd(2) + 1;
+		selection[i].name = r_magic[selection[i].which].mi_name;
+		selection[i].worth = r_magic[selection[i].which].mi_worth;
+
+		switch (selection[i].which) {
+		case R_DIGEST:
+		    if (selection[i].plus1 > 2) selection[i].plus1 = 2;
+		    else if (selection[i].plus1 < 1) selection[i].plus1 = 1;
+		/* fall thru here to other cases */
+		case R_ADDSTR:
+		case R_ADDDAM:
+		case R_PROTECT:
+		case R_ADDHIT:
+		case R_ADDINTEL:
+		case R_ADDWISDOM:
+		    if (selection[i].plus1 > 0)
+			selection[i].worth += selection[i].plus1 * 50;
+		}
+		if(min_worth > selection[i].worth)
+		    min_worth = selection[i].worth;
+	    }
+	    break;
+
+	/* scroll */
+	case 6:
+	    goods = SCROLL;
+	    for (i=0; i<nitems; i++) {
+		selection[i].which = pick_one(s_magic, MAXSCROLLS);
+		selection[i].count = 1;
+		selection[i].name = s_magic[selection[i].which].mi_name;
+		selection[i].worth = s_magic[selection[i].which].mi_worth;
+		if (min_worth > selection[i].worth)
+		    min_worth = selection[i].worth;
+	    }
+	    break;
+
+	/* potions */
+	case 7:
+	    goods = POTION;
+	    for (i=0; i<nitems; i++) {
+		selection[i].which = pick_one(p_magic, MAXPOTIONS);
+		selection[i].count = 1;
+		selection[i].name = p_magic[selection[i].which].mi_name;
+		selection[i].worth = p_magic[selection[i].which].mi_worth;
+		if (min_worth > selection[i].worth)
+		    min_worth = selection[i].worth;
+	    }
+	    break;
+
+	/* Miscellaneous magic */ 
+	case 8:
+	    goods = MM;
+	    for (i=0; i<nitems; i++) { /* don't sell as many mm as others */
+		selection[i].which = pick_one(m_magic, MAXMM);
+		selection[i].count = 1;
+		selection[i].name = m_magic[selection[i].which].mi_name;
+		selection[i].worth = m_magic[selection[i].which].mi_worth;
+
+		switch (selection[i].which) {
+		case MM_JUG:
+		    switch(rnd(9)) {
+			case 0: selection[i].plus1 = P_PHASE;
+			when 1: selection[i].plus1 = P_CLEAR;
+			when 2: selection[i].plus1 = P_SEEINVIS;
+			when 3: selection[i].plus1 = P_HEALING;
+			when 4: selection[i].plus1 = P_MFIND;
+			when 5: selection[i].plus1 = P_TFIND;
+			when 6: selection[i].plus1 = P_HASTE;
+			when 7: selection[i].plus1 = P_RESTORE;
+			when 8: selection[i].plus1 = P_FLY;
+		    }
+		when MM_OPEN:
+		case MM_HUNGER:
+		case MM_DRUMS:
+		case MM_DISAPPEAR:
+		case MM_CHOKE:
+		case MM_KEOGHTOM:
+		    selection[i].plus1  = 3 + (rnd(3)+1) * 3;
+		    selection[i].worth += selection[i].plus1 * 50;
+		when MM_BRACERS:
+		    selection[i].plus1  = rnd(10)+1;
+		    selection[i].worth += selection[i].plus1 * 75;
+		when MM_DISP:
+		    selection[i].plus1  = 2;
+		when MM_PROTECT:
+		    selection[i].plus1  = rnd(5)+1;
+		    selection[i].worth += selection[i].plus1 * 100;
+		when MM_SKILLS:
+		    selection[i].plus1 = player.t_ctype;
+		otherwise:
+		    break;
+		}
+		if(min_worth > selection[i].worth)
+		    min_worth = selection[i].worth;
+	    }
+	    break;
+    }
+
+    /* See if player can afford an item */
+    if (min_worth > purse) {
+	msg("The %s eyes your small purse and departs.",
+			monsters[NUMMONST].m_name);
+	/* Get rid of the monster */
+	killed(item, FALSE, FALSE);
+	return;
+    }
+
+    /* Display the goods */
+    msg("The %s shows you his wares.--More--", monsters[NUMMONST].m_name);
+    wait_for(cw,' ');
+    msg("");
+    clearok(cw, TRUE);
+    touchwin(cw);
+
+    wclear(hw);
+    touchwin(hw);
+    for (i=0; i < nitems; i++) {
+	mvwaddch(hw, i+2, 0, '[');
+	waddch(hw, (char) ((int) 'a' + i));
+	waddstr(hw, "] ");
+	switch (goods) {
+	    case ARMOR:
+		waddstr(hw, "Some ");
+	    when WEAPON:
+		if (selection[i].count == 1)
+		    waddstr(hw, " A ");
+		else {
+		    sprintf(buffer, "%2d ", selection[i].count);
+		    waddstr(hw, buffer);
+		}
+	    when STICK:
+		wprintw(hw, "A %-5s of ", ws_type[selection[i].which]);
+	    when RING:
+		waddstr(hw, "A ring of ");
+	    when SCROLL:
+		waddstr(hw, "A scroll of ");
+	    when POTION:
+		waddstr(hw, "A potion of ");
+	}
+	if (selection[i].count > 1)
+	    sprintf(buffer, "%s%s ", selection[i].name, "s");
+	else
+	    sprintf(buffer, "%s ", selection[i].name);
+	wprintw(hw, "%-24s", buffer);
+	wprintw(hw, " Price:%5d", selection[i].worth);
+    }
+    sprintf(buffer, "Purse:  %d", purse);
+    mvwaddstr(hw, nitems+3, 0, buffer);
+    mvwaddstr(hw, 0, 0, "How about one of the following goods? ");
+    draw(hw);
+    /* Get rid of the monster */
+    killed(item, FALSE, FALSE);
+
+    which_item = (int) (wgetch(hw) - 'a');
+    while (which_item < 0 || which_item >= nitems) {
+	if (which_item == (int) ESCAPE - (int) 'a') {
+	    return;
+	}
+	mvwaddstr(hw, 0, 0, "Please enter one of the listed items. ");
+	draw(hw);
+	which_item = (int) (wgetch(hw) - 'a');
+    }
+
+    if (selection[which_item].worth > purse) {
+	msg("You cannot afford it.");
+	return;
+    }
+
+    purse -= selection[which_item].worth;
+
+    item = spec_item(goods, selection[which_item].which,
+		     selection[which_item].plus1, selection[which_item].plus2);
+
+    obj = OBJPTR(item);
+    if (selection[which_item].count > 1) {
+	obj->o_count = selection[which_item].count;
+	obj->o_group = newgrp();
+    }
+    /* If a stick or ring, let player know the type */
+    switch (goods) {
+	case RING:  r_know[selection[which_item].which] = TRUE;
+	when POTION:p_know[selection[which_item].which] = TRUE;
+	when SCROLL:s_know[selection[which_item].which] = TRUE;
+	when STICK: ws_know[selection[which_item].which] = TRUE;
+	when MM:    m_know[selection[which_item].which] = TRUE;
+
+    }
+
+    if (add_pack(item, FALSE, NULL) == FALSE) {
+
+	obj->o_pos = hero;
+	fall(item, TRUE);
+    }
+}
+
+
+
+/*
+ * what to do when the hero steps next to a monster
+ */
+struct linked_list *
+wake_monster(y, x)
+int y, x;
+{
+    register struct thing *tp;
+    register struct linked_list *it;
+    register struct room *trp;
+    register const char *mname;
+    bool nasty;	/* Will the monster "attack"? */
+    char ch;
+
+    if ((it = find_mons(y, x)) == NULL) {
+	msg("Can't find monster in show");
+	return (NULL);
+    }
+    tp = THINGPTR(it);
+    ch = tp->t_type;
+
+    trp = roomin(&tp->t_pos); /* Current room for monster */
+    mname = monsters[tp->t_index].m_name;
+
+    /*
+     * Let greedy ones in a room guard gold
+     * (except in a maze where lots of creatures would all go for the 
+     * same piece of gold)
+     */
+    if (on(*tp, ISGREED)	&& off(*tp, ISRUN)	&& 
+	levtype != MAZELEV	&& trp != NULL		&&
+	lvl_obj != NULL) {
+	    register struct linked_list *item;
+	    register struct object *cur;
+
+	    for (item = lvl_obj; item != NULL; item = next(item)) {
+		cur = OBJPTR(item);
+		if ((cur->o_type == GOLD) &&
+		    (roomin(&cur->o_pos) == trp)) {
+		    /* Run to the gold */
+		    tp->t_dest = &cur->o_pos;
+		    turn_on(*tp, ISRUN);
+		    turn_off(*tp, ISDISGUISE);
+
+		    /* Make it worth protecting */
+		    cur->o_count += GOLDCALC + GOLDCALC;
+		    break;
+		}
+	    }
+    }
+
+    /*
+     * Every time he sees mean monster, it might start chasing him
+     */
+    if (on(*tp, ISMEAN)							&& 
+	off(*tp, ISHELD)						&& 
+	off(*tp, ISRUN)							&& 
+	rnd(100) > 33							&& 
+	(!is_stealth(&player) || (on(*tp, ISUNIQUE) && rnd(100) > 95))	&&
+	(off(player, ISINVIS) || on(*tp, CANSEE))			||
+	(trp != NULL && (trp->r_flags & ISTREAS))) {
+	tp->t_dest = &hero;
+	turn_on(*tp, ISRUN);
+	turn_off(*tp, ISDISGUISE);
+    }
+
+    /* See if the monster will bother the player */
+    nasty = (on(*tp, ISRUN) && cansee(tp->t_pos.y, tp->t_pos.x));
+
+    /*
+     * Let the creature summon if it can.
+     * Also check to see if there is room around the player,
+     * if not then the creature will wait
+     */
+    if (on(*tp, CANSUMMON) && nasty		&& 
+	rnd(40) < tp->t_stats.s_lvl		&&
+	fallpos(&hero, FALSE, 2) != NULL) {
+	const char *helpname;
+	int fail;
+	register int which, i;
+
+	turn_off(*tp, CANSUMMON);
+	helpname = monsters[tp->t_index].m_typesum;
+	for (which=1; which<NUMMONST; which++) {
+	     if (strcmp(helpname, monsters[which].m_name) == 0)
+		 break;
+	}
+	if (which >= NUMMONST)
+	     debug("couldn't find summoned one");
+	if ((off(*tp, ISINVIS)     || on(player, CANSEE)) &&
+	    (off(*tp, ISSHADOW)    || on(player, CANSEE)) &&
+	    (off(*tp, CANSURPRISE) || ISWEARING(R_ALERT))) {
+	    if (monsters[which].m_normal == FALSE) { /* genocided? */
+		msg("The %s appears dismayed", mname);
+		monsters[tp->t_index].m_numsum = 0;
+	    }
+	    else {
+		sprintf(outstring,"The %s summons %ss for help", mname, helpname);
+		msg(outstring);
+	    }
+	}
+	else {
+	    if (monsters[which].m_normal == FALSE) /* genocided? */
+		monsters[tp->t_index].m_numsum = 0;
+	    else
+		msg("%ss seem to appear from nowhere!", helpname);
+	}
+	/*
+	 * try to make all the creatures around player but remember
+	 * if unsuccessful
+	 */
+	for (i=0, fail=0; i<monsters[tp->t_index].m_numsum; i++) {
+	     if (!creat_mons(&player, which, FALSE))
+		 fail++;	/* remember the failures */
+	}
+	/*
+	 * try once again to make the buggers
+	 */
+	for (i=0; i<fail; i++)
+	     creat_mons(tp, which, FALSE);
+	
+	/* Now let the poor fellow see all the trouble */
+	light(&hero);
+    }
+
+    /* 
+     * Handle monsters that can gaze and do things while running
+     * Player must be able to see the monster and the monster must 
+     * not be asleep 
+     */
+    if (nasty && !invisible(tp)) {
+	/*
+	 * Confusion
+	 */
+	if (on(*tp, CANHUH)				 &&
+	   (off(*tp, ISINVIS)     || on(player, CANSEE)) &&
+	   (off(*tp, CANSURPRISE) || ISWEARING(R_ALERT))) {
+	    if (!save(VS_MAGIC, &player, 0)) {
+		if (off(player, ISCLEAR)) {
+		    if (find_slot(unconfuse))
+			lengthen(unconfuse, rnd(20)+HUHDURATION);
+		    else {
+			fuse(unconfuse, 0, rnd(20)+HUHDURATION, AFTER);
+			msg("The %s's gaze has confused you.",mname);
+			turn_on(player, ISHUH);
+		    }
+		}
+		else msg("You feel dizzy for a moment, but it quickly passes.");
+	    }
+	    else if (rnd(100) < 67)
+		turn_off(*tp, CANHUH); /* Once you save, maybe that's it */
+	}
+
+	/* Sleep */
+	if(on(*tp, CANSNORE) &&  
+	   no_command == 0 && 
+	   !save(VS_PARALYZATION, &player, 0)) {
+	    if (ISWEARING(R_ALERT))
+		msg("You feel slightly drowsy for a moment.");
+	    else {
+		msg("The %s's gaze puts you to sleep.", mname);
+		no_command += SLEEPTIME;
+		if (rnd(100) < 50) turn_off(*tp, CANSNORE);
+	    }
+	}
+
+	/* Fear */
+	if (on(*tp, CANFRIGHTEN)) {
+	    turn_off(*tp, CANFRIGHTEN);
+	    if (!ISWEARING(R_HEROISM)		&&
+		!save(VS_WAND, &player, 0)	&&
+	        !(on(player, ISFLEE) && (player.t_dest == &tp->t_pos))) {
+		    turn_on(player, ISFLEE);
+		    player.t_dest = &tp->t_pos;
+		    msg("The sight of the %s terrifies you.", mname);
+	    }
+	}
+
+	/* blinding creatures */
+	if(on(*tp, CANBLIND) && 
+	   !find_slot(sight) && 
+	   !save(VS_WAND,&player, 0)){
+	    msg("The gaze of the %s blinds you", mname);
+	    turn_on(player, ISBLIND);
+	    fuse(sight, 0, rnd(30)+20, AFTER);
+	    light(&hero);
+	}
+
+	/* the sight of the ghost can age you! */
+	if (on(*tp, CANAGE)) { 
+	    turn_off (*tp, CANAGE);
+	    if (!save(VS_MAGIC, &player, 0)) {
+		msg ("The sight of the %s ages you!", mname);
+		pstats.s_const--;
+		max_stats.s_const--;
+		if (pstats.s_const < 0)
+		    death (D_CONSTITUTION);
+	    }
+	}
+
+
+	/* Turning to stone */
+	if (on(*tp, LOOKSTONE)) {
+	    turn_off(*tp, LOOKSTONE);
+
+	    if (on(player, CANINWALL))
+		msg("The gaze of the %s has no effect.", mname);
+	    else {
+		if (!save(VS_PETRIFICATION, &player, 0) && rnd(100) < 15) {
+		    pstats.s_hpt = -1;
+		    msg("The gaze of the %s petrifies you.", mname);
+		    msg("You are turned to stone !!! --More--");
+		    wait_for(cw,' ');
+		    death(D_PETRIFY);
+		}
+		else {
+		    msg("The gaze of the %s stiffens your limbs.", mname);
+		    no_command += STONETIME;
+		}
+	    }
+	}
+    }
+
+    return it;
+}
+/*
+ * wanderer:
+ *	A wandering monster has awakened and is headed for the player
+ */
+
+wanderer()
+{
+    register int i;
+    register struct room *hr = roomin(&hero);
+    register struct linked_list *item;
+    register struct thing *tp;
+    register const long *attr;	/* Points to monsters' attributes */
+    int carry;	/* Chance of wanderer carrying anything */
+    short rmonst;	/* Our random wanderer */
+    bool canteleport = FALSE,	/* Can the monster teleport? */
+	 seehim;	/* Is monster within sight? */
+    coord cp;
+
+    rmonst = randmonster(TRUE, FALSE);	/* Choose a random wanderer */
+    attr = &monsters[rmonst].m_flags[0]; /* Start of attributes */
+    for (i=0; i<MAXFLAGS; i++)
+	if (*attr++ == CANTELEPORT) {
+	    canteleport = TRUE;
+	    break;
+	}
+
+    /* Find a place for it -- avoid the player's room if can't teleport */
+    do {
+	do {
+	    i = rnd_room();
+	} until (canteleport || hr != &rooms[i] || levtype == MAZELEV ||
+		 levtype == OUTSIDE || levtype == POSTLEV);
+
+	/* Make sure the monster does not teleport on top of the player */
+	do {
+	    rnd_pos(&rooms[i], &cp);
+	} while (hr == &rooms[i] && ce(cp, hero));
+    } until (step_ok(cp.y, cp.x, NOMONST, NULL));
+
+    /* Create a new wandering monster */
+    item = new_item(sizeof *tp);
+    new_monster(item, rmonst, &cp, FALSE);
+    tp = THINGPTR(item);
+    turn_on(*tp, ISRUN);
+    turn_off(*tp, ISDISGUISE);
+    tp->t_dest = &hero;
+    tp->t_pos = cp;	/* Assign the position to the monster */
+    seehim = cansee(tp->t_pos.y, tp->t_pos.x);
+    if (on(*tp, HASFIRE)) {
+	register struct room *rp;
+
+	rp = roomin(&tp->t_pos);
+	if (rp) {
+	    register struct linked_list *fire_item;
+
+	    fire_item = creat_item();
+	    ldata(fire_item) = (char *) tp;
+	    attach(rp->r_fires, fire_item);
+
+	    rp->r_flags |= HASFIRE;
+	    if (seehim && next(rp->r_fires) == NULL)
+		light(&hero);
+	}
+    }
+
+    /* See if we give the monster anything */
+    carry = monsters[tp->t_index].m_carry;
+    if (off(*tp, ISUNIQUE)) carry /= 2;	/* Non-unique has only a half chance */
+    carry_obj(tp, carry);
+
+    /* Alert the player if a monster just teleported in */
+    if (hr == &rooms[i] && canteleport && seehim && !invisible(tp)) {
+	msg("A %s just teleported in", monsters[rmonst].m_name);
+	light(&hero);
+	running = FALSE;
+    }
+
+    if (wizard)
+	msg("Started a wandering %s", monsters[tp->t_index].m_name);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/move.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,1386 @@
+/*
+ * Hero movement commands
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Super-Rogue"
+ * Copyright (C) 1984 Robert D. Kindelberger
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include <ctype.h>
+#include "rogue.h"
+
+/*
+ * Used to hold the new hero position
+ */
+
+static coord nh;
+
+static const char Moves[3][3] = {
+    { 'y', 'k', 'u' },
+    { 'h', '\0', 'l' },
+    { 'b', 'j', 'n' }
+};
+
+/*
+ * be_trapped:
+ *	The guy stepped on a trap.... Make him pay.
+ */
+
+be_trapped(th, tc)
+register struct thing *th;
+register coord *tc;
+{
+    register struct trap *tp;
+    register char ch;
+    register const char *mname = NULL;
+    register bool is_player = (th == &player),
+	          can_see;
+    register struct linked_list *mitem = NULL;
+
+
+    /* Can the player see the creature? */
+    can_see = (cansee(tc->y, tc->x) && (is_player || !invisible(th)));
+
+    tp = trap_at(tc->y, tc->x);
+    /*
+     * if he's wearing boots of elvenkind, he won't set off the trap
+     * unless its a magic pool (they're not really traps)
+     */
+    if (is_player					&&
+	cur_misc[WEAR_BOOTS] != NULL			&&
+	cur_misc[WEAR_BOOTS]->o_which == MM_ELF_BOOTS	&&
+	tp->tr_type != POOL)
+	    return '\0';
+
+    /*
+     * if the creature is flying then it won't set off the trap
+     */
+     if (on(*th, ISFLY))
+	return '\0';
+
+    tp->tr_flags |= ISFOUND;
+
+    if (!is_player) {
+	mitem = find_mons(th->t_pos.y, th->t_pos.x);
+	mname = monsters[th->t_index].m_name;
+    }
+    else {
+	count = running = FALSE;
+	mvwaddch(cw, tp->tr_pos.y, tp->tr_pos.x, tp->tr_type);
+    }
+    switch (ch = tp->tr_type) {
+	case TRAPDOOR:
+	    if (is_player) {
+		level++;
+		pstats.s_hpt -= roll(1, 10);
+		msg("You fell into a trap!");
+		if (pstats.s_hpt <= 0) death(D_FALL);
+		new_level(NORMLEV);
+	    }
+	    else {
+		if (can_see) msg("The %s fell into a trap!", mname);
+
+		/* See if the fall killed the monster */
+		if ((th->t_stats.s_hpt -= roll(1, 10)) <= 0) {
+		    killed(mitem, FALSE, FALSE);
+		}
+		else {	/* Just move monster to next level */
+		    check_residue(th);
+
+		    /* Erase the monster from the old position */
+		    if (isalpha(mvwinch(cw, th->t_pos.y, th->t_pos.x)))
+			mvwaddch(cw, th->t_pos.y, th->t_pos.x, th->t_oldch);
+		    mvwaddch(mw, th->t_pos.y, th->t_pos.x, ' ');
+		    turn_on(*th, ISELSEWHERE);
+		    detach(mlist, mitem);
+		    attach(tlist, mitem);	/* remember him next level */
+		}
+	    }
+	when BEARTRAP:
+	    if (is_stealth(th)) {
+		if (is_player) msg("You pass a bear trap.");
+		else if (can_see) msg("The %s passes a bear trap.", mname);
+	    }
+	    else {
+		th->t_no_move += BEARTIME;
+		if (is_player) msg("You are caught in a bear trap.");
+		else if (can_see) msg("The %s is caught in a bear trap.",
+					mname);
+	    }
+	when SLEEPTRAP:
+	    if (is_player) {
+		msg("A strange white mist envelops you.");
+		if (!ISWEARING(R_ALERT)) {
+		    msg("You fall asleep.");
+		    no_command += SLEEPTIME;
+		}
+	    }
+	    else {
+		if (can_see) 
+		    msg("A strange white mist envelops the %s.",mname);
+		if (on(*th, ISUNDEAD)) {
+		    if (can_see) 
+			msg("The mist doesn't seem to affect the %s.",mname);
+		}
+		else {
+		    th->t_no_move += SLEEPTIME;
+		}
+	    }
+	when ARROWTRAP:
+	    if (swing(th->t_ctype, th->t_stats.s_lvl-1, th->t_stats.s_arm, 1))
+	    {
+		if (is_player) {
+		    msg("Oh no! An arrow shot you.");
+		    if ((pstats.s_hpt -= roll(1, 6)) <= 0) {
+			msg("The arrow killed you.");
+			death(D_ARROW);
+		    }
+		}
+		else {
+		    if (can_see) msg("An arrow shot the %s.", mname);
+		    if ((th->t_stats.s_hpt -= roll(1, 6)) <= 0) {
+			if (can_see) msg("The arrow killed the %s.", mname);
+			killed(mitem, FALSE, FALSE);
+		    }
+		}
+	    }
+	    else
+	    {
+		register struct linked_list *item;
+		register struct object *arrow;
+
+		if (is_player) msg("An arrow shoots past you.");
+		else if (can_see) msg("An arrow shoots by the %s.", mname);
+		item = new_item(sizeof *arrow);
+		arrow = OBJPTR(item);
+		arrow->o_type = WEAPON;
+		arrow->contents = NULL;
+		arrow->o_which = ARROW;
+		arrow->o_hplus = rnd(3) - 1;
+		arrow->o_dplus = rnd(3) - 1;
+		init_weapon(arrow, ARROW);
+		arrow->o_count = 1;
+		arrow->o_pos = *tc;
+		arrow->o_mark[0] = '\0';
+		fall(item, FALSE);
+	    }
+	when TELTRAP:
+	    if (is_player) teleport();
+	    else {
+		register int rm;
+	        struct room *old_room;	/* old room of monster */
+
+		/* 
+		 * Erase the monster from the old position 
+		 */
+		if (isalpha(mvwinch(cw, th->t_pos.y, th->t_pos.x)))
+		    mvwaddch(cw, th->t_pos.y, th->t_pos.x, th->t_oldch);
+		mvwaddch(mw, th->t_pos.y, th->t_pos.x, ' ');
+		/*
+		 * check to see if room should go dark
+		 */
+		if (on(*th, HASFIRE)) {
+		    old_room=roomin(&th->t_pos);
+		    if (old_room != NULL) {
+			register struct linked_list *fire_item;
+
+			for (fire_item = old_room->r_fires; fire_item != NULL;
+			     fire_item = next(fire_item)) {
+			    if (THINGPTR(fire_item) == th) {
+				detach(old_room->r_fires, fire_item);
+				destroy_item(fire_item);
+
+				if (old_room->r_fires == NULL) {
+				    old_room->r_flags &= ~HASFIRE;
+				    if (can_see) light(&hero);
+				}
+			    }
+			}
+		    }
+		}
+
+		/* Get a new position */
+		do {
+		    rm = rnd_room();
+		    rnd_pos(&rooms[rm], &th->t_pos);
+		} until(winat(th->t_pos.y, th->t_pos.x) == FLOOR);
+
+		/* Put it there */
+		mvwaddch(mw, th->t_pos.y, th->t_pos.x, th->t_type);
+		th->t_oldch = CCHAR( mvwinch(cw, th->t_pos.y, th->t_pos.x) );
+		/*
+		 * check to see if room that creature appears in should
+		 * light up
+		 */
+	        if (on(*th, HASFIRE)) {
+		    register struct linked_list *fire_item;
+
+		    fire_item = creat_item();
+		    ldata(fire_item) = (char *) th;
+		    attach(rooms[rm].r_fires, fire_item);
+
+		    rooms[rm].r_flags |= HASFIRE;
+		    if(cansee(th->t_pos.y, th->t_pos.x) && 
+		       next(rooms[rm].r_fires) == NULL)
+			light(&hero);
+		}
+		if (can_see) msg("The %s seems to have disappeared!", mname);
+	    }
+	when DARTTRAP:
+	    if (swing(th->t_ctype, th->t_stats.s_lvl+1, th->t_stats.s_arm, 1)) {
+		if (is_player) {
+		    msg("A small dart just hit you in the shoulder.");
+		    if ((pstats.s_hpt -= roll(1, 4)) <= 0) {
+			msg("The dart killed you.");
+			death(D_DART);
+		    }
+
+		    /* Now the poison */
+		    if (!save(VS_POISON, &player, 0)) {
+			/* 75% chance it will do point damage - else strength */
+			if (rnd(100) < 75) {
+			    pstats.s_hpt /= 2;
+			    if (pstats.s_hpt == 0) death(D_POISON);
+			}
+			else if (!ISWEARING(R_SUSABILITY))
+				chg_str(-1);
+		    }
+		}
+		else {
+		    if (can_see)
+			msg("A small dart just hit the %s in the shoulder.",
+				mname);
+		    if ((th->t_stats.s_hpt -= roll(1,4)) <= 0) {
+			if (can_see) msg("The dart killed the %s.", mname);
+			killed(mitem, FALSE, FALSE);
+		    }
+		    if (!save(VS_POISON, th, 0)) {
+			th->t_stats.s_hpt /= 2;
+			if (th->t_stats.s_hpt <= 0) {
+			    if (can_see) msg("The dart killed the %s.", mname);
+			    killed(mitem, FALSE, FALSE);
+			}
+		    }
+		}
+	    }
+	    else {
+		if (is_player)
+		    msg("A small dart whizzes by your ear and vanishes.");
+		else if (can_see)
+		    msg("A small dart whizzes by the %s's ear and vanishes.",
+			mname);
+	    }
+        when POOL: {
+	    register int i;
+
+	    i = rnd(100);
+	    if (is_player) {
+		if ((tp->tr_flags & ISGONE)) {
+		    if (i < 30) {
+			teleport();	   /* teleport away */
+			pool_teleport = TRUE;
+		    }
+		    else if((i < 45) && level > 2) {
+			level -= rnd(2) + 1;
+			cur_max = level;
+			new_level(NORMLEV);
+			pool_teleport = TRUE;
+			msg("You here a faint groan from below.");
+		    }
+		    else if(i < 70) {
+			level += rnd(4) + 1;
+			new_level(NORMLEV);
+			pool_teleport = TRUE;
+			msg("You find yourself in strange surroundings.");
+		    }
+		    else if(i > 95) {
+			msg("Oh no!!! You drown in the pool!!! --More--");
+			wait_for(cw,' ');
+			death(D_DROWN);
+		    }
+		}
+	    }
+	    else {
+		if (i < 60) {
+		    if (can_see) {
+			/* Drowns */
+			if (i < 30) msg("The %s drowned in the pool!", mname);
+
+			/* Teleported to another level */
+			else msg("The %s disappeared!", mname);
+		    }
+		    killed(mitem, FALSE, FALSE);
+		}
+	    }
+	}
+    when MAZETRAP:
+	if (is_player) {
+	    pstats.s_hpt -= roll(1, 10);
+	    level++;
+	    msg("You fell through a trap door!");
+	    if (pstats.s_hpt <= 0) death(D_FALL);
+	    new_level(MAZELEV);
+	    msg("You are surrounded by twisty passages!");
+	}
+	else {
+	    if (can_see) msg("The %s fell into a trap!", mname);
+	    killed(mitem, FALSE, FALSE);
+	}
+    }
+
+    /* Move the cursor back onto the hero */
+    wmove(cw, hero.y, hero.x);
+
+    md_flushinp(); /* flush typeahead */
+
+    return(ch);
+}
+
+/*
+ * blue_light:
+ *	magically light up a room (or level or make it dark)
+ */
+
+bool
+blue_light(blessed, cursed)
+bool blessed, cursed;
+{
+    register struct room *rp;
+    bool ret_val=FALSE;	/* Whether or not affect is known */
+
+    rp = roomin(&hero);	/* What room is hero in? */
+
+    /* Darken the room if the magic is cursed */
+    if (cursed) {
+	if ((rp == NULL) || !lit_room(rp)) msg(nothing);
+	else {
+	    rp->r_flags |= ISDARK;
+	    if (!lit_room(rp) && (levtype != OUTSIDE || !daytime))
+		msg("The %s suddenly goes dark.",
+			levtype == OUTSIDE ? "area" : "room");
+	    else msg(nothing);
+	    ret_val = TRUE;
+	}
+    }
+    else {
+	ret_val = TRUE;
+	if (rp && !lit_room(rp) &&
+	    (levtype != OUTSIDE || !daytime)) {
+	    addmsg("The %s is lit", levtype == OUTSIDE ? "area" : "room");
+	    if (!terse)
+		addmsg(" by a %s blue light.",
+		    blessed ? "bright" : "shimmering");
+	    endmsg();
+	}
+	else if (winat(hero.y, hero.x) == PASSAGE)
+	    msg("The corridor glows %sand then fades",
+		    blessed ? "brightly " : "");
+	else {
+	    ret_val = FALSE;
+	    msg(nothing);
+	}
+	if (blessed) {
+	    register int i;	/* Index through rooms */
+
+	    for (i=0; i<MAXROOMS; i++)
+		rooms[i].r_flags &= ~ISDARK;
+	}
+	else if (rp) rp->r_flags &= ~ISDARK;
+    }
+
+    /*
+     * Light the room and put the player back up
+     */
+    light(&hero);
+    mvwaddch(cw, hero.y, hero.x, PLAYER);
+    return(ret_val);
+}
+
+/*
+ * corr_move:
+ *	Check to see that a move is legal.  If so, return correct character.
+ * 	If not, if player came from a legal place, then try to turn him.
+ */
+
+corr_move(dy, dx)
+int dy, dx;
+{
+    int legal=0;		/* Number of legal alternatives */
+    register int y, x,		/* Indexes though possible positions */
+		 locy = 0, locx = 0;	/* Hold delta of chosen location */
+
+    /* New position */
+    nh.y = hero.y + dy;
+    nh.x = hero.x + dx;
+
+    /* If it is a legal move, just return */
+    if (nh.x >= 0 && nh.x < COLS && nh.y > 0 && nh.y < LINES - 2) {
+        
+	switch (winat(nh.y, nh.x)) {
+	    case WALL:
+	    case '|':
+	    case '-':
+		break;
+	    default:
+		if (diag_ok(&hero, &nh, &player))
+			return;
+	}
+    }
+
+    /* Check legal places surrounding the player -- ignore previous position */
+    for (y = hero.y - 1; y <= hero.y + 1; y++) {
+	if (y < 1 || y > LINES - 3)
+	    continue;
+	for (x = hero.x - 1; x <= hero.x + 1; x++) {
+	    /* Ignore borders of the screen */
+	    if (x < 0 || x > COLS - 1)
+		continue;
+	    
+	    /* 
+	     * Ignore where we came from, where we are, and where we couldn't go
+	     */
+	    if ((x == hero.x - dx && y == hero.y - dy) ||
+		(x == hero.x + dx && y == hero.y + dy) ||
+		(x == hero.x && y == hero.y))
+		continue;
+
+	    switch (winat(y, x)) {
+		case WALL:
+		case '|':
+		case '-':
+		    break;
+		default:
+		    nh.y = y;
+		    nh.x = x;
+		    if (diag_ok(&hero, &nh, &player)) {
+			legal++;
+			locy = y - (hero.y - 1);
+			locx = x - (hero.x - 1);
+		    }
+	    }
+	}
+    }
+
+    /* If we have 2 or more legal moves, make no change */
+    if (legal != 1) {
+	return;
+    }
+
+    runch = Moves[locy][locx];
+
+    /*
+     * For mazes, pretend like it is the beginning of a new run at each turn
+     * in order to get the lighting correct.
+     */
+    if (levtype == MAZELEV) firstmove = TRUE;
+    return;
+}
+
+/*
+ * dip_it:
+ *	Dip an object into a magic pool
+ */
+dip_it()
+{
+	reg struct linked_list *what;
+	reg struct object *ob;
+	reg struct trap *tp;
+	reg int wh, i;
+
+	tp = trap_at(hero.y,hero.x);
+	if (tp == NULL || tp->tr_type != POOL) {
+	    msg("I see no shimmering pool here");
+	    return;
+	}
+	if (tp->tr_flags & ISGONE) {
+	    msg("This shimmering pool appears to have used once already");
+	    return;
+	}
+	if ((what = get_item(pack, "dip", ALL)) == NULL) {
+	    msg("");
+	    after = FALSE;
+	    return;
+	}
+	ob = OBJPTR(what);
+	mpos = 0;
+	if (ob == cur_armor		 || 
+	    ob == cur_misc[WEAR_BOOTS]	 || ob == cur_misc[WEAR_JEWEL]	 ||
+	    ob == cur_misc[WEAR_GAUNTLET]|| ob == cur_misc[WEAR_CLOAK]	 ||
+	    ob == cur_misc[WEAR_BRACERS] || ob == cur_misc[WEAR_NECKLACE]||
+	    ob == cur_ring[LEFT_1]	 || ob == cur_ring[LEFT_2]	 ||
+	    ob == cur_ring[LEFT_3]	 || ob == cur_ring[LEFT_4]	 ||
+	    ob == cur_ring[RIGHT_1]	 || ob == cur_ring[RIGHT_2]	 ||
+	    ob == cur_ring[RIGHT_3]	 || ob == cur_ring[RIGHT_4]) {
+	    msg("You'll have to take it off first.");
+	    return;
+	}
+	tp->tr_flags |= ISGONE;
+	if (ob != NULL) {
+	    wh = ob->o_which;
+	    ob->o_flags |= ISKNOW;
+	    i = rnd(100);
+	    switch(ob->o_type) {
+		case WEAPON:
+		    if(i < 50) {		/* enchant weapon here */
+			if ((ob->o_flags & ISCURSED) == 0) {
+				ob->o_hplus += 1;
+				ob->o_dplus += 1;
+			}
+			else {		/* weapon was prev cursed here */
+				ob->o_hplus = rnd(2);
+				ob->o_dplus = rnd(2);
+			}
+			ob->o_flags &= ~ISCURSED;
+		        msg("The %s glows blue for a moment.",weaps[wh].w_name);
+		    }
+		    else if(i < 70) {	/* curse weapon here */
+			if ((ob->o_flags & ISCURSED) == 0) {
+				ob->o_hplus = -(rnd(2)+1);
+				ob->o_dplus = -(rnd(2)+1);
+			}
+			else {			/* if already cursed */
+				ob->o_hplus--;
+				ob->o_dplus--;
+			}
+			ob->o_flags |= ISCURSED;
+		        msg("The %s glows red for a moment.",weaps[wh].w_name);
+		    }			
+		    else
+			msg(nothing);
+		when ARMOR:
+		    if (i < 50) {	/* enchant armor */
+			if((ob->o_flags & ISCURSED) == 0)
+			    ob->o_ac -= rnd(2) + 1;
+			else
+			    ob->o_ac = -rnd(3)+ armors[wh].a_class;
+			ob->o_flags &= ~ISCURSED;
+		        msg("The %s glows blue for a moment",armors[wh].a_name);
+		    }
+		    else if(i < 75){	/* curse armor */
+			if ((ob->o_flags & ISCURSED) == 0)
+			    ob->o_ac = rnd(3)+ armors[wh].a_class;
+			else
+			    ob->o_ac += rnd(2) + 1;
+			ob->o_flags |= ISCURSED;
+		        msg("The %s glows red for a moment.",armors[wh].a_name);
+		    }
+		    else
+			msg(nothing);
+		when STICK: {
+		    int j;
+		    j = rnd(8) + 1;
+		    if(i < 50) {		/* add charges */
+			ob->o_charges += j;
+		        ws_know[wh] = TRUE;
+			if (ob->o_flags & ISCURSED)
+			    ob->o_flags &= ~ISCURSED;
+		        sprintf(outstring,"The %s %s glows blue for a moment.",
+			    ws_made[wh],ws_type[wh]);
+			msg(outstring);
+		    }
+		    else if(i < 65) {	/* remove charges */
+			if ((ob->o_charges -= i) < 0)
+			    ob->o_charges = 0;
+		        ws_know[wh] = TRUE;
+			if (ob->o_flags & ISBLESSED)
+			    ob->o_flags &= ~ISBLESSED;
+			else
+			    ob->o_flags |= ISCURSED;
+		        sprintf(outstring,"The %s %s glows red for a moment.",
+			    ws_made[wh],ws_type[wh]);
+			msg(outstring);
+		    }
+		    else 
+			msg(nothing);
+		}
+		when SCROLL:
+		    s_know[wh] = TRUE;
+		    msg("The '%s' scroll unfurls.",s_names[wh]);
+		when POTION:
+		    p_know[wh] = TRUE;
+		    msg("The %s potion bubbles for a moment.",p_colors[wh]);
+		when RING:
+		    if(i < 50) {	 /* enchant ring */
+			if ((ob->o_flags & ISCURSED) == 0)
+			    ob->o_ac += rnd(2) + 1;
+			else
+			    ob->o_ac = rnd(2) + 1;
+			ob->o_flags &= ~ISCURSED;
+		    }
+		    else if(i < 80) { /* curse ring */
+			if ((ob->o_flags & ISCURSED) == 0)
+			    ob->o_ac = -(rnd(2) + 1);
+			else
+			    ob->o_ac -= (rnd(2) + 1);
+			ob->o_flags |= ISCURSED;
+		    }
+		    r_know[wh] = TRUE;
+		    msg("The %s ring vibrates for a moment.",r_stones[wh]);
+		when MM:
+		    m_know[wh] = TRUE;
+		    switch (ob->o_which) {
+		    case MM_BRACERS:
+		    case MM_PROTECT:
+			if(i < 50) {	 /* enchant item */
+			    if ((ob->o_flags & ISCURSED) == 0)
+				ob->o_ac += rnd(2) + 1;
+			    else
+				ob->o_ac = rnd(2) + 1;
+			    ob->o_flags &= ~ISCURSED;
+			}
+			else if(i < 80) { /* curse item */
+			    if ((ob->o_flags & ISCURSED) == 0)
+				ob->o_ac = -(rnd(2) + 1);
+			    else
+				ob->o_ac -= (rnd(2) + 1);
+			    ob->o_flags |= ISCURSED;
+			}
+			msg("The item vibrates for a moment.");
+		    when MM_CHOKE:
+		    case MM_DISAPPEAR:
+			ob->o_ac = 0;
+			msg ("The dust dissolves in the pool!");
+		    }
+		otherwise:
+		msg("The pool bubbles for a moment.");
+	    }
+	    updpack(FALSE);
+	}
+	else
+	    msg(nothing);
+}
+
+/*
+ * do_move:
+ *	Check to see that a move is legal.  If it is handle the
+ * consequences (fighting, picking up, etc.)
+ */
+
+do_move(dy, dx)
+int dy, dx;
+{
+    register struct room *rp, *orp;
+    register char ch;
+    coord old_hero;
+    int i, wasfirstmove;
+
+    wasfirstmove = firstmove;
+    firstmove = FALSE;
+    curprice = -1;		/* if in trading post, we've moved off obj */
+    if (player.t_no_move) {
+	player.t_no_move--;
+	msg("You are still stuck in the bear trap");
+	return;
+    }
+    /*
+     * Do a confused move (maybe)
+     */
+    if ((on(player, ISHUH) && rnd(100) < 80) || 
+	(on(player, ISDANCE) && rnd(100) < 80) || 
+	(ISWEARING(R_DELUSION) && rnd(100) < 25))
+	nh = *rndmove(&player);
+    else {
+	nh.y = hero.y + dy;
+	nh.x = hero.x + dx;
+    }
+
+    /*
+     * Check if he tried to move off the screen or make an illegal
+     * diagonal move, and stop him if he did.
+     */
+    if (nh.x < 0 || nh.x > COLS-1 || nh.y < 1 || nh.y >= LINES - 2
+	|| !diag_ok(&hero, &nh, &player))
+    {
+	after = running = FALSE;
+	return;
+    }
+    if (running && ce(hero, nh))
+	after = running = FALSE;
+    ch = CCHAR( winat(nh.y, nh.x) );
+
+    /* Take care of hero trying to move close to something frightening */
+    if (on(player, ISFLEE)) {
+	if (rnd(100) < 10) {
+	    turn_off(player, ISFLEE);
+	    msg("You regain your composure.");
+	}
+	else if (DISTANCE(nh.y, nh.x, player.t_dest->y, player.t_dest->x) <
+		 DISTANCE(hero.y, hero.x, player.t_dest->y, player.t_dest->x))
+			return;
+    }
+
+    /* Take care of hero being held */
+    if (on(player, ISHELD) && !isalpha(ch))
+    {
+	msg("You are being held");
+	return;
+    }
+
+    /* assume he's not in a wall */
+    if (!isalpha(ch)) turn_off(player, ISINWALL);
+
+    switch(ch) {
+	case '|':
+	case '-':
+	    if (levtype == OUTSIDE) {
+		hero = nh;
+		new_level(OUTSIDE);
+		return;
+	    }
+	case WALL:
+	case SECRETDOOR:
+	    if (off(player, CANINWALL) || running) {
+	        after = running = FALSE;
+
+		/* Light if finishing run */
+		if (levtype == MAZELEV && lit_room(&rooms[0]))
+		    look(FALSE, TRUE);
+
+	        after = running = FALSE;
+
+	        return;
+	    }
+	    turn_on(player, ISINWALL);
+	    break;
+	case POOL:
+	    if (levtype == OUTSIDE) {
+		lake_check(&nh);
+		running = FALSE;
+		break;
+	    }
+	case MAZETRAP:
+	    if (levtype == OUTSIDE) {
+	    running = FALSE;
+	    break;
+	}
+	case TRAPDOOR:
+	case TELTRAP:
+	case BEARTRAP:
+	case SLEEPTRAP:
+	case ARROWTRAP:
+	case DARTTRAP:
+	    ch = be_trapped(&player, &nh);
+	    if (ch == TRAPDOOR || ch == TELTRAP || 
+		pool_teleport  || ch == MAZETRAP) {
+		pool_teleport = FALSE;
+		return;
+	    }
+	    break;
+	case GOLD:
+	case POTION:
+	case SCROLL:
+	case FOOD:
+	case WEAPON:
+	case ARMOR:
+	case RING:
+	case MM:
+	case RELIC:
+	case STICK:
+	    running = FALSE;
+	    take = ch;
+	    break;
+    	case DOOR:
+    	case STAIRS:
+	    running = FALSE;
+	    break;
+	case POST:
+	    running = FALSE;
+	    new_level(POSTLEV);
+	    return;
+	default:
+	    break;
+    }
+
+    if (isalpha(ch)) { /* if its a monster then fight it */
+	running = FALSE;
+	i = 1;
+	if (player.t_ctype == C_FIGHTER)
+	   i += pstats.s_lvl/10;
+	while (i--)
+	    fight(&nh, cur_weapon, FALSE);
+	return;
+    }
+
+    /*
+     * if not fighting then move the hero
+     */
+    old_hero = hero;	/* Save hero's old position */
+    hero = nh;		/* Move the hero */
+    rp = roomin(&hero);
+    orp = roomin(&old_hero);
+
+    /* Unlight any possible cross-corridor */
+    if (levtype == MAZELEV) {
+	register bool call_light = FALSE;
+	register char wall_check;
+
+	if (wasfirstmove && lit_room(&rooms[0])) {
+	    /* Are we moving out of a corridor? */
+	    switch (runch) {
+		case 'h':
+		case 'l':
+		    if (old_hero.y + 1 < LINES - 2) {
+			wall_check = CCHAR( winat(old_hero.y + 1, old_hero.x) );
+			if (!isrock(wall_check)) call_light = TRUE;
+		    }
+		    if (old_hero.y - 1 > 0) {
+			wall_check = CCHAR( winat(old_hero.y - 1, old_hero.x) );
+			if (!isrock(wall_check)) call_light = TRUE;
+		    }
+		    break;
+		case 'j':
+		case 'k':
+		    if (old_hero.x + 1 < COLS) {
+			wall_check = CCHAR( winat(old_hero.y, old_hero.x + 1) );
+			if (!isrock(wall_check)) call_light = TRUE;
+		    }
+		    if (old_hero.x - 1 >= 0) {
+			wall_check = CCHAR( winat(old_hero.y, old_hero.x - 1) );
+			if (!isrock(wall_check)) call_light = TRUE;
+		    }
+		    break;
+		default:
+		    call_light = TRUE;
+	    }
+	    player.t_oldpos = old_hero;
+	    if (call_light) light(&old_hero);
+	}
+    }
+
+    else if (orp != NULL && rp == NULL) {    /* Leaving a room -- darken it */
+	orp->r_flags |= FORCEDARK;	/* Fake darkness */
+	light(&old_hero);
+	orp->r_flags &= ~FORCEDARK;	/* Restore light state */
+    }
+    else if (rp != NULL && orp == NULL){/* Entering a room */
+	light(&hero);
+    }
+    ch = CCHAR( winat(old_hero.y, old_hero.x) );
+    wmove(cw, unc(old_hero));
+    waddch(cw, ch);
+    wmove(cw, unc(hero));
+    waddch(cw, PLAYER);
+}
+
+/*
+ * do_run:
+ *	Start the hero running
+ */
+
+do_run(ch)
+char ch;
+{
+    firstmove = TRUE;
+    running = TRUE;
+    after = FALSE;
+    runch = ch;
+}
+
+/*
+ * getdelta:
+ *	Takes a movement character (eg. h, j, k, l) and returns the
+ *	y and x delta corresponding to it in the remaining arguments.
+ *	Returns TRUE if it could find it, FALSE otherwise.
+ */
+bool
+getdelta(match, dy, dx)
+char match;
+int *dy, *dx;
+{
+    register y, x;
+
+    for (y = 0; y < 3; y++)
+	for (x = 0; x < 3; x++)
+	    if (Moves[y][x] == match) {
+		*dy = y - 1;
+		*dx = x - 1;
+		return(TRUE);
+	    }
+
+    return(FALSE);
+}
+
+/*
+ * isatrap:
+ *	Returns TRUE if this character is some kind of trap
+ */
+isatrap(ch)
+reg char ch;
+{
+	switch(ch) {
+		case DARTTRAP:
+		case TELTRAP:
+		case TRAPDOOR:
+		case ARROWTRAP:
+		case SLEEPTRAP:
+		case BEARTRAP:	return(TRUE);
+		case MAZETRAP:
+		case POOL:	return(levtype != OUTSIDE);
+		default:	return(FALSE);
+	}
+}
+
+/*
+ * Called to illuminate a room.
+ * If it is dark, remove anything that might move.
+ */
+
+light(cp)
+coord *cp;
+{
+    register struct room *rp;
+    register int j, k, x, y;
+    register char ch, rch, sch;
+    register struct linked_list *item;
+    int jlow, jhigh, klow, khigh;	/* Boundaries of lit area */
+
+    if ((rp = roomin(cp)) != NULL) {
+	/*
+	 * is he wearing ring of illumination? 
+	 */
+	if (&hero == cp && ISWEARING(R_LIGHT)) /* Must be hero's room */
+	    rp->r_flags &= ~ISDARK;
+	
+	/* If we are in a maze, don't look at the whole room (level) */
+	if (levtype == MAZELEV) {
+	    int see_radius;
+
+	    see_radius = 1;
+
+	    /* If we are looking at the hero in a rock, broaden our sights */
+	    if (&hero == cp || &player.t_oldpos == cp) {
+		ch = CCHAR( winat(hero.y, hero.x) );
+		if (isrock(ch)) see_radius = 2;
+		ch = CCHAR( winat(player.t_oldpos.y, player.t_oldpos.x) );
+		if (isrock(ch)) see_radius = 2;
+	    }
+
+	    jlow = max(0, cp->y - see_radius - rp->r_pos.y);
+	    jhigh = min(rp->r_max.y, cp->y + see_radius + 1 - rp->r_pos.y);
+	    klow = max(0, cp->x - see_radius - rp->r_pos.x);
+	    khigh = min(rp->r_max.x, cp->x + see_radius + 1 - rp->r_pos.x);
+	}
+	else {
+	    jlow = klow = 0;
+	    jhigh = rp->r_max.y;
+	    khigh = rp->r_max.x;
+	}
+	for (j = 0; j < rp->r_max.y; j++)
+	{
+	    for (k = 0; k < rp->r_max.x; k++)
+	    {
+		bool see_here = 0, see_before = 0;
+
+		/* Is this in the give area -- needed for maze */
+		if ((j < jlow || j >= jhigh) && (k < klow || k >= khigh))
+		    continue;
+
+		y = rp->r_pos.y + j;
+		x = rp->r_pos.x + k;
+
+		/*
+		 * If we are in a maze do not look at this area unless
+		 * we can see it from where we are or where we last were
+		 * (for erasing purposes).
+		 */
+		if (levtype == MAZELEV) {
+		    /* If we can't see it from here, could we see it before? */
+		    if ((see_here = maze_view(y, x)) == FALSE) {
+			coord savhero;
+
+			/* Could we see it from where we were? */
+			savhero = hero;
+			hero = player.t_oldpos;
+			see_before = maze_view(y, x);
+			hero = savhero;
+
+			if (!see_before) continue;
+		    }
+		}
+
+		ch = show(y, x);
+		wmove(cw, y, x);
+		/*
+		 * Figure out how to display a secret door
+		 */
+		if (ch == SECRETDOOR) {
+		    if (j == 0 || j == rp->r_max.y - 1)
+			ch = '-';
+		    else
+			ch = '|';
+		}
+		/* For monsters, if they were previously not seen and
+		 * now can be seen, or vice-versa, make sure that will
+		 * happen.  This is for dark rooms as opposed to invisibility.
+		 *
+		 * Call winat() in the test because ch will not reveal
+		 * invisible monsters.
+		 */
+		if (isalpha(winat(y, x))) {
+		    struct thing *tp;	/* The monster */
+
+		    item = wake_monster(y, x);
+		    tp = THINGPTR(item);
+
+		    /* Previously not seen -- now can see it */
+		    if (tp->t_oldch == ' ' && cansee(tp->t_pos.y, tp->t_pos.x)) 
+			tp->t_oldch = CCHAR( mvinch(y, x) );
+
+		    /* Previously seen -- now can't see it */
+		    else if (!cansee(tp->t_pos.y, tp->t_pos.x) &&
+			     roomin(&tp->t_pos) != NULL)
+			switch (tp->t_oldch) {
+			    /*
+			     * Only blank it out if it is in a room and not
+			     * the border (or other wall) of the room.
+			     */
+			     case DOOR:
+			     case SECRETDOOR:
+			     case '-':
+			     case '|':
+				break;
+
+			     otherwise:
+				tp->t_oldch = ' ';
+			}
+		}
+
+		/*
+		 * If the room is a dark room, we might want to remove
+		 * monsters and the like from it (since they might
+		 * move).
+		 * A dark room.
+		 */
+		if ((!lit_room(rp) && (levtype != OUTSIDE)) ||
+		    (levtype == OUTSIDE && !daytime) ||
+		    on(player, ISBLIND) 	||
+		    (rp->r_flags & FORCEDARK)	||
+		    (levtype == MAZELEV && !see_here && see_before)) {
+		    sch = CCHAR( mvwinch(cw, y, x) );	/* What's seen */
+		    rch = CCHAR( mvinch(y, x) );	/* What's really there */
+		    switch (rch) {
+			case DOOR:
+			case SECRETDOOR:
+			case STAIRS:
+			case TRAPDOOR:
+			case TELTRAP:
+			case BEARTRAP:
+			case SLEEPTRAP:
+			case ARROWTRAP:
+			case DARTTRAP:
+			case MAZETRAP:
+			case POOL:
+			case POST:
+			case '|':
+			case '-':
+			case WALL:
+			    if (isalpha(sch)) ch = rch;
+			    else if (sch != FLOOR) ch = sch;
+			    else ch = ' '; /* Hide undiscoverd things */
+			when FLOOR:
+			    ch = ' ';
+			otherwise:
+			    ch = ' ';
+		    }
+		    /* Take care of our magic bookkeeping. */
+		    switch (sch) {
+			case MAGIC:
+			case BMAGIC:
+			case CMAGIC:
+			    ch = sch;
+		    }
+		}
+		mvwaddch(cw, y, x, ch);
+	    }
+	}
+    }
+}
+
+/*
+ * lit_room:
+ * 	Called to see if the specified room is lit up or not.
+ */
+
+bool
+lit_room(rp)
+register struct room *rp;
+{
+    register struct linked_list *fire_item;
+    register struct thing *fire_creature;
+
+    if (!(rp->r_flags & ISDARK)) return(TRUE);	/* A definitely lit room */
+
+    /* Is it lit by fire light? */
+    if (rp->r_flags & HASFIRE) {
+	switch (levtype) {
+	    case MAZELEV:
+		/* See if a fire creature is in line of sight */
+		for (fire_item = rp->r_fires; fire_item != NULL;
+		     fire_item = next(fire_item)) {
+		    fire_creature = THINGPTR(fire_item);
+		    if (maze_view(fire_creature->t_pos.y,
+				  fire_creature->t_pos.x)) return(TRUE);
+		}
+
+		/* Couldn't find any in line-of-sight */
+		return(FALSE);
+
+	    /* We should probably do something special for the outside */
+	    otherwise:
+		return TRUE;
+	}
+    }
+    return(FALSE);
+}
+
+/*
+ * rndmove:
+ *	move in a random direction if the monster/person is confused
+ */
+
+coord *
+rndmove(who)
+struct thing *who;
+{
+    register int x, y;
+    register int ex, ey, nopen = 0;
+    static coord ret;  /* what we will be returning */
+    static coord dest;
+
+    ret = who->t_pos;
+    /*
+     * Now go through the spaces surrounding the player and
+     * set that place in the array to true if the space can be
+     * moved into
+     */
+    ey = ret.y + 1;
+    ex = ret.x + 1;
+    for (y = who->t_pos.y - 1; y <= ey; y++)
+	if (y > 0 && y < LINES - 2)
+	    for (x = who->t_pos.x - 1; x <= ex; x++)
+	    {
+		if (x < 0 || x >= COLS)
+		    continue;
+		if (step_ok(y, x, NOMONST, who) == TRUE)
+		{
+		    dest.y = y;
+		    dest.x = x;
+		    if (!diag_ok(&who->t_pos, &dest, who))
+			continue;
+		    if (rnd(++nopen) == 0)
+			ret = dest;
+		}
+	    }
+    return &ret;
+}
+
+
+
+/*
+ * set_trap:
+ *	set a trap at (y, x) on screen.
+ */
+
+set_trap(tp, y, x)
+register struct thing *tp;
+register int y, x;
+{
+    register bool is_player = (tp == &player);
+    register char selection = rnd(7) + '1';
+    register char ch = 0, och;
+    int thief_bonus = 0;
+    int s_dext;
+
+    switch (och = CCHAR( mvinch(y, x) )) {
+	case WALL:
+	case FLOOR:
+	case PASSAGE:
+	    break;
+	default:
+	    msg("The trap failed!");
+	    return;
+    }
+
+    if (is_player && player.t_ctype == C_THIEF) thief_bonus = 30;
+
+    s_dext = (tp == &player) ? dex_compute() : tp->t_stats.s_dext;
+
+    if (ntraps >= MAXTRAPS || ++trap_tries >= MAXTRPTRY || levtype == POSTLEV ||
+	rnd(80) >= (s_dext + tp->t_stats.s_lvl/2 + thief_bonus)) {
+	if (is_player) msg("The trap failed!");
+	return;
+    }
+
+
+    if (is_player) {
+	int state = 0; /* 0 -> current screen, 1 -> prompt screen, 2 -> done */
+
+	msg("Which kind of trap do you wish to set? (* for a list): ");
+	do {
+	    selection = tolower(readchar());
+	    switch (selection) {
+		case '*':
+		  if (state != 1) {
+		    wclear(hw);
+		    touchwin(hw);
+		    mvwaddstr(hw, 2, 0,	"[1] Trap Door\n[2] Bear Trap\n");
+		    waddstr(hw,		"[3] Sleep Trap\n[4] Arrow Trap\n");
+		    waddstr(hw,		"[5] Teleport Trap\n[6] Dart Trap\n");
+		    if (wizard) {
+			waddstr(hw,	"[7] Magic pool\n[8] Maze Trap\n");
+			waddstr(hw,	"[9] Trading Post\n");
+		    }	
+		    mvwaddstr(hw, 0, 0, "Which kind of trap do you wish to set? ");
+		    draw(hw);
+		    state = 1;	/* Now in prompt window */
+		  }
+		  break;
+
+		case ESCAPE:
+		    if (state == 1) {
+			clearok(cw, TRUE); /* Set up for redraw */
+			touchwin(cw);
+		    }
+		    msg("");
+
+		    trap_tries--;	/* Don't count this one */
+		    after = FALSE;
+		    return;
+
+		case '1':
+		case '2':
+		case '3':
+		case '4':
+		case '5':
+		case '6':
+		case '7':
+		case '8':
+		case '9':
+		    if (selection < '7' || wizard) {
+			if (state == 1) {	/* In prompt window */
+			    clearok(cw, TRUE); /* Set up for redraw */
+			    touchwin(cw);
+			}
+
+			msg("");
+
+			/* Make sure there is a floor below us for trap doors */
+			if (selection == '1' && level >= nfloors) {
+			    if (state == 1) draw(cw);
+			    msg("There is no level below this one.");
+			    return;
+			}
+			state = 2;	/* Finished */
+			break;
+		    }
+
+		    /* Fall through for non-wizard, unusual trap case */
+		default:
+		    if (state == 1) {	/* In the prompt window */
+			mvwaddstr(hw, 0, 0, "Please enter a selection between 1 and 6:  ");
+			draw(hw);
+		    }
+		    else {	/* Normal window */
+			mpos = 0;
+			msg("Please enter a selection between 1 and 6:  ");
+		    }
+	    }
+	} while (state != 2);
+    }
+
+    switch (selection) {
+	case '1': ch = TRAPDOOR;
+	when '2': ch = BEARTRAP;
+	when '3': ch = SLEEPTRAP;
+	when '4': ch = ARROWTRAP;
+	when '5': ch = TELTRAP;
+	when '6': ch = DARTTRAP;
+	when '7': ch = POOL;
+	when '8': ch = MAZETRAP;
+	when '9': ch = POST;
+    }
+
+    mvaddch(y, x, ch);
+    traps[ntraps].tr_show = och;
+    traps[ntraps].tr_type = ch;
+    traps[ntraps].tr_pos.y = y;
+    traps[ntraps].tr_pos.x = x;
+    if (is_player) 
+	traps[ntraps].tr_flags = ISTHIEFSET;
+    if (ch == POOL || ch == POST) {
+	traps[ntraps].tr_flags |= ISFOUND;
+    }
+
+    ntraps++;
+}
+
+/*
+ * show:
+ *	returns what a certain thing will display as to the un-initiated
+ */
+
+show(y, x)
+register int y, x;
+{
+    register char ch = CCHAR( winat(y, x) );
+    register struct linked_list *it;
+    register struct thing *tp;
+
+    if (isatrap(ch)) {
+	register struct trap *trp = trap_at(y, x);
+
+	return (trp->tr_flags & ISFOUND) ? ch : trp->tr_show;
+    }
+    else if (isalpha(ch)) {
+	if ((it = find_mons(y, x)) == NULL) {
+	    msg("Can't find monster in show");
+	    return(mvwinch(stdscr, y, x));
+	}
+	tp = THINGPTR(it);
+
+	if (on(*tp, ISDISGUISE)) ch = tp->t_disguise; /* As a mimic */
+
+	/* Hide invisible creatures */
+	else if (invisible(tp)) {
+	    /* We can't see surprise-type creatures through "see invisible" */
+	    if (off(player,CANSEE) || on(*tp,CANSURPRISE))
+		ch = CCHAR( mvwinch(stdscr, y, x) ); /* Invisible */
+	}
+	else if (on(*tp, CANINWALL)) {
+	    if (isrock(mvwinch(stdscr, y, x))) ch = CCHAR( winch(stdscr) ); /* As Xorn */
+	}
+    }
+    return ch;
+}
+
+
+/*
+ * trap_at:
+ *	find the trap at (y,x) on screen.
+ */
+
+struct trap *
+trap_at(y, x)
+register int y, x;
+{
+    register struct trap *tp, *ep;
+
+    ep = &traps[ntraps];
+    for (tp = traps; tp < ep; tp++)
+	if (tp->tr_pos.y == y && tp->tr_pos.x == x)
+	    break;
+    if (tp == ep)
+	debug((sprintf(prbuf, "Trap at %d,%d not in array", y, x), prbuf));
+    return tp;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/network.h	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,21 @@
+/* 
+ * Networking information -- should not vary among networking machines
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#define SYSLEN 9
+#define LOGLEN 8
+#define NUMNET 6
+#undef NUMNET
+struct network {
+    char *system;
+    char *rogue;
+};
+extern struct network Network[];
+
+/* This system's name -- should not be defined if uname() is available */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/new_level.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,579 @@
+/*
+ * new_level: Dig and draw a new level
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include "rogue.h"
+#define TERRASAVE 3
+
+new_level(ltype)
+LEVTYPE	ltype;		/* designates type of level to create */
+{
+    register int rm = 0, i, cnt;
+    register char ch;
+    register struct linked_list *item;
+    register struct thing *tp;
+    register struct object *obj;
+    int waslit = 0;	/* Was the previous outside level lit? */
+    int starty = 0, startx = 0, deltay = 0, deltax = 0;
+    bool fresh=TRUE, vert = 0, top;
+    struct room *rp;
+    struct linked_list *nitem, *savmonst=NULL, *savitems=NULL;
+    coord stairs = { 0, 0 };
+
+    if (wizard) {
+	msg("Turns: %d", turns);	/* Number of turns for last level */
+	mpos = 0;
+    }
+
+    /* Start player off right */
+    turn_off(player, ISHELD);
+    turn_off(player, ISFLEE);
+    extinguish(suffocate);
+    hold_count = 0;
+    trap_tries = 0;
+
+    /* Are we just entering a dungeon?  If so, how big is it? */
+    if (ltype != OUTSIDE && nfloors < 0) nfloors = HARDER+10  + rnd(11);
+
+    if (level > max_level)
+	max_level = level;
+
+    /* Are we starting a new outside level? */
+    if (ltype == OUTSIDE) {
+	register int i, j;
+
+	/* Save some information prior to clearing the screen */
+	if (level == -1 || mvinch(hero.y, hero.x)  == '-') vert = TRUE;
+	else vert = FALSE;
+
+	if (level == -1) {
+	    fresh = TRUE;
+	    starty = 2;
+	    startx = 1;
+	    deltay = deltax = 1;
+	    level = 0;	/* Restore the level */
+	}
+	else {	/* Copy several lines of the terrain to the other end */
+	    char cch;	/* Copy character */
+
+	    /* Was the area dark (not magically lit)? */
+	    if (!(rooms[0].r_flags & ISDARK)) waslit = 1;
+
+	    fresh = FALSE;
+	    if ((vert && hero.y == 1) || (!vert && hero.x == 0)) top = TRUE;
+	    else top = FALSE;
+	    for (i=0; i<TERRASAVE; i++) {
+		if (vert)
+		    for (j=1; j<COLS-1; j++) {
+			if (top) {
+			    cch = CCHAR( mvinch(i+2, j) );
+			    mvaddch(LINES-6+i, j, cch);
+			}
+			else {
+			    cch = CCHAR( mvinch(LINES-4-i, j) );
+			    mvaddch(4-i, j, cch);
+			}
+		    }
+		else
+		    for (j=2; j<LINES-3; j++) {
+			if (top) {
+			    cch = CCHAR( mvinch(j, i+1) );
+			    mvaddch(j, COLS-4+i, cch);
+			}
+			else {
+			    cch = CCHAR( mvinch(j, COLS-2-i) );
+			    mvaddch(j, 3-i, cch);
+			}
+		    }
+	    }
+
+	    if (vert) {
+		startx = deltax = 1;
+		if (top) {
+		    starty = LINES-4-TERRASAVE;
+		    deltay = -1;
+		}
+		else {
+		    starty = TERRASAVE + 2;
+		    deltay = 1;
+		}
+	    }
+	    else {
+		starty = 2;
+		deltay = 1;
+		if (top) {
+		    startx = COLS-2-TERRASAVE;
+		    deltax = -1;
+		}
+		else {
+		    deltax = 1;
+		    startx = TERRASAVE + 1;
+		}
+	    }
+
+	    /* Check if any monsters should be saved */
+	    for (item = mlist; item != NULL; item = nitem) {
+		nitem = next(item);
+		tp = THINGPTR(item);
+		if (vert) {
+		    if (top) {
+			if (tp->t_pos.y < TERRASAVE + 2)
+			    tp->t_pos.y += LINES - 5 - TERRASAVE;
+			else continue;
+		    }
+		    else {
+			if (tp->t_pos.y > LINES - 4 - TERRASAVE)
+			    tp->t_pos.y += 5 + TERRASAVE - LINES;
+			else continue;
+		    }
+		}
+		else {
+		    if (top) {
+			if (tp->t_pos.x < TERRASAVE + 1)
+			    tp->t_pos.x += COLS - 2 - TERRASAVE;
+			else continue;
+		    }
+		    else {
+			if (tp->t_pos.x > COLS - 2 - TERRASAVE)
+			    tp->t_pos.x += 2 + TERRASAVE - COLS;
+			else continue;
+		    }
+		}
+		detach(mlist, item);
+		attach(savmonst, item);
+	    }
+
+	    /* Check if any treasure should be saved */
+	    for (item = lvl_obj; item != NULL; item = nitem) {
+		nitem = next(item);
+		obj = OBJPTR(item);
+		if (vert) {
+		    if (top) {
+			if (obj->o_pos.y < TERRASAVE + 2)
+			    obj->o_pos.y += LINES - 5 - TERRASAVE;
+			else continue;
+		    }
+		    else {
+			if (obj->o_pos.y > LINES - 4 - TERRASAVE)
+			    obj->o_pos.y += 5 + TERRASAVE - LINES;
+			else continue;
+		    }
+		}
+		else {
+		    if (top) {
+			if (obj->o_pos.x < TERRASAVE + 1)
+			    obj->o_pos.x += COLS - 2 - TERRASAVE;
+			else continue;
+		    }
+		    else {
+			if (obj->o_pos.x > COLS - 2 - TERRASAVE)
+			    obj->o_pos.x += 2 + TERRASAVE - COLS;
+			else continue;
+		    }
+		}
+		detach(lvl_obj, item);
+		attach(savitems, item);
+	    }
+	}
+    }
+
+
+    wclear(cw);
+    wclear(mw);
+    if (fresh) clear();
+    /*
+     * check to see if he missed a UNIQUE, If he did then put it back
+     * in the monster table for next time
+     */
+    for (item = mlist; item != NULL; item = next(item)) {
+	tp = THINGPTR(item);
+	if (on(*tp, ISUNIQUE)) 
+	    monsters[tp->t_index].m_normal = TRUE;
+    }
+    /*
+     * Free up the monsters on the last level
+     */
+    t_free_list(monst_dead);
+    t_free_list(mlist);
+    o_free_list(lvl_obj);		/* Free up previous objects (if any) */
+    for (rp = rooms; rp < &rooms[MAXROOMS]; rp++)
+	t_free_list(rp->r_exit);	/* Free up the exit lists */
+
+    levtype = ltype;
+    foods_this_level = 0;		/* food for hero this level */
+    if (ltype == POSTLEV) {
+	do_post();			/* do post stuff */
+    }
+    else if (ltype == MAZELEV) {
+	do_maze();
+	no_food++;
+	put_things(ltype);		/* Place objects (if any) */
+    }
+    else if (ltype == OUTSIDE) {
+	init_terrain();
+	do_terrain(starty, startx, deltay, deltax, (bool) (fresh || !vert));
+	no_food++;
+	put_things(ltype);
+
+	/* Should we magically light this area? */
+	if (waslit) rooms[0].r_flags &= ~ISDARK;
+    }
+    else {
+	do_rooms();			/* Draw rooms */
+	do_passages();			/* Draw passages */
+	no_food++;
+	put_things(ltype);		/* Place objects (if any) */
+    }
+    /*
+     * Place the staircase down.  Only a small chance for an outside stairway.
+     */
+    if (ltype != OUTSIDE || roll(1, 4) == 4) {
+	cnt = 0;
+	do {
+	    rm = rnd_room();
+	    rnd_pos(&rooms[rm], &stairs);
+	} until (mvinch(stairs.y, stairs.x) == FLOOR || cnt++ > 5000);
+	addch(STAIRS);
+    }
+    /*
+     * maybe add a trading post 
+     */
+    if (level > 5 && rnd(11) == 7 && ltype == NORMLEV) {
+	cnt = 0;
+	do {
+	    rm = rnd_room();
+	    if (rooms[rm].r_flags & ISTREAS)
+		continue;
+	    rnd_pos(&rooms[rm], &stairs);
+	} until (winat(stairs.y, stairs.x) == FLOOR || cnt++ > 5000);
+	addch(POST);
+    }
+    if (ltype != POSTLEV) {	/* Add monsters that fell through */
+	nitem = tlist;
+	while (nitem != NULL) {
+	    item = nitem;
+	    nitem = next(item); /* because detach and attach mess up ptrs */
+	    tp = THINGPTR(item);
+	    cnt = 0;
+	    do {
+		rm = rnd_room();
+		rnd_pos(&rooms[rm], &tp->t_pos);
+	    } until (cnt++ > 5000 || winat(tp->t_pos.y, tp->t_pos.x) == FLOOR);
+	    mvwaddch(mw, tp->t_pos.y, tp->t_pos.x, tp->t_type);
+	    tp->t_oldch = CCHAR( mvwinch(cw, tp->t_pos.y, tp->t_pos.x) );
+
+	    /*
+	     * If it has a fire, mark it
+	     */
+	    if (on(*tp, HASFIRE)) {
+		register struct linked_list *fire_item;
+
+		fire_item = creat_item();
+		ldata(fire_item) = (char *) tp;
+		attach(rooms[rm].r_fires, fire_item);
+		rooms[rm].r_flags |= HASFIRE;
+	    }
+	    turn_off(*tp, ISELSEWHERE);
+	    detach(tlist, item);
+	    attach(mlist, item);
+	}
+    }
+
+    /* Restore any saved monsters */
+    for (item = savmonst; item != NULL; item = nitem) {
+	nitem = next(item);
+	tp = THINGPTR(item);
+	mvwaddch(mw, tp->t_pos.y, tp->t_pos.x, tp->t_type);
+	tp->t_oldch = CCHAR( mvwinch(cw, tp->t_pos.y, tp->t_pos.x) );
+
+	/*
+	 * If it has a fire, mark it
+	 */
+	if (on(*tp, HASFIRE)) {
+	    register struct linked_list *fire_item;
+
+	    fire_item = creat_item();
+	    ldata(fire_item) = (char *) tp;
+	    attach(rooms[rm].r_fires, fire_item);
+	    rooms[rm].r_flags |= HASFIRE;
+	}
+
+	detach(savmonst, item);
+	attach(mlist, item);
+    }
+
+    /* Restore any saved objects */
+    for(item = savitems; item != NULL; item = nitem) {
+	nitem = next(item);
+	obj = OBJPTR(item);
+	mvaddch(obj->o_pos.y, obj->o_pos.x, obj->o_type);
+	detach(savitems, item);
+	attach(lvl_obj, item);
+    }
+
+
+    /*
+     * Place the traps (except for trading post)
+     */
+    ntraps = 0;	/* No traps yet */
+    if (levtype == NORMLEV) {
+	if (rnd(10) < vlevel) {
+	    ntraps = rnd(vlevel/4)+1;
+	    if (ntraps > MAXTRAPS)
+		ntraps = MAXTRAPS;
+	    i = ntraps;
+	    while (i--)
+	    {
+		cnt = 0;
+		do {
+		    rm = rnd_room();
+		    if (rooms[rm].r_flags & ISTREAS)
+			continue;
+		    rnd_pos(&rooms[rm], &stairs);
+		} until (winat(stairs.y, stairs.x) == FLOOR || cnt++ > 5000);
+
+		traps[i].tr_flags = 0;
+
+		/* If we are at the bottom, we can't set a trap door */
+		if (level >= nfloors) ch = (char) rnd(7) + 1;
+		else ch = (char) rnd(8);
+
+		switch((int) ch) {
+		    case 0: ch = TRAPDOOR;
+		    when 1: ch = BEARTRAP;
+		    when 2: ch = SLEEPTRAP;
+		    when 3: ch = ARROWTRAP;
+		    when 4: ch = TELTRAP;
+		    when 5: ch = DARTTRAP;
+		    when 6: ch = POOL;
+			    traps[i].tr_flags = ISFOUND;
+		    when 7: ch = MAZETRAP;
+		}
+		addch(ch);
+		traps[i].tr_type = ch;
+		traps[i].tr_show = FLOOR;
+		traps[i].tr_pos = stairs;
+	    }
+	}
+    }
+    if (fresh) {	/* A whole new picture */
+	cnt = 0;
+	do {
+	    rm = rnd_room();
+	    if (rooms[rm].r_flags & ISTREAS)
+		continue;
+	    rnd_pos(&rooms[rm], &hero);
+	} until(	cnt++ > 5000 ||
+		    (winat(hero.y, hero.x) == FLOOR &&
+		     DISTANCE(hero.y, hero.x, stairs.y, stairs.x) > 16));
+    }
+    else {		/* We're extending into an adjacent outside plane */
+	rm = 0;
+	if (vert) {
+	    if (hero.y == 1) hero.y = LINES - 3 - TERRASAVE; /* Top to bottom */
+	    else hero.y = TERRASAVE + 1;	/* Bottom to top */
+	}
+	else {
+	    if (hero.x == 0) hero.x = COLS - 1 - TERRASAVE; /* Right to left */
+	    else hero.x = TERRASAVE;	/* Left to right */
+	}
+    }
+    oldrp = &rooms[rm];		/* Set the current room */
+    player.t_oldpos = player.t_pos;	/* Set the current position */
+    if (ISWEARING(R_AGGR) || 
+	(cur_misc[WEAR_JEWEL] != NULL && 
+	 cur_misc[WEAR_JEWEL]->o_which == MM_JEWEL))
+	aggravate();
+    light(&hero);
+    wmove(cw, hero.y, hero.x);
+    waddch(cw, PLAYER);
+
+    if (level > cur_max)
+	cur_max = level;
+
+    status(TRUE);
+}
+
+/*
+ * Pick a room that is really there
+ */
+
+rnd_room()
+{
+    register int rm;
+
+    if (levtype != NORMLEV)
+	rm = 0;
+    else do
+	{
+	    rm = rnd(MAXROOMS);
+	} while (rooms[rm].r_flags & ISGONE);
+    return rm;
+}
+
+/*
+ * put_things:
+ *	put potions and scrolls on this level
+ */
+
+put_things(ltype)
+LEVTYPE	ltype;		/* designates type of level to create */
+{
+    register int i, rm, cnt;
+    register struct object *cur;
+    register struct linked_list *item, *exitptr;
+    bool got_unique = FALSE;
+    int length, width;
+    coord tp, *exit;
+
+    /*
+     * The only way to get new stuff is to go down into the dungeon.
+     */
+    if (level <= cur_max)
+	return;
+
+    /* 
+     * There is a chance that there is a treasure room on this level 
+     * Increasing chance after level 9 
+     */
+    if (ltype != MAZELEV && rnd(HARDER) < level - 8) {	
+	register  j;
+	register struct room *rp;
+
+	/* Count the number of free spaces */
+	i = 0;	/* 0 tries */
+	do {
+	    rp = &rooms[rnd_room()];
+	    width = rp->r_max.y - 2;
+	    length = rp->r_max.x - 2;
+	} until ((width*length >= MAXTREAS) || (i++ > MAXROOMS*4));
+
+	/* Mark the room as a treasure room */
+	rp->r_flags |= ISTREAS;
+
+	/* Make all the doors secret doors */
+	for (exitptr = rp->r_exit; exitptr; exitptr = next(exitptr)) {
+	    exit = DOORPTR(exitptr);
+	    move(exit->y, exit->x);
+	    addch(SECRETDOOR);
+	}
+
+	/*
+	 * check to see if there are any monsters in room already
+	 */
+	for (item = mlist; item != NULL; item = next(item)) {
+	    register struct thing *tp;
+
+	    tp = THINGPTR(item);
+	    if (rp == roomin(&tp->t_pos)) {
+		turn_on(*tp, ISMEAN);
+		if (off(*tp, CANINWALL)) {
+		    tp->t_dest = &hero;
+		    turn_on(*tp, ISRUN);
+		}
+		if (on(*tp, ISUNIQUE))
+		    got_unique = TRUE;
+
+		/* If it is a mimic, undisguise it */
+		if (on(*tp, ISDISGUISE)) 
+		    turn_off(*tp, ISDISGUISE);
+	    }
+	}
+
+
+	/* Put in the monsters and treasures */
+	for (j=1; j<rp->r_max.y-1; j++)
+	    for (i=1; i<rp->r_max.x-1; i++) {
+		coord trp;
+
+		trp.y = rp->r_pos.y+j;
+		trp.x = rp->r_pos.x+i;
+
+		/* Monsters */
+		if ((rnd(100) < (MAXTREAS*100)/(width*length)) &&
+		    (mvwinch(mw, rp->r_pos.y+j, rp->r_pos.x+i) == ' ')) {
+		    register struct thing *tp;
+
+		    /* Make a monster */
+		    item = new_item(sizeof *tp);
+		    tp = THINGPTR(item);
+
+		    /* 
+		     * Put it there and aggravate it (unless it can escape) 
+		     * only put one UNIQUE per treasure room at most
+		     */
+		    if (got_unique)
+			new_monster(item,randmonster(FALSE, TRUE),&trp,TRUE);
+		    else 
+			new_monster(item,randmonster(FALSE, FALSE),&trp,TRUE);
+		    if (on(*tp, ISUNIQUE)) {
+			got_unique = TRUE;
+			carry_obj(tp, monsters[tp->t_index].m_carry);
+		    }
+		    turn_on(*tp, ISMEAN);
+		    if (off(*tp, CANINWALL)) {
+			tp->t_dest = &hero;
+			turn_on(*tp, ISRUN);
+		    }
+
+		    /* If it is a mimic, undisguise it */
+		    if (on(*tp, ISDISGUISE)) 
+			turn_off(*tp, ISDISGUISE);
+
+		    if (on(*tp, HASFIRE)) {
+			register struct linked_list *fire_item;
+
+			fire_item = creat_item();
+			ldata(fire_item) = (char *) tp;
+			attach(rp->r_fires, fire_item);
+			rp->r_flags |= HASFIRE;
+		    }
+		}
+
+		/* Treasures */
+		if ((rnd(100) < (MAXTREAS*100)/(width*length)) &&
+		    (mvinch(rp->r_pos.y+j, rp->r_pos.x+i) == FLOOR)) {
+		    item = new_thing(ALL);
+		    attach(lvl_obj, item);
+		    cur = OBJPTR(item);
+	
+		    mvaddch(trp.y, trp.x, cur->o_type);
+		    cur->o_pos = trp;
+		}
+	    }
+    }
+
+    /*
+     * Do MAXOBJ attempts to put things on a level
+     */
+    for (i = 0; i < MAXOBJ; i++)
+	if (rnd(100) < 45) {
+	    /*
+	     * Pick a new object and link it in the list
+	     */
+	    item = new_thing(ALL);
+	    attach(lvl_obj, item);
+	    cur = OBJPTR(item);
+	    /*
+	     * Put it somewhere
+	     */
+	    cnt = 0;
+	    do {
+		rm = rnd_room();
+		rnd_pos(&rooms[rm], &tp);
+	    } until (winat(tp.y, tp.x) == FLOOR || cnt++ > 500);
+	    mvaddch(tp.y, tp.x, cur->o_type);
+	    cur->o_pos = tp;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/options.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,469 @@
+/*
+ * This file has all the code for the option command.
+ * I would rather this command were not necessary, but
+ * it is the only way to keep the wolves off of my back.
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include <ctype.h>
+#include "rogue.h"
+
+#define	NUM_OPTS	(sizeof optlist / sizeof (OPTION))
+
+
+/*
+ * description of an option and what to do with it
+ */
+struct optstruct {
+    char	*o_name;	/* option name */
+    char	*o_prompt;	/* prompt for interactive entry */
+    int 	*o_opt;		/* pointer to thing to set */
+    int		(*o_putfunc)();	/* function to print value */
+    int		(*o_getfunc)();	/* function to get value interactively */
+};
+
+typedef struct optstruct	OPTION;
+
+int	put_bool(), 
+	get_bool(),
+	put_str(),
+	get_str(),
+	put_abil(),
+	get_abil(),
+	get_quest(),
+	put_quest();
+
+OPTION	optlist[] = {
+    {"terse",	 "Terse output: ",
+		 (int *) &terse,	put_bool,	get_bool	},
+    {"flush",	 "Flush typeahead during battle: ",
+		 (int *) &fight_flush,	put_bool,	get_bool	},
+    {"jump",	 "Show position only at end of run: ",
+		 (int *) &jump,		put_bool,	get_bool	},
+    {"step",	"Do inventories one line at a time: ",
+		(int *) &slow_invent,	put_bool,	get_bool	},
+    {"askme",	"Ask me about unidentified things: ",
+		(int *) &askme,		put_bool,	get_bool	},
+    {"pickup", "Pick things up automatically: ",
+		(int *) &auto_pickup,	put_bool,	get_bool	},
+    {"name",	 "Name: ",
+		(int *) whoami,		put_str,	get_str		},
+    {"fruit",	 "Fruit: ",
+		(int *) fruit,		put_str,	get_str		},
+    {"file",	 "Save file: ",
+		(int *) file_name,	put_str,	get_str		},
+    {"score",	 "Score file: ",
+		(int *) score_file,	put_str,	get_str		},
+    {"class",	"Character class: ",
+		(int *)&char_type,	put_abil,	get_abil	},
+    {"quest",	"Quest item: ",
+		(int *) &quest_item,	put_quest,	get_quest	}
+};
+
+/*
+ * The ability field is read-only
+ */
+get_abil(abil, win)
+int *abil;
+WINDOW *win;
+{
+    register int oy, ox;
+
+    getyx(win, oy, ox);
+    put_abil(abil, win);
+    get_ro(win, oy, ox);
+}
+
+/*
+ * The quest field is read-only
+ */
+get_quest(quest, win)
+int *quest;
+WINDOW *win;
+{
+    register int oy, ox;
+
+    getyx(win, oy, ox);
+    waddstr(win, rel_magic[*quest].mi_name);
+    get_ro(win, oy, ox);
+}
+
+/*
+ * get_ro:
+ *	"Get" a read-only value.
+ */
+
+get_ro(win, oy, ox)
+WINDOW *win;
+register int oy, ox;
+{
+    register int ny, nx;
+    register bool op_bad;
+    
+    op_bad = TRUE;
+    getyx(win, ny, nx);
+    while(op_bad)	
+    {
+	wmove(win, oy, ox);
+	draw(win);
+	switch (wgetch(win))
+	{
+	    case '\n':
+	    case '\r':
+		op_bad = FALSE;
+		break;
+	    case '\033':
+	    case '\007':
+		return QUIT;
+	    case '-':
+		return MINUS;
+	    default:
+		mvwaddstr(win, ny, nx + 5, "(no change allowed)");
+	}
+    }
+    wmove(win, ny, nx + 5);
+    wclrtoeol(win);
+    wmove(win, ny, nx);
+    waddch(win, '\n');
+    return NORM;
+}
+
+/*
+ * allow changing a boolean option and print it out
+ */
+
+get_bool(bp, win)
+bool *bp;
+WINDOW *win;
+{
+    register int oy, ox;
+    register bool op_bad;
+
+    op_bad = TRUE;
+    getyx(win, oy, ox);
+    waddstr(win, *bp ? "True" : "False");
+    while(op_bad)	
+    {
+	wmove(win, oy, ox);
+	draw(win);
+	switch (wgetch(win))
+	{
+	    case 't':
+	    case 'T':
+		*bp = TRUE;
+		op_bad = FALSE;
+		break;
+	    case 'f':
+	    case 'F':
+		*bp = FALSE;
+		op_bad = FALSE;
+		break;
+	    case '\n':
+	    case '\r':
+		op_bad = FALSE;
+		break;
+	    case '\033':
+	    case '\007':
+		return QUIT;
+	    case '-':
+		return MINUS;
+	    default:
+		mvwaddstr(win, oy, ox + 10, "(T or F)");
+	}
+    }
+    wmove(win, oy, ox);
+    wclrtoeol(win);
+    waddstr(win, *bp ? "True" : "False");
+    waddch(win, '\n');
+    return NORM;
+}
+
+
+/*
+ * set a string option
+ */
+get_str(opt, win)
+register char *opt;
+WINDOW *win;
+{
+    register char *sp;
+    register int c, oy, ox;
+    char buf[LINELEN];
+
+    draw(win);
+    getyx(win, oy, ox);
+    /*
+     * loop reading in the string, and put it in a temporary buffer
+     */
+    for (sp = buf;
+	(c = wgetch(win)) != '\n'	&& 
+	c != '\r'			&& 
+	c != '\033'			&& 
+	c != '\007'			&&
+	sp < &buf[LINELEN-1];
+	wclrtoeol(win), draw(win))
+    {
+	if (c == -1)
+	    continue;
+	else if (c == md_erasechar()) /* process erase character */
+	{
+	    if (sp > buf)
+	    {
+		register int i;
+
+		sp--;
+		for (i = strlen(unctrl(*sp)); i; i--)
+		    waddch(win, '\b');
+	    }
+	    continue;
+	}
+	else if (c == md_killchar()) /* process kill character */
+	{
+	    sp = buf;
+	    wmove(win, oy, ox);
+	    continue;
+	}
+	else if (sp == buf)
+	    if (c == '-' && win == hw)	/* To move back a line in hw */
+		break;
+	    else if (c == '~')
+	    {
+		strcpy(buf, home);
+		waddstr(win, home);
+		sp += strlen(home);
+		continue;
+	    }
+	*sp++ = c;
+	waddstr(win, unctrl(c));
+    }
+    *sp = '\0';
+    if (sp > buf)	/* only change option if something has been typed */
+	strucpy(opt, buf, strlen(buf));
+    wmove(win, oy, ox);
+    waddstr(win, opt);
+    waddch(win, '\n');
+    draw(win);
+    if (win == cw)
+	mpos += (int)(sp - buf);
+    if (c == '-')
+	return MINUS;
+    else if (c == '\033' || c == '\007')
+	return QUIT;
+    else
+	return NORM;
+}
+
+
+
+/*
+ * print and then set options from the terminal
+ */
+option()
+{
+    register OPTION	*op;
+    register int	retval;
+
+    wclear(hw);
+    touchwin(hw);
+    /*
+     * Display current values of options
+     */
+    for (op = optlist; op <= &optlist[NUM_OPTS-1]; op++)
+    {
+	waddstr(hw, op->o_prompt);
+	(*op->o_putfunc)(op->o_opt, hw);
+	waddch(hw, '\n');
+    }
+    /*
+     * Set values
+     */
+    wmove(hw, 0, 0);
+    for (op = optlist; op <= &optlist[NUM_OPTS-1]; op++)
+    {
+	waddstr(hw, op->o_prompt);
+	if ((retval = (*op->o_getfunc)(op->o_opt, hw)))
+	    if (retval == QUIT)
+		break;
+	    else if (op > optlist) {	/* MINUS */
+		wmove(hw, (int)(op - optlist) - 1, 0);
+		op -= 2;
+	    }
+	    else	/* trying to back up beyond the top */
+	    {
+		putchar('\007');
+		wmove(hw, 0, 0);
+		op--;
+	    }
+    }
+    /*
+     * Switch back to original screen
+     */
+    mvwaddstr(hw, LINES-1, 0, spacemsg);
+    draw(hw);
+    wait_for(hw,' ');
+    clearok(cw, TRUE);
+    touchwin(cw);
+    after = FALSE;
+}
+
+/*
+ * parse options from string, usually taken from the environment.
+ * the string is a series of comma seperated values, with booleans
+ * being stated as "name" (true) or "noname" (false), and strings
+ * being "name=....", with the string being defined up to a comma
+ * or the end of the entire option string.
+ */
+
+parse_opts(str)
+register char *str;
+{
+    register char *sp;
+    register OPTION *op;
+    register int len;
+
+    while (*str)
+    {
+	/*
+	 * Get option name
+	 */
+	for (sp = str; isalpha(*sp); sp++)
+	    continue;
+	len = (int)(sp - str);
+	/*
+	 * Look it up and deal with it
+	 */
+	for (op = optlist; op <= &optlist[NUM_OPTS-1]; op++)
+	    if (EQSTR(str, op->o_name, len))
+	    {
+		if (op->o_putfunc == put_bool)	/* if option is a boolean */
+		    *(bool *)op->o_opt = TRUE;
+		else				/* string option */
+		{
+		    register char *start;
+		    char value[80];
+
+		    /*
+		     * Skip to start of string value
+		     */
+		    for (str = sp + 1; *str == '='; str++)
+			continue;
+		    if (*str == '~')
+		    {
+			strcpy((char *) value, home);
+			start = (char *) value + strlen(home);
+			while (*++str == '/')
+			    continue;
+		    }
+		    else
+			start = (char *) value;
+		    /*
+		     * Skip to end of string value
+		     */
+		    for (sp = str + 1; *sp && *sp != ','; sp++)
+			continue;
+		    strucpy(start, str, sp - str);
+
+		    /* Put the value into the option field */
+		    if (op->o_putfunc != put_abil) 
+			strcpy((char *)op->o_opt, value);
+
+		    else if (*op->o_opt == -1) { /* Only init ability once */
+			register int len = strlen(value);
+
+			if (isupper(value[0])) value[0] = tolower(value[0]);
+			if (EQSTR(value, "fighter", len))
+				*op->o_opt = C_FIGHTER;
+			else if (EQSTR(value, "magic", min(len, 5)))
+				*op->o_opt = C_MAGICIAN;
+			else if (EQSTR(value, "cleric", len))
+				*op->o_opt = C_CLERIC;
+			else if (EQSTR(value, "thief", len))
+				*op->o_opt = C_THIEF;
+		    }
+		}
+		break;
+	    }
+	    /*
+	     * check for "noname" for booleans
+	     */
+	    else if (op->o_putfunc == put_bool
+	      && EQSTR(str, "no", 2) && EQSTR(str + 2, op->o_name, len - 2))
+	    {
+		*(bool *)op->o_opt = FALSE;
+		break;
+	    }
+
+	/*
+	 * skip to start of next option name
+	 */
+	while (*sp && !isalpha(*sp))
+	    sp++;
+	str = sp;
+    }
+}
+
+
+/*
+ * print the character type
+ */
+put_abil(ability, win)
+int *ability;
+WINDOW *win;
+{
+    char *abil;
+
+    switch (*ability) {
+	case C_MAGICIAN:abil = "Magic User";
+	when C_FIGHTER:	abil = "Fighter";
+	when C_CLERIC:	abil = "Cleric";
+	when C_THIEF:	abil = "Thief";
+	otherwise:	abil = "??";
+    }
+    waddstr(win, abil);
+}
+
+
+/*
+ * print out the quest
+ */
+
+put_quest(quest, win)
+int *quest;
+WINDOW *win;
+{
+    waddstr(win, rel_magic[*quest].mi_name);
+}
+
+
+/*
+ * put out a boolean
+ */
+put_bool(b, win)
+bool	*b;
+WINDOW *win;
+{
+    waddstr(win, *b ? "True" : "False");
+}
+
+
+
+
+/*
+ * put out a string
+ */
+put_str(str, win)
+char *str;
+WINDOW *win;
+{
+    waddstr(win, str);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/outside.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,210 @@
+/*
+ * functions for dealing with the "outside" level
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include "rogue.h"
+
+extern char rnd_terrain(), get_terrain();
+
+/*
+ * init_terrain:
+ *	Get the single "outside room" set up correctly
+ */
+
+void
+init_terrain()
+{
+    register struct room *rp;
+
+    for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) {
+	    rp->r_flags = ISGONE;	/* kill all rooms */
+	    rp->r_fires = NULL;		/* no fires */
+    }
+    rp = &rooms[0];			/* point to only room */
+    rp->r_flags = ISDARK;		/* outside is always dark */
+    rp->r_pos.x = 0;			/* room fills whole screen */
+    rp->r_pos.y = 1;
+    rp->r_max.x = COLS;
+    rp->r_max.y = LINES - 3;
+}
+
+
+
+void
+do_terrain(basey, basex, deltay, deltax, fresh)
+int basey, basex, deltay, deltax;
+bool fresh;
+{
+    register cury, curx;	/* Current y and x positions */
+
+    /* Lay out the boundary */
+    for (cury=1; cury<LINES-2; cury++) {	/* Vertical "walls" */
+	mvaddch(cury, 0, '|');
+	mvaddch(cury, COLS-1, '|');
+    }
+    for (curx=0; curx<COLS; curx++) {		/* Horizontal "walls" */
+	mvaddch(1, curx, '-');
+	mvaddch(LINES-3, curx, '-');
+    }
+
+    /* If we are not continuing, let's start out with a line of terrain */
+    if (fresh) {
+	char ch;	/* Next char to add */
+
+	/* Move to the starting point (should be (1, 0)) */
+	move(basey, basex);
+	curx = basex;
+
+	/* Start with some random terrain */
+	if (basex == 0) {
+	    ch = rnd_terrain();
+	    addch(ch);
+	}
+	else ch = CCHAR( mvinch(basey, basex) );
+
+	curx += deltax;
+
+	/* Fill in the rest of the line */
+	while (curx > 0 && curx < COLS-1) {
+	    /* Put in the next piece */
+	    ch = get_terrain(ch, '\0', '\0', '\0');
+	    mvaddch(basey, curx, ch);
+	    curx += deltax;
+	}
+
+	basey++;	/* Advance to next line */
+    }
+
+    /* Fill in the rest of the lines */
+    cury = basey;
+    while (cury > 1 && cury < LINES - 3) {
+	curx = basex;
+	while (curx > 0 && curx < COLS-1) {
+	    register char left, top_left, top, top_right;
+	    register int left_pos, top_pos;
+
+	    /* Get the surrounding terrain */
+	    left_pos = curx - deltax;
+	    top_pos = cury - deltay;
+
+	    left = CCHAR( mvinch(cury, left_pos) );
+	    top_left = CCHAR( mvinch(top_pos, left_pos) );
+	    top = CCHAR( mvinch(top_pos, curx) );
+	    top_right = CCHAR( mvinch(top_pos, curx + deltax) );
+
+	    /* Put the piece of terrain on the map */
+	    mvaddch(cury, curx, get_terrain(left, top_left, top, top_right));
+
+	    /* Get the next x coordinate */
+	    curx += deltax;
+	}
+
+	/* Get the next y coordinate */
+	cury += deltay;
+    }
+    genmonsters(5, (bool) 0);
+}
+
+
+/*
+ * do_paths:
+ *	draw at least a single path-way through the terrain
+ */
+
+
+/*
+ * rnd_terrain:
+ *	return a weighted, random type of outside terrain
+ */
+
+char
+rnd_terrain()
+{
+    int chance = rnd(100);
+
+    /* Forest is most likely */
+    if (chance < 60) return(FOREST);
+
+    /* Next comes meadow */
+    if (chance < 90) return(FLOOR);
+
+    /* Then comes lakes */
+    if (chance < 97) return(POOL);
+
+    /* Finally, mountains */
+    return(WALL);
+}
+
+
+/*
+ * get_terrain:
+ *	return a terrain weighted by what is surrounding
+ */
+
+char
+get_terrain(one, two, three, four)
+char one, two, three, four;
+{
+    register int i;
+    int forest = 0, mountain = 0, lake = 0, meadow = 0, total = 0;
+    char surrounding[4];
+
+    surrounding[0] = one;
+    surrounding[1] = two;
+    surrounding[2] = three;
+    surrounding[3] = four;
+
+    for (i=0; i<4; i++) 
+	switch (surrounding[i]) {
+	    case FOREST:
+		forest++;
+		total++;
+	    
+	    when WALL:
+		mountain++;
+		total++;
+
+	    when POOL:
+		lake++;
+		total++;
+
+	    when FLOOR:
+		meadow++;
+		total++;
+	}
+
+    /* Should we continue mountain? */
+    if (rnd(total+1) < mountain) return(WALL);
+
+    /* Should we continue lakes? */
+    if (rnd(total+1) < lake) return(POOL);
+
+    /* Should we continue meadow? */
+    if (rnd(total+1) < meadow) return(FLOOR);
+
+    /* Should we continue forest? */
+    if (rnd(total+2) < forest) return(FOREST);
+
+    /* Return something random */
+    return(rnd_terrain());
+}
+
+
+/*
+ * lake_check:
+ *	Determine if the player would drown
+ */
+
+void
+lake_check(place)
+coord *place;
+{
+    NOOP(place);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/pack.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,1143 @@
+/*
+ * Routines to deal with the pack
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include <ctype.h>
+#include "rogue.h"
+
+char outstring[512];	/* ridiculously long string for use with msg */
+
+/*
+ * add_pack:
+ *	Pick up an object and add it to the pack.  If the argument is non-null
+ * use it as the linked_list pointer instead of gettting it off the ground.
+ */
+bool
+add_pack(item, silent, packret)
+register struct linked_list *item, **packret;
+bool silent;
+{
+    register struct linked_list *ip, *lp = NULL, *ap;
+    register struct object *obj, *op = NULL;
+    register bool exact, from_floor;
+
+    if (packret != NULL)
+	*packret = NULL;
+    
+    if (item == NULL)
+    {
+	from_floor = TRUE;
+	if ((item = find_obj(hero.y, hero.x)) == NULL)
+	    return(FALSE);
+    }
+    else
+	from_floor = FALSE;
+    obj = OBJPTR(item);
+    /*
+     * If it is gold, just add its value to rogue's purse and get rid
+     * of it.
+     */
+    if (obj->o_type == GOLD) {
+	register struct linked_list *mitem;
+	register struct thing *tp;
+
+	if (!silent) {
+	    if (!terse) addmsg("You found ");
+	    msg("%d gold pieces.", obj->o_count);
+	}
+
+	/* First make sure no greedy monster is after this gold.
+	 * If so, make the monster run after the rogue instead.
+	 */
+	 for (mitem = mlist; mitem != NULL; mitem = next(mitem)) {
+	    tp = THINGPTR(mitem);
+	    if (tp->t_dest == &obj->o_pos) tp->t_dest = &hero;
+	}
+
+	purse += obj->o_count;
+	if (from_floor) {
+	    detach(lvl_obj, item);
+	    if ((ap = find_obj(hero.y, hero.x)) == NULL)
+		mvaddch(hero.y,hero.x,(roomin(&hero)==NULL ? PASSAGE : FLOOR));
+	    else 
+		mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type);
+	}
+	o_discard(item);
+	return(TRUE);
+    }
+
+    /*
+     * see if he can carry any more weight
+     */
+    if (itemweight(obj) + pstats.s_pack > pstats.s_carry) {
+	msg("Too much for you to carry.");
+	return FALSE;
+    }
+    /*
+     * Link it into the pack.  Search the pack for a object of similar type
+     * if there isn't one, stuff it at the beginning, if there is, look for one
+     * that is exactly the same and just increment the count if there is.
+     * it  that.  Food is always put at the beginning for ease of access, but
+     * is not ordered so that you can't tell good food from bad.  First check
+     * to see if there is something in thr same group and if there is then
+     * increment the count.
+     */
+    if (obj->o_group)
+    {
+	for (ip = pack; ip != NULL; ip = next(ip))
+	{
+	    op = OBJPTR(ip);
+	    if (op->o_group == obj->o_group)
+	    {
+		/*
+		 * Put it in the pack and notify the user
+		 */
+		op->o_count += obj->o_count;
+		if (from_floor)
+		{
+		    detach(lvl_obj, item);
+		    if ((ap = find_obj(hero.y, hero.x)) == NULL)
+			mvaddch(hero.y,hero.x,
+				(roomin(&hero)==NULL ? PASSAGE : FLOOR));
+		    else 
+			mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type);
+		}
+		o_discard(item);
+		item = ip;
+		goto picked_up;
+	    }
+	}
+    }
+
+    /*
+     * Check for and deal with scare monster scrolls
+     */
+    if (obj->o_type == SCROLL && obj->o_which == S_SCARE)
+	if (obj->o_flags & ISCURSED)
+	{
+	    msg("The scroll turns to dust as you pick it up.");
+	    detach(lvl_obj, item);
+	    if ((ap = find_obj(hero.y, hero.x)) == NULL)
+		mvaddch(hero.y,hero.x,(roomin(&hero)==NULL ? PASSAGE : FLOOR));
+	    else 
+		mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type);
+	    return(TRUE);
+	}
+
+    /*
+     * Search for an object of the same type
+     */
+    exact = FALSE;
+    for (ip = pack; ip != NULL; ip = next(ip))
+    {
+	op = OBJPTR(ip);
+	if (obj->o_type == op->o_type)
+	    break;
+    }
+    if (ip == NULL)
+    {
+	/*
+	 * Put it at the end of the pack since it is a new type
+	 */
+	for (ip = pack; ip != NULL; ip = next(ip))
+	{
+	    op = OBJPTR(ip);
+	    if (op->o_type != FOOD)
+		break;
+	    lp = ip;
+	}
+    }
+    else
+    {
+	/*
+	 * Search for an object which is exactly the same
+	 */
+	while (ip != NULL && op->o_type == obj->o_type)
+	{
+	    if (op->o_which == obj->o_which)
+	    {
+		exact = TRUE;
+		break;
+	    }
+	    lp = ip;
+	    if ((ip = next(ip)) == NULL)
+		break;
+	    op = OBJPTR(ip);
+	}
+    }
+    /*
+     * Check if there is room
+     */
+    if (ip == NULL || !exact || !ISMULT(obj->o_type)) {
+	if (inpack == MAXPACK-1) {
+	    msg(terse ? "No room." : "You can't carry anything else.");
+	    return(FALSE);
+	}
+    }
+    inpack++;
+    if (from_floor)
+    {
+	detach(lvl_obj, item);
+	if ((ap = find_obj(hero.y, hero.x)) == NULL)
+	    mvaddch(hero.y,hero.x,(roomin(&hero)==NULL ? PASSAGE : FLOOR));
+	else 
+	    mvaddch(hero.y,hero.x,(OBJPTR(ap))->o_type);
+    }
+    if (ip == NULL)
+    {
+	/*
+	 * Didn't find an exact match, just stick it here
+	 */
+	if (pack == NULL)
+	    pack = item;
+	else
+	{
+	    lp->l_next = item;
+	    item->l_prev = lp;
+	    item->l_next = NULL;
+	}
+    }
+    else
+    {
+	/*
+	 * If we found an exact match.  If it is food,
+	 * increase the count, otherwise put it with its clones.
+	 */
+	if (exact && ISMULT(obj->o_type))
+	{
+	    op->o_count += obj->o_count;
+	    inpack--;			/* adjust for previous addition */
+	    o_discard(item);
+	    item = ip;
+	    goto picked_up;
+	}
+	if ((item->l_prev = prev(ip)) != NULL)
+	    item->l_prev->l_next = item;
+	else
+	    pack = item;
+	item->l_next = ip;
+	ip->l_prev = item;
+    }
+picked_up:
+    /*
+     * Notify the user
+     */
+    obj = OBJPTR(item);
+    if (!silent)
+    {
+	if (!terse)
+	    addmsg("You now have ");
+	sprintf(outstring,"%s (%c)", inv_name(obj, !terse), pack_char(pack, obj));
+	msg(outstring);
+    }
+
+    /* Relics can do strange things when you pick them up */
+    if (obj->o_type == RELIC) {
+	cur_relic[obj->o_which]++;	/* Note that we have it */
+	switch (obj->o_which) {
+	    case HEIL_ANKH:
+		msg("The ankh welds itself into your hand.");
+
+	    /* A cloak must be worn. */
+	    when EMORI_CLOAK:
+		if (cur_armor != NULL || cur_misc[WEAR_CLOAK]) {
+		    msg("The cloak insists you remove your current garments.");
+		    if (!dropcheck(cur_armor != NULL ? cur_armor
+						     : cur_misc[WEAR_CLOAK])) {
+			pstats.s_hpt = -1;
+			msg("The cloak constricts around you.");
+			msg("It draws your life force from you!!! -- More --");
+			wait_for(cw,' ');
+			death(D_RELIC);
+		    }
+		}
+
+	    /* The amulet must be worn. */
+	    when YENDOR_AMULET:
+		if (cur_misc[WEAR_JEWEL]) {
+		    msg("You have an urge to remove your current amulet.");
+		    if (!dropcheck(cur_misc[WEAR_JEWEL])) {
+			pstats.s_hpt = -1;
+			msg("The Amulet of Yendor begins pulsing.");
+			msg("It fades away.... -- More --");
+			wait_for(cw,' ');
+			death(D_RELIC);
+		    }
+		}
+		msg("The amulet welds itself into your chest.");
+
+	    /* Weapons will insist on being wielded. */
+	    when MUSTY_DAGGER:
+	    case HRUGGEK_MSTAR:
+	    case YEENOGHU_FLAIL:
+		if (cur_weapon != NULL) {
+		    msg("The artifact insists you release your current weapon.");
+		    if (!dropcheck(cur_weapon)) {
+			pstats.s_hpt = -1;
+			msg("The artifact forces your weapon into your heart.");
+			msg("It hums with satisfaction. -- More --");
+			wait_for(cw,' ');
+			death(D_RELIC);
+		    }
+		}
+		cur_weapon = obj;
+	}
+    }
+
+    updpack(FALSE);
+    if (packret != NULL)
+	*packret = item;
+    return(TRUE);
+}
+
+/*
+ * inventory:
+ *	list what is in the pack
+ */
+inventory(list, type)
+register struct linked_list *list;
+register int type;
+{
+    register struct object *obj;
+    register char ch;
+    register int n_objs;
+    register int cnt;
+    char inv_temp[LINELEN];
+
+    cnt = 0;
+    n_objs = 0;
+    for (ch = 'a'; list != NULL; ch++, list = next(list)) {
+	obj = OBJPTR(list);
+	if (!is_type(obj, type))
+	    continue;
+	switch (n_objs++) {
+	    /*
+	     * For the first thing in the inventory, just save the string
+	     * in case there is only one.
+	     */
+	    case 0:
+		sprintf(inv_temp, "%c) %s", ch, inv_name(obj, FALSE));
+		break;
+	    /*
+	     * If there is more than one, clear the screen, print the
+	     * saved message and fall through to ...
+	     */
+	    case 1:
+		if (slow_invent)
+		    msg(inv_temp);
+		else
+		{
+		    wclear(hw);
+		    waddstr(hw, inv_temp);
+		    waddch(hw, '\n');
+		}
+	    /*
+	     * Print the line for this object
+	     */
+	    default:
+		if (ch > 'z')
+		    ch = 'A';
+		if (slow_invent){
+		    sprintf(outstring,"%c) %s", ch, inv_name(obj, FALSE));
+		    msg(outstring);
+		}
+		else {
+		    if (++cnt >= LINES - 2) { /* if bottom of screen */
+			dbotline(hw, morestr);
+			cnt = 0;
+			wclear(hw);
+		    }
+		    wprintw(hw, "%c) %s\n", ch, inv_name(obj, FALSE));
+		}
+	}
+    }
+    if (n_objs == 0) {
+	if (terse)
+	    msg(type == 0 ? "Empty handed." :
+			    "Nothing appropriate");
+	else
+	    msg(type == 0 ? "You are empty handed." :
+			    "You don't have anything appropriate");
+	return FALSE;
+    }
+    if (n_objs == 1) {
+	msg(inv_temp);
+	return TRUE;
+    }
+    if (!slow_invent)
+    {
+	mvwaddstr(hw, LINES-1, 0, spacemsg);
+	draw(hw);
+	wait_for(hw,' ');
+	clearok(cw, TRUE);
+	touchwin(cw);
+    }
+    return TRUE;
+}
+
+/*
+ * pick_up:
+ *	Add something to characters pack.
+ */
+pick_up(ch)
+char ch;
+{
+    switch (ch) {
+	default:
+	    debug("Where did you pick that up???");
+	case GOLD:
+	case ARMOR:
+	case POTION:
+	case FOOD:
+	case WEAPON:
+	case SCROLL:	
+	case MM:
+	case RING:
+	case STICK:
+	case RELIC:
+	    while (add_pack(NULL, FALSE, NULL));	/* pick up everything there */
+	    break;
+    }
+}
+
+/*
+ * picky_inven:
+ *	Allow player to inventory a single item
+ */
+void
+picky_inven()
+{
+    register struct linked_list *item;
+    register char ch, mch;
+
+    if (pack == NULL)
+	msg("You aren't carrying anything");
+    else if (next(pack) == NULL)
+	msg("a) %s", inv_name(OBJPTR(pack), FALSE));
+    else
+    {
+	msg(terse ? "Item: " : "Which item do you wish to inventory: ");
+	mpos = 0;
+	if ((mch = readchar()) == ESCAPE)
+	{
+	    msg("");
+	    return;
+	}
+
+	/* Check for a special character */
+	switch (mch) {
+	    case FOOD:
+	    case SCROLL:
+	    case POTION:
+	    case RING:
+	    case STICK:
+	    case RELIC:
+	    case ARMOR:
+	    case WEAPON:
+	    case MM:
+		msg("");
+		if (get_item(pack, NULL, mch) == NULL) {
+		    if (terse) msg("None in pack.");
+		    else msg("You have no %c in your pack.", mch);
+		}
+		return;
+	}
+
+	for (ch = 'a', item = pack; item != NULL; item = next(item), ch++)
+	    if (ch == mch)
+	    {
+		sprintf(outstring, "%c) %s",ch ,inv_name(OBJPTR(item), FALSE));
+		msg(outstring);
+		return;
+	    }
+	if (!terse)
+	    msg("'%s' not in pack.", unctrl(mch));
+	msg("Range is 'a' to '%c'", --ch);
+    }
+}
+
+
+/*
+ * get_item:
+ *	pick something out of a pack for a purpose
+ */
+struct linked_list *
+get_item(list, purpose, type)
+reg struct linked_list *list;
+char *purpose;	/* NULL if we should be silent (no prompts) */
+int type;
+{
+    reg struct linked_list *item;
+    reg struct object *obj;
+    reg int cnt, ch, och;
+    struct linked_list *saveitem = NULL;
+
+    cnt = 0;
+    if (list == NULL) {
+	msg("You aren't carrying anything.");
+	return NULL;
+    }
+    /* see if we have any of the type requested */
+    for(ch = 'a',item = list ; item != NULL ; item = next(item), ch++) {
+	obj = OBJPTR(item);
+	if (is_type(obj, type)) {
+	    cnt++;
+	    saveitem = item;
+	}
+    }
+    if (cnt == 0) {
+	if (purpose) msg("Nothing to %s",purpose);
+	after = FALSE;
+	return NULL;
+    }
+    else if (cnt == 1) {	/* only found one of 'em */
+	obj = OBJPTR(saveitem);
+	for(;;)  {
+	    if (purpose) {	/* Should we prompt the player? */
+		msg("%s what (* for the item)? ",purpose);
+		ch = tolower(readchar());
+	    }
+	    else {
+		sprintf(outstring, "%c) %s", pack_char(list, obj), inv_name(obj,FALSE));
+		msg(outstring);
+	    }
+
+	    if (ch == '*') {
+		mpos = 0;
+		sprintf(outstring, "%c) %s", pack_char(list, obj), inv_name(obj,FALSE));
+		msg(outstring);
+		continue;
+	    }
+	    if (ch == ESCAPE) {
+		msg("");
+		after = FALSE;
+		return NULL;
+	    }
+	    for(item = list,och = 'a'; item != NULL; item = next(item),och++) {
+		if (ch == och) break;
+		if (och == 'z') och = 'A' - 1;
+	    }
+	    if (item == NULL) {
+		msg("Please specify a letter between 'a' and '%c'",
+		    och == 'A' ? 'z' : och-1);
+		continue;
+	    }
+	    if (is_type (OBJPTR(item), type)) {
+		if (purpose) mpos = 0;
+		return item;
+	    }
+	    else
+		msg ("You can't %s that!", purpose);
+
+	} 
+    }
+    for(;;) {
+	if (purpose) {
+	    msg("%s what? (* for list): ",purpose);
+	    ch = readchar();
+	}
+	else ch = '*';
+
+	mpos = 0;
+	if (ch == ESCAPE) {		/* abort if escape hit */
+	    after = FALSE;
+	    msg("");		/* clear display */
+	    return NULL;
+	}
+	if (ch == '*') {
+	    wclear(hw);
+	    cnt = 0;
+	    for(item = list,ch = 'a'; item != NULL ; item = next(item), ch++) {
+		obj = OBJPTR(item);
+		if (!is_type(OBJPTR(item), type))
+		    continue;
+		wprintw(hw,"%c) %s\n\r",ch,inv_name(obj,FALSE));
+		if (++cnt >= LINES - 2 && next(item) != NULL) {
+		    cnt = 0;
+		    dbotline(hw, spacemsg);
+		    wclear(hw);
+		}
+		if (ch == 'z') ch = 'A' - 1;
+	    }
+	    wmove(hw, LINES - 1,0);
+	    if (purpose) wprintw(hw,"%s what? ",purpose);
+	    else waddstr(hw, spacemsg);
+
+	    draw(hw);		/* write screen */
+
+	    if (purpose) {
+		do {
+		    ch = tolower(wgetch(hw));
+		} until (isalpha(ch) || ch == ESCAPE);
+	    }
+	    else {
+		ch = pack_char(list, OBJPTR(saveitem)); /* Pick a valid item */
+		wait_for(hw,' ');
+	    }
+
+	    restscr(cw);		/* redraw orig screen */
+	    if(ch == ESCAPE) {
+		after = FALSE;
+		msg("");		/* clear top line */
+		return NULL;	/* all done if abort */
+	    }
+	    /* ch has item to get from list */
+	}
+	for(item = list,och = 'a'; item != NULL; item = next(item),och++) {
+	    if (ch == och) break;
+	    if (och == 'z') och = 'A' - 1;
+	}
+	if (item == NULL) {
+	    msg("Please specify a letter between 'a' and '%c'",
+		och == 'A' ? 'z' : och-1);
+	    continue;
+	}
+	if (is_type(OBJPTR(item), type))
+	    return (item);
+	else
+	    msg ("You can't %s that!", purpose);
+    }
+}
+
+pack_char(list, obj)
+register struct object *obj;
+struct linked_list *list;
+{
+    register struct linked_list *item;
+    register char c;
+
+    c = 'a';
+    for (item = list; item != NULL; item = next(item)) {
+	if (OBJPTR(item) == obj)
+	    return c;
+	else {
+	    if (c == 'z') c = 'A';
+	    else c++;
+	}
+    }
+    return 'z';
+}
+
+
+/*
+ * cur_null:
+ *	This updates cur_weapon etc for dropping things
+ */
+cur_null(op)
+reg struct object *op;
+{
+	if (op == cur_weapon)			cur_weapon = NULL;
+	else if (op == cur_armor)		cur_armor = NULL;
+	else if (op == cur_ring[LEFT_1])	cur_ring[LEFT_1] = NULL;
+	else if (op == cur_ring[LEFT_2])	cur_ring[LEFT_2] = NULL;
+	else if (op == cur_ring[LEFT_3])	cur_ring[LEFT_3] = NULL;
+	else if (op == cur_ring[LEFT_4])	cur_ring[LEFT_4] = NULL;
+	else if (op == cur_ring[RIGHT_1])	cur_ring[RIGHT_1] = NULL;
+	else if (op == cur_ring[RIGHT_2])	cur_ring[RIGHT_2] = NULL;
+	else if (op == cur_ring[RIGHT_3])	cur_ring[RIGHT_3] = NULL;
+	else if (op == cur_ring[RIGHT_4])	cur_ring[RIGHT_4] = NULL;
+	else if (op == cur_misc[WEAR_BOOTS])	cur_misc[WEAR_BOOTS] = NULL;
+	else if (op == cur_misc[WEAR_JEWEL])	cur_misc[WEAR_JEWEL] = NULL;
+	else if (op == cur_misc[WEAR_GAUNTLET]) cur_misc[WEAR_GAUNTLET] = NULL;
+	else if (op == cur_misc[WEAR_CLOAK])	cur_misc[WEAR_CLOAK] = NULL;
+	else if (op == cur_misc[WEAR_BRACERS])	cur_misc[WEAR_BRACERS] = NULL;
+	else if (op == cur_misc[WEAR_NECKLACE]) cur_misc[WEAR_NECKLACE] = NULL;
+}
+
+/*
+ * idenpack:
+ *	Identify all the items in the pack
+ */
+idenpack()
+{
+	reg struct linked_list *pc;
+
+	for (pc = pack ; pc != NULL ; pc = next(pc))
+		whatis(pc);
+}
+
+is_type (obj, type)
+register struct object *obj;
+register int type;
+{
+    register bool current;
+
+    if (type == obj->o_type)
+	return (TRUE);
+
+    switch (type) {
+	case ALL:
+	    return (TRUE);
+	when ZAPPABLE:
+	    if (obj->o_type == STICK) return (TRUE);
+	    if (obj->o_type == RELIC)
+		switch (obj->o_which) {
+		    case MING_STAFF:
+		    case ASMO_ROD:
+		    case ORCUS_WAND:
+			return (TRUE);
+		}
+	when WEARABLE:
+	case REMOVABLE:
+	    current = is_current(obj);
+
+	    /*
+	     * Don't wear thing we are already wearing or remove things
+	     * we aren't wearing.
+	     */
+	    if (type == WEARABLE && current) return (FALSE);
+	    else if (type == REMOVABLE && !current) return (FALSE);
+
+	    switch (obj->o_type) {
+		case RELIC:
+		    switch (obj->o_which) {
+			case HEIL_ANKH:
+			case EMORI_CLOAK:
+			    return (TRUE);
+		    }
+		when MM:
+		    switch (obj->o_which) {
+			case MM_ELF_BOOTS:
+			case MM_DANCE:
+			case MM_BRACERS:
+			case MM_DISP:
+			case MM_PROTECT:
+			case MM_G_DEXTERITY:
+			case MM_G_OGRE:
+			case MM_JEWEL:
+			case MM_R_POWERLESS:
+			case MM_FUMBLE:
+			case MM_STRANGLE:
+			case MM_ADAPTION:
+			    return (TRUE);
+		    }
+		when ARMOR:
+		case RING:
+		    return (TRUE);
+	    }
+	when CALLABLE:
+	    switch (obj->o_type) {
+	    case RING:
+	    case POTION:
+	    case STICK:
+	    case SCROLL:
+	    case MM:
+		return(TRUE);
+	    }
+	when WIELDABLE:
+	    switch (obj->o_type) {
+		case STICK:
+		case WEAPON:
+		    return(TRUE);
+		when RELIC:
+		    switch (obj->o_which) {
+			case MUSTY_DAGGER:
+			case HRUGGEK_MSTAR:
+			case YEENOGHU_FLAIL:
+			case MING_STAFF:
+			case ORCUS_WAND:
+			case ASMO_ROD:
+			    return(TRUE);
+		    }
+	    }
+	when IDENTABLE:
+	    if (!(obj->o_flags & ISKNOW) && obj->o_type != FOOD)
+		return (TRUE);
+	    if (obj->o_type == MM) {
+	      switch (obj->o_which) {
+		case MM_JUG:
+		    /* Can still identify a jug if we don't know the potion */
+		    if (obj->o_ac != JUG_EMPTY && !p_know[obj->o_ac])
+			return (TRUE);
+	      }
+	    }
+	when USEABLE:
+	    if (obj->o_type == MM) {
+		switch(obj->o_which) {
+		case MM_JUG:
+		case MM_BEAKER:
+		case MM_BOOK:
+		case MM_SKILLS:
+		case MM_OPEN:
+		case MM_HUNGER:
+		case MM_DRUMS:
+		case MM_DISAPPEAR:
+		case MM_CHOKE:
+		case MM_KEOGHTOM:
+		    return (TRUE);
+		}
+	    }
+	    else if (obj->o_type == RELIC) {
+		switch (obj->o_which) {
+		    case EMORI_CLOAK:
+		    case BRIAN_MANDOLIN:
+		    case HEIL_ANKH:
+		    case YENDOR_AMULET:
+		    case GERYON_HORN:
+			return (TRUE);
+		}
+	    }
+	when PROTECTABLE:
+	    switch (obj->o_type) {
+		case WEAPON:
+		    if ((obj->o_flags & ISMETAL) == 0) return (FALSE);
+
+		    /* Fall through */
+		case ARMOR:
+		    return (TRUE);
+
+		when MM:
+		    if (obj->o_which == MM_BRACERS) return (TRUE);
+	    }
+    }
+    return(FALSE);
+}
+
+del_pack(item)
+register struct linked_list *item;
+{
+    register struct object *obj;
+
+    obj = OBJPTR(item);
+    if (obj->o_count > 1) {
+	obj->o_count--;
+    }
+    else {
+	cur_null(obj);
+	detach(pack, item);
+	o_discard(item);
+	inpack--;
+    }
+}
+
+/*
+ * carry_obj:
+ *	Check to see if a monster is carrying something and, if so, give
+ * it to him.
+ */
+
+carry_obj(mp, chance)
+register struct thing *mp;
+int chance;
+{
+    reg struct linked_list *item;
+    reg struct object *obj;
+
+    /* 
+     * If there is no chance, just return.
+     * Note that this means there must be a "chance" in order for
+     * the creature to carry a relic.
+     */
+    if (chance <= 0) return;
+
+    /* 
+     * check for the relic/artifacts 
+     * Do the relics first so they end up last in the pack. Attach()
+     * always adds things to the beginning. This way they will be the
+     * last things dropped when the creature is killed. This will ensure
+     * the relic will be on top if there is a stack of item lying on the
+     * floor and so the hero will know where it is if he's trying to
+     * avoid it
+     */
+    if (on(*mp, CARRYDAGGER)) {
+	item = spec_item(RELIC, MUSTY_DAGGER, NULL, NULL);
+	obj = OBJPTR(item);
+	obj->o_pos = mp->t_pos;
+	attach(mp->t_pack, item);
+    }
+
+    if (on(*mp, CARRYCLOAK)) {
+	item = spec_item(RELIC, EMORI_CLOAK, NULL, NULL);
+	obj = OBJPTR(item);
+	obj->o_pos = mp->t_pos;
+	attach(mp->t_pack, item);
+    }
+
+    if (on(*mp, CARRYANKH)) {
+	item = spec_item(RELIC, HEIL_ANKH, NULL, NULL);
+	obj = OBJPTR(item);
+	obj->o_pos = mp->t_pos;
+	attach(mp->t_pack, item);
+    }
+
+    if (on(*mp, CARRYSTAFF)) {
+	item = spec_item(RELIC, MING_STAFF, NULL, NULL);
+	obj = OBJPTR(item);
+	obj->o_pos = mp->t_pos;
+	attach(mp->t_pack, item);
+    }
+
+    if (on(*mp, CARRYWAND)) {
+	item = spec_item(RELIC, ORCUS_WAND, NULL, NULL);
+	obj = OBJPTR(item);
+	obj->o_pos = mp->t_pos;
+	attach(mp->t_pack, item);
+    }
+
+    if (on(*mp, CARRYROD)) {
+	item = spec_item(RELIC, ASMO_ROD, NULL, NULL);
+	obj = OBJPTR(item);
+	obj->o_pos = mp->t_pos;
+	attach(mp->t_pack, item);
+    }
+
+    if (on(*mp, CARRYAMULET)) {
+	item = spec_item(RELIC, YENDOR_AMULET, NULL, NULL);
+	obj = OBJPTR(item);
+	obj->o_pos = mp->t_pos;
+	attach(mp->t_pack, item);
+    }
+
+    if (on(*mp, CARRYMANDOLIN)) {
+	item = spec_item(RELIC, BRIAN_MANDOLIN, NULL, NULL);
+	obj = OBJPTR(item);
+	obj->o_pos = mp->t_pos;
+	attach(mp->t_pack, item);
+    }
+    if (on(*mp, CARRYMSTAR)) {
+	item = spec_item(RELIC, HRUGGEK_MSTAR, NULL, NULL);
+	obj = OBJPTR(item);
+	obj->o_pos = mp->t_pos;
+	attach(mp->t_pack, item);
+    }
+    if (on(*mp, CARRYFLAIL)) {
+	item = spec_item(RELIC, YEENOGHU_FLAIL, NULL, NULL);
+	obj = OBJPTR(item);
+	obj->o_pos = mp->t_pos;
+	attach(mp->t_pack, item);
+    }
+    if (on(*mp, CARRYHORN)) {
+	item = spec_item(RELIC, GERYON_HORN, NULL, NULL);
+	obj = OBJPTR(item);
+	obj->o_pos = mp->t_pos;
+	attach(mp->t_pack, item);
+    }
+    /*
+     * If it carries gold, give it some
+     */
+    if (on(*mp, CARRYGOLD) && rnd(100) < chance) {
+	    item = spec_item(GOLD, NULL, NULL, NULL);
+	    obj = OBJPTR(item);
+	    obj->o_count = GOLDCALC + GOLDCALC;
+	    obj->o_pos = mp->t_pos;
+	    attach(mp->t_pack, item);
+    }
+
+    /*
+     * If it carries food, give it some
+     */
+    if (on(*mp, CARRYFOOD) && rnd(100) < chance) {
+	item = spec_item(FOOD, NULL, NULL, NULL);
+	obj = OBJPTR(item);
+	obj->o_weight = things[TYP_FOOD].mi_wght;
+	obj->o_pos = mp->t_pos;
+	attach(mp->t_pack, item);
+    }
+
+    /*
+     * If it carries a weapon, give it one
+     */
+    if (on(*mp, CARRYWEAPON) && rnd(100) < chance) {
+	int type, hit, dam;
+
+	/* Get the "bonuses" */
+	hit = rnd(5) - 2;
+	dam = rnd(5) - 2;
+
+	/* Only choose an appropriate type of weapon */
+	switch (rnd(11)) {
+	    case 0: type = DAGGER;
+	    when 1: type = BATTLEAXE;
+	    when 2: type = MACE;
+	    when 3: type = SWORD;
+	    when 4: type = PIKE;
+	    when 5: type = HALBERD;
+	    when 6: type = SPETUM;
+	    when 7: type = BARDICHE;
+	    when 8: type = TRIDENT;
+	    when 9: type = BASWORD;
+	    otherwise: type = TWOSWORD;
+	}
+
+	/* Create the item */
+	item = spec_item(WEAPON, type, hit, dam);
+	obj = OBJPTR(item);
+	obj->o_pos = mp->t_pos;
+	attach(mp->t_pack, item);
+    }
+
+    /*
+     * If it carries a scroll, give it one
+     */
+    if (on(*mp, CARRYSCROLL) && rnd(100) < chance) {
+	item = new_thing(TYP_SCROLL);
+	obj = OBJPTR(item);
+	obj->o_pos = mp->t_pos;
+
+	/* Can the monster carry this scroll? */
+	if (obj->o_which == S_SCARE && mp->t_stats.s_intel < 16)
+	    fall(item, FALSE);	/* This would scare us! */
+	else attach(mp->t_pack, item);
+    }
+
+    /*
+     * If it carries a potion, give it one
+     */
+    if (on(*mp, CARRYPOTION) && rnd(100) < chance) {
+	item = new_thing(TYP_POTION);
+	obj = OBJPTR(item);
+	obj->o_pos = mp->t_pos;
+	attach(mp->t_pack, item);
+    }
+
+    /*
+     * If it carries a ring, give it one
+     */
+    if (on(*mp, CARRYRING) && rnd(100) < chance) {
+	item = new_thing(TYP_RING);
+	obj = OBJPTR(item);
+	obj->o_pos = mp->t_pos;
+	attach(mp->t_pack, item);
+    }
+
+    /*
+     * If it carries a wand or staff, give it one
+     */
+    if (on(*mp, CARRYSTICK) && rnd(100) < chance) {
+	item = new_thing(TYP_STICK);
+	obj = OBJPTR(item);
+	obj->o_pos = mp->t_pos;
+	attach(mp->t_pack, item);
+    }
+
+    /*
+     * If it carries any miscellaneous magic, give it one
+     */
+    if (on(*mp, CARRYMISC) && rnd(100) < chance) {
+	item = new_thing(TYP_MM);
+	obj = OBJPTR(item);
+	obj->o_pos = mp->t_pos;
+	attach(mp->t_pack, item);
+    }
+}
+
+
+/*
+ * grab():
+ *	See what is on the spot where the player is standing.  If
+ *	nothing is there, do nothing.  If there is one thing, pick it
+ *	up.  If there are multiple things, prompt the player for what
+ *	he wants (* means everything).
+ */
+
+grab(y, x)
+register y, x;
+{
+    register struct linked_list *next_item, *item;
+    register struct object *obj;
+    register int cnt;
+    int num_there = 0, ch, och;
+
+    /*
+     * Count how many objects there are and move them to the front
+     * of the level list.
+     */
+    for (item = lvl_obj; item != NULL; item = next_item) {
+	obj = OBJPTR(item);
+	next_item = next(item);
+	if (obj->o_pos.y == y && obj->o_pos.x == x) {
+	    num_there++;
+	    detach(lvl_obj, item);	/* Remove it from the list */
+	    attach(lvl_obj, item);	/* Place it at the front of the list */
+	}
+    }
+
+    /* Nothing there. */
+    if (num_there < 1) msg("Nothing %s", terse ? "there." : "to pick up.");
+
+    /* One thing there */
+    else if (num_there == 1) {
+	add_pack(FALSE, FALSE, NULL);
+	return(1);
+    }
+
+    /* Multiple things there */
+    else {
+	wclear(hw);
+	cnt = 0;
+	for (item = lvl_obj, ch = 'a'; item != NULL && cnt < num_there;
+	     item = next(item), ch++) {
+	    obj = OBJPTR(item);
+	    wprintw(hw,"%c) %s\n\r", ch, inv_name(obj,FALSE));
+	    if (++cnt >= LINES - 2 && next(item) != NULL) {
+		cnt = 0;
+		dbotline(hw, spacemsg);
+		wclear(hw);
+	    }
+	    if (ch == 'z') ch = 'A' - 1;
+	}
+	wmove(hw, LINES - 1,0);
+	wprintw(hw, "Pick up what? (* for all): ");
+	draw(hw);		/* write screen */
+
+	for (;;) {
+	    do {
+		ch = tolower(wgetch(hw));
+	    } until (isalpha(ch) || ch == '*' || ch == ESCAPE);
+	    restscr(cw);		/* redraw orig screen */
+	    if (ch == ESCAPE) {
+		after = FALSE;
+		msg("");		/* clear top line */
+		break;
+	    }
+	    if (ch == '*') {
+		while (add_pack(NULL, TRUE, NULL));	/* pick up everything there */
+		return(num_there);
+	    }
+	    /* ch has item to get from list */
+
+	    cnt = 0;
+	    for (item = lvl_obj, och = 'a'; item != NULL && cnt < num_there;
+		 item = next(item), och++, cnt++) {
+		if (ch == och)
+		    break;
+		if (och == 'z') och = 'A' - 1;
+	    }
+	    if (item == NULL || cnt >= num_there) {
+		wmove(hw, LINES - 1, 25);
+		wprintw(hw, " [between 'a' and '%c']:%c ",
+		    och == 'A' ? 'z' : och-1, '\007');
+		draw(hw);		/* write screen */
+		continue;
+	    }
+	    else {
+		detach(lvl_obj, item);
+		if (add_pack(item, FALSE, NULL)) {
+		    /*
+		     * There should always be at least one item left since we
+		     * handle the one item case up above.  But it never hurts
+		     * to make sure we don't have a NULL pointer.
+		     */
+		    if ((item = find_obj(hero.y, hero.x)) == NULL)
+			mvaddch(y, x, (OBJPTR(item))->o_type);
+		    return(1);
+		}
+		else attach(lvl_obj, item);	/* Couldn't pick it up! */
+		break;
+	    }
+	}
+    }
+
+    return(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/passages.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,284 @@
+/*
+ * Draw the connecting passages
+ *
+ * @(#)passages.c	3.4 (Berkeley) 6/15/81
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include "rogue.h"
+
+/*
+ * do_passages:
+ *	Draw all the passages on a level.
+ */
+
+do_passages()
+{
+    register struct rdes *r1, *r2 = NULL;
+    register int i, j;
+    register int roomcount;
+    static struct rdes
+    {
+	bool	conn[MAXROOMS];		/* possible to connect to room i? */
+	bool	isconn[MAXROOMS];	/* connection been made to room i? */
+	bool	ingraph;		/* this room in graph already? */
+    } rdes[MAXROOMS] = {
+	{ { 0, 1, 0, 1, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
+	{ { 1, 0, 1, 0, 1, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
+	{ { 0, 1, 0, 0, 0, 1, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
+	{ { 1, 0, 0, 0, 1, 0, 1, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
+	{ { 0, 1, 0, 1, 0, 1, 0, 1, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
+	{ { 0, 0, 1, 0, 1, 0, 0, 0, 1 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
+	{ { 0, 0, 0, 1, 0, 0, 0, 1, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
+	{ { 0, 0, 0, 0, 1, 0, 1, 0, 1 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
+	{ { 0, 0, 0, 0, 0, 1, 0, 1, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
+    };
+
+    /*
+     * reinitialize room graph description
+     */
+    for (r1 = rdes; r1 <= &rdes[MAXROOMS-1]; r1++)
+    {
+	for (j = 0; j < MAXROOMS; j++)
+	    r1->isconn[j] = FALSE;
+	r1->ingraph = FALSE;
+    }
+
+    /*
+     * starting with one room, connect it to a random adjacent room and
+     * then pick a new room to start with.
+     */
+    roomcount = 1;
+    r1 = &rdes[rnd(MAXROOMS)];
+    r1->ingraph = TRUE;
+    do
+    {
+	/*
+	 * find a room to connect with
+	 */
+	j = 0;
+	for (i = 0; i < MAXROOMS; i++)
+	    if (r1->conn[i] && !rdes[i].ingraph && rnd(++j) == 0)
+		r2 = &rdes[i];
+	/*
+	 * if no adjacent rooms are outside the graph, pick a new room
+	 * to look from
+	 */
+	if (j == 0)
+	{
+	    do
+		r1 = &rdes[rnd(MAXROOMS)];
+	    until (r1->ingraph);
+	}
+	/*
+	 * otherwise, connect new room to the graph, and draw a tunnel
+	 * to it
+	 */
+	else
+	{
+	    r2->ingraph = TRUE;
+	    i = (int)(r1 - rdes);
+	    j = (int)(r2 - rdes);
+	    conn(i, j);
+	    r1->isconn[j] = TRUE;
+	    r2->isconn[i] = TRUE;
+	    roomcount++;
+	}
+    } while (roomcount < MAXROOMS);
+
+    /*
+     * attempt to add passages to the graph a random number of times so
+     * that there isn't just one unique passage through it.
+     */
+    for (roomcount = rnd(5); roomcount > 0; roomcount--)
+    {
+	r1 = &rdes[rnd(MAXROOMS)];	/* a random room to look from */
+	/*
+	 * find an adjacent room not already connected
+	 */
+	j = 0;
+	for (i = 0; i < MAXROOMS; i++)
+	    if (r1->conn[i] && !r1->isconn[i] && rnd(++j) == 0)
+		r2 = &rdes[i];
+	/*
+	 * if there is one, connect it and look for the next added
+	 * passage
+	 */
+	if (j != 0)
+	{
+	    i = (int)(r1 - rdes);
+	    j = (int)(r2 - rdes);
+	    conn(i, j);
+	    r1->isconn[j] = TRUE;
+	    r2->isconn[i] = TRUE;
+	}
+    }
+}
+
+/*
+ * conn:
+ *	Draw a corridor from a room in a certain direction.
+ */
+
+conn(r1, r2)
+int r1, r2;
+{
+    register struct room *rpf, *rpt = NULL;
+    register char rmt;
+    register int distance = 0, turn_spot = 0, turn_distance = 0;
+    register int rm;
+    register char direc;
+    coord delta = { 0, 0 }, curr, turn_delta = { 0, 0 }, spos = { 0, 0 }, epos = { 0, 0 };
+
+    if (r1 < r2)
+    {
+	rm = r1;
+	if (r1 + 1 == r2)
+	    direc = 'r';
+	else
+	    direc = 'd';
+    }
+    else
+    {
+	rm = r2;
+	if (r2 + 1 == r1)
+	    direc = 'r';
+	else
+	    direc = 'd';
+    }
+    rpf = &rooms[rm];
+    /*
+     * Set up the movement variables, in two cases:
+     * first drawing one down.
+     */
+    if (direc == 'd')
+    {
+	rmt = rm + 3;				/* room # of dest */
+	rpt = &rooms[rmt];			/* room pointer of dest */
+	delta.x = 0;				/* direction of move */
+	delta.y = 1;
+	spos.x = rpf->r_pos.x;			/* start of move */
+	spos.y = rpf->r_pos.y;
+	epos.x = rpt->r_pos.x;			/* end of move */
+	epos.y = rpt->r_pos.y;
+	if (!(rpf->r_flags & ISGONE))		/* if not gone pick door pos */
+	{
+	    spos.x += rnd(rpf->r_max.x-2)+1;
+	    spos.y += rpf->r_max.y-1;
+	}
+	if (!(rpt->r_flags & ISGONE))
+	    epos.x += rnd(rpt->r_max.x-2)+1;
+	distance = abs(spos.y - epos.y) - 1;	/* distance to move */
+	turn_delta.y = 0;			/* direction to turn */
+	turn_delta.x = (spos.x < epos.x ? 1 : -1);
+	turn_distance = abs(spos.x - epos.x);	/* how far to turn */
+	turn_spot = rnd(distance-1) + 1;		/* where turn starts */
+    }
+    else if (direc == 'r')			/* setup for moving right */
+    {
+	rmt = rm + 1;
+	rpt = &rooms[rmt];
+	delta.x = 1;
+	delta.y = 0;
+	spos.x = rpf->r_pos.x;
+	spos.y = rpf->r_pos.y;
+	epos.x = rpt->r_pos.x;
+	epos.y = rpt->r_pos.y;
+	if (!(rpf->r_flags & ISGONE))
+	{
+	    spos.x += rpf->r_max.x-1;
+	    spos.y += rnd(rpf->r_max.y-2)+1;
+	}
+	if (!(rpt->r_flags & ISGONE))
+	    epos.y += rnd(rpt->r_max.y-2)+1;
+	distance = abs(spos.x - epos.x) - 1;
+	turn_delta.y = (spos.y < epos.y ? 1 : -1);
+	turn_delta.x = 0;
+	turn_distance = abs(spos.y - epos.y);
+	turn_spot = rnd(distance-1) + 1;
+    }
+    else
+	debug("error in connection tables");
+    /*
+     * Draw in the doors on either side of the passage or just put #'s
+     * if the rooms are gone.
+     */
+    if (!(rpf->r_flags & ISGONE)) door(rpf, &spos);
+    else
+    {
+	cmov(spos);
+	addch('#');
+    }
+    if (!(rpt->r_flags & ISGONE)) door(rpt, &epos);
+    else
+    {
+	cmov(epos);
+	addch('#');
+    }
+    /*
+     * Get ready to move...
+     */
+    curr.x = spos.x;
+    curr.y = spos.y;
+    while(distance)
+    {
+	/*
+	 * Move to new position
+	 */
+	curr.x += delta.x;
+	curr.y += delta.y;
+	/*
+	 * Check if we are at the turn place, if so do the turn
+	 */
+	if (distance == turn_spot && turn_distance > 0)
+	    while(turn_distance--)
+	    {
+		cmov(curr);
+		addch(PASSAGE);
+		curr.x += turn_delta.x;
+		curr.y += turn_delta.y;
+	    }
+	/*
+	 * Continue digging along
+	 */
+	cmov(curr);
+	addch(PASSAGE);
+	distance--;
+    }
+    curr.x += delta.x;
+    curr.y += delta.y;
+    if (!ce(curr, epos))
+	msg("Warning, connectivity problem on this level.");
+}
+
+/*
+ * Add a door or possibly a secret door
+ * also enters the door in the exits array of the room.
+ */
+
+door(rm, cp)
+register struct room *rm;
+register coord *cp;
+{
+    struct linked_list *newroom;
+    coord *exit;
+
+    cmov(*cp);
+    addch( (rnd(10) < level - 1 && rnd(100) < 20 ? SECRETDOOR : DOOR) );
+
+    /* Insert the new room into the linked list of rooms */
+    newroom = new_item(sizeof(coord));
+    exit = DOORPTR(newroom);
+    *exit = *cp;
+    attach(rm->r_exit, newroom);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/player.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,587 @@
+/*
+ * This file contains functions for dealing with special player abilities
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include "rogue.h"
+
+
+/*
+ * affect:
+ *	cleric affecting undead
+ */
+
+affect()
+{
+    register struct linked_list *item;
+    register struct thing *tp;
+    register const char *mname;
+    bool see;
+    coord new_pos;
+
+    if (player.t_ctype != C_CLERIC && cur_relic[HEIL_ANKH] == 0) {
+	msg("Only clerics can affect undead.");
+	return;
+    }
+
+    new_pos.y = hero.y + delta.y;
+    new_pos.x = hero.x + delta.x;
+
+    if (cansee(new_pos.y, new_pos.x)) see = TRUE;
+    else see = FALSE;
+
+    /* Anything there? */
+    if (new_pos.y < 0 || new_pos.y > LINES-3 ||
+	new_pos.x < 0 || new_pos.x > COLS-1 ||
+	mvwinch(mw, new_pos.y, new_pos.x) == ' ') {
+	msg("Nothing to affect.");
+	return;
+    }
+
+    if ((item = find_mons(new_pos.y, new_pos.x)) == NULL) {
+	debug("Affect what @ %d,%d?", new_pos.y, new_pos.x);
+	return;
+    }
+    tp = THINGPTR(item);
+    mname = monsters[tp->t_index].m_name;
+
+    if (on(player, ISINVIS) && off(*tp, CANSEE)) {
+	sprintf(outstring,"%s%s cannot see you", see ? "The " : "It",
+	    see ? mname : "");
+	msg(outstring);
+	return;
+    }
+
+    if (off(*tp, TURNABLE) || on(*tp, WASTURNED)) 
+	goto annoy;
+    turn_off(*tp, TURNABLE);
+
+    /* Can cleric kill it? */
+    if (pstats.s_lvl >= 3 * tp->t_stats.s_lvl) {
+	unsigned long test;	/* For overflow check */
+
+	sprintf(outstring,"You have destroyed %s%s.", see ? "the " : "it", see ? mname : "");
+	msg(outstring);
+	test = pstats.s_exp + tp->t_stats.s_exp;
+
+	/* Be sure there is no overflow before increasing experience */
+	if (test > pstats.s_exp) pstats.s_exp = test;
+	killed(item, FALSE, TRUE);
+	check_level(TRUE);
+	return;
+    }
+
+    /* Can cleric turn it? */
+    if (rnd(100) + 1 >
+	 (100 * ((2 * tp->t_stats.s_lvl) - pstats.s_lvl)) / pstats.s_lvl) {
+	unsigned long test;	/* Overflow test */
+
+	/* Make the monster flee */
+	turn_on(*tp, WASTURNED);	/* No more fleeing after this */
+	turn_on(*tp, ISFLEE);
+	runto(tp, &hero);
+
+	/* Let player know */
+	sprintf(outstring,"You have turned %s%s.", see ? "the " : "it", see ? mname : "");
+	msg(outstring);
+
+	/* get points for turning monster -- but check overflow first */
+	test = pstats.s_exp + tp->t_stats.s_exp/2;
+	if (test > pstats.s_exp) pstats.s_exp = test;
+	check_level(TRUE);
+
+	/* If monster was suffocating, stop it */
+	if (on(*tp, DIDSUFFOCATE)) {
+	    turn_off(*tp, DIDSUFFOCATE);
+	    extinguish(suffocate);
+	}
+
+	/* If monster held us, stop it */
+	if (on(*tp, DIDHOLD) && (--hold_count == 0))
+		turn_off(player, ISHELD);
+	turn_off(*tp, DIDHOLD);
+	return;
+    }
+
+    /* Otherwise -- no go */
+annoy:
+    sprintf(outstring,"You do not affect %s%s.", see ? "the " : "it", see ? mname : "");
+    msg(outstring);
+
+    /* Annoy monster */
+   if (off(*tp, ISFLEE)) runto(tp, &hero);
+}
+
+/*
+ * the magic user is going to try and cast a spell
+ */
+cast()
+{
+    register int i, num_spells, spell_ability;
+    int  which_spell;
+    bool nohw = FALSE;
+
+    i = num_spells = spell_ability = which_spell = 0;
+
+    if (player.t_ctype != C_MAGICIAN && pstats.s_intel < 16) {
+	msg("You are not permitted to cast spells.");
+	return;
+    }
+    if (cur_misc[WEAR_CLOAK] != NULL &&
+	cur_misc[WEAR_CLOAK]->o_which == MM_R_POWERLESS) {
+	msg("You can't seem to cast a spell!");
+	return;
+    }
+    num_spells = 0;
+
+    /* Get the number of avilable spells */
+    if (pstats.s_intel >= 16) 
+	num_spells = pstats.s_intel - 15;
+
+    if (player.t_ctype == C_MAGICIAN) 
+	num_spells += pstats.s_lvl;
+
+    if (num_spells > MAXSPELLS) 
+	num_spells = MAXSPELLS;
+
+    spell_ability = pstats.s_lvl * pstats.s_intel;
+    if (player.t_ctype != C_MAGICIAN)
+	spell_ability /= 2;
+
+    /* Prompt for spells */
+    msg("Which spell are you casting? (* for list): ");
+
+    which_spell = (int) (readchar() - 'a');
+    if (which_spell == (int) ESCAPE - (int) 'a') {
+	mpos = 0;
+	msg("");
+	after = FALSE;
+	return;
+    }
+    if (which_spell >= 0 && which_spell < num_spells) nohw = TRUE;
+
+    else if (slow_invent) {
+	register char c;
+
+	for (i=0; i<num_spells; i++) {
+	    msg("");
+	    mvwaddch(cw, 0, 0, '[');
+	    waddch(cw, (char) ((int) 'a' + i));
+	    waddstr(cw, "] A spell of ");
+	    if (magic_spells[i].s_type == TYP_POTION)
+		waddstr(cw, p_magic[magic_spells[i].s_which].mi_name);
+	    else if (magic_spells[i].s_type == TYP_SCROLL)
+		waddstr(cw, s_magic[magic_spells[i].s_which].mi_name);
+	    else if (magic_spells[i].s_type == TYP_STICK)
+		waddstr(cw, ws_magic[magic_spells[i].s_which].mi_name);
+	    waddstr(cw, morestr);
+	    draw(cw);
+	    do {
+		c = readchar();
+	    } while (c != ' ' && c != ESCAPE);
+	    if (c == ESCAPE)
+		break;
+	}
+	msg("");
+	mvwaddstr(cw, 0, 0, "Which spell are you casting? ");
+	draw(cw);
+    }
+    else {
+	/* Set up for redraw */
+	msg("");
+	clearok(cw, TRUE);
+	touchwin(cw);
+
+	/* Now display the possible spells */
+	wclear(hw);
+	touchwin(hw);
+	mvwaddstr(hw, 2, 0, "	Cost		Spell");
+	mvwaddstr(hw, 3, 0, "-----------------------------------------------");
+	for (i=0; i<num_spells; i++) {
+	    mvwaddch(hw, i+4, 0, '[');
+	    waddch(hw, (char) ((int) 'a' + i));
+	    waddch(hw, ']');
+	    sprintf(prbuf, "	%3d", magic_spells[i].s_cost);
+	    waddstr(hw, prbuf);
+	    waddstr(hw, "	A spell of ");
+	    if (magic_spells[i].s_type == TYP_POTION)
+		waddstr(hw, p_magic[magic_spells[i].s_which].mi_name);
+	    else if (magic_spells[i].s_type == TYP_SCROLL)
+		waddstr(hw, s_magic[magic_spells[i].s_which].mi_name);
+	    else if (magic_spells[i].s_type == TYP_STICK)
+		waddstr(hw, ws_magic[magic_spells[i].s_which].mi_name);
+	}
+	sprintf(prbuf,"[Current spell power = %d]",spell_ability - spell_power);
+	mvwaddstr(hw, 0, 0, prbuf);
+	waddstr(hw, " Which spell are you casting? ");
+	draw(hw);
+    }
+
+    if (!nohw) {
+	which_spell = (int) (wgetch(hw) - 'a');
+	while (which_spell < 0 || which_spell >= num_spells) {
+	    if (which_spell == (int) ESCAPE - (int) 'a') {
+		after = FALSE;
+		return;
+	    }
+	    wmove(hw, 0, 0);
+	    wclrtoeol(hw);
+	    waddstr(hw, "Please enter one of the listed spells. ");
+	    draw(hw);
+	    which_spell = (int) (wgetch(hw) - 'a');
+	}
+    }
+
+    if ((spell_power + magic_spells[which_spell].s_cost) > spell_ability) {
+	msg("Your attempt fails.");
+	return;
+    }
+    if (nohw)
+	msg("Your spell is successful.");
+    else {
+	mvwaddstr(hw, 0, 0, "Your spell is successful.--More--");
+	wclrtoeol(hw);
+	draw(hw);
+	wait_for(hw,' ');
+    }
+    if (magic_spells[which_spell].s_type == TYP_POTION)
+        quaff(	magic_spells[which_spell].s_which,
+        	magic_spells[which_spell].s_flag,
+		FALSE);
+    else if (magic_spells[which_spell].s_type == TYP_SCROLL)
+        read_scroll(	magic_spells[which_spell].s_which,
+        		magic_spells[which_spell].s_flag,
+			FALSE);
+    else if (magic_spells[which_spell].s_type == TYP_STICK) {
+	 if (!do_zap(	TRUE, 
+			magic_spells[which_spell].s_which,
+			magic_spells[which_spell].s_flag)) {
+	     after = FALSE;
+	     return;
+	 }
+    }
+    spell_power += magic_spells[which_spell].s_cost;
+}
+
+/* Constitution bonus */
+
+const_bonus()	/* Hit point adjustment for changing levels */
+{
+    if (pstats.s_const > 6 && pstats.s_const <= 14) 
+	return(0);
+    if (pstats.s_const > 14) 
+	return(pstats.s_const-14);
+    if (pstats.s_const > 3) 
+	return(-1);
+    return(-2);
+}
+
+
+/* Routines for thieves */
+
+/*
+ * gsense:
+ *	Sense gold
+ */
+
+gsense()
+{
+    /* Only thieves can do this */
+    if (player.t_ctype != C_THIEF) {
+	msg("You seem to have no gold sense.");
+	return;
+    }
+
+    if (lvl_obj != NULL) {
+	struct linked_list *gitem;
+	struct object *cur;
+	int gtotal = 0;
+
+	wclear(hw);
+	for (gitem = lvl_obj; gitem != NULL; gitem = next(gitem)) {
+	    cur = OBJPTR(gitem);
+	    if (cur->o_type == GOLD) {
+		gtotal += cur->o_count;
+		mvwaddch(hw, cur->o_pos.y, cur->o_pos.x, GOLD);
+	    }
+	}
+	if (gtotal) {
+	    s_know[S_GFIND] = TRUE;
+	    msg("You sense gold!");
+	    overlay(hw,cw);
+	    return;
+	}
+    }
+    msg("You can sense no gold on this level.");
+}
+
+/* 
+ * the cleric asks his deity for a spell
+ */
+pray()
+{
+    register int i, num_prayers, prayer_ability;
+    int which_prayer;
+    bool nohw = FALSE;
+
+    which_prayer = num_prayers = prayer_ability = i = 0;
+
+    if (player.t_ctype != C_CLERIC && pstats.s_wisdom < 17 &&
+	cur_relic[HEIL_ANKH] == 0) {
+	msg("You are not permitted to pray.");
+	return;
+    }
+    if (cur_misc[WEAR_CLOAK] != NULL &&
+	cur_misc[WEAR_CLOAK]->o_which == MM_R_POWERLESS) {
+	msg("You can't seem to pray!");
+	return;
+    }
+    num_prayers = 0;
+
+    /* Get the number of avilable prayers */
+    if (pstats.s_wisdom > 16) 
+	num_prayers = (pstats.s_wisdom - 15) / 2;
+
+    if (player.t_ctype == C_CLERIC) 
+	num_prayers += pstats.s_lvl;
+
+    if (cur_relic[HEIL_ANKH]) num_prayers += 3;
+
+    if (num_prayers > MAXPRAYERS) 
+	num_prayers = MAXPRAYERS;
+
+    prayer_ability = pstats.s_lvl * pstats.s_wisdom;
+    if (player.t_ctype != C_CLERIC)
+	prayer_ability /= 2;
+
+    if (cur_relic[HEIL_ANKH]) prayer_ability *= 2;
+
+    /* Prompt for prayer */
+    msg("Which prayer are you offering? (* for list): ");
+    which_prayer = (int) (readchar() - 'a');
+    if (which_prayer == (int) ESCAPE - (int) 'a') {
+	mpos = 0;
+	msg("");
+	after = FALSE;
+	return;
+    }
+    if (which_prayer >= 0 && which_prayer < num_prayers) nohw = TRUE;
+
+    else if (slow_invent) {
+	register char c;
+
+	for (i=0; i<num_prayers; i++) {
+	    msg("");
+	    mvwaddch(cw, 0, 0, '[');
+	    waddch(cw, (char) ((int) 'a' + i));
+	    waddstr(cw, "] A prayer for ");
+	    if (cleric_spells[i].s_type == TYP_POTION)
+		waddstr(cw, p_magic[cleric_spells[i].s_which].mi_name);
+	    else if (cleric_spells[i].s_type == TYP_SCROLL)
+		waddstr(cw, s_magic[cleric_spells[i].s_which].mi_name);
+	    else if (cleric_spells[i].s_type == TYP_STICK)
+		waddstr(cw, ws_magic[cleric_spells[i].s_which].mi_name);
+	    waddstr(cw, morestr);
+	    draw(cw);
+	    do {
+		c = readchar();
+	    } while (c != ' ' && c != ESCAPE);
+	    if (c == ESCAPE)
+		break;
+	}
+	msg("");
+	mvwaddstr(cw, 0, 0, "Which prayer are you offering? ");
+	draw(cw);
+    }
+    else {
+	/* Set up for redraw */
+	msg("");
+	clearok(cw, TRUE);
+	touchwin(cw);
+
+	/* Now display the possible prayers */
+	wclear(hw);
+	touchwin(hw);
+	mvwaddstr(hw, 2, 0, "	Cost		Prayer");
+	mvwaddstr(hw, 3, 0, "-----------------------------------------------");
+	for (i=0; i<num_prayers; i++) {
+	    mvwaddch(hw, i+4, 0, '[');
+	    waddch(hw, (char) ((int) 'a' + i));
+	    waddch(hw, ']');
+	    sprintf(prbuf, "	%3d", cleric_spells[i].s_cost);
+	    waddstr(hw, prbuf);
+	    waddstr(hw, "	A prayer for ");
+	    if (cleric_spells[i].s_type == TYP_POTION)
+		waddstr(hw, p_magic[cleric_spells[i].s_which].mi_name);
+	    else if (cleric_spells[i].s_type == TYP_SCROLL)
+		waddstr(hw, s_magic[cleric_spells[i].s_which].mi_name);
+	    else if (cleric_spells[i].s_type == TYP_STICK)
+		waddstr(hw, ws_magic[cleric_spells[i].s_which].mi_name);
+	}
+	sprintf(prbuf,"[Current prayer ability = %d]",prayer_ability-pray_time);
+	mvwaddstr(hw, 0, 0, prbuf);
+	waddstr(hw, " Which prayer are you offering? ");
+	draw(hw);
+    }
+
+    if (!nohw) {
+	which_prayer = (int) (wgetch(hw) - 'a');
+	while (which_prayer < 0 || which_prayer >= num_prayers) {
+	    if (which_prayer == (int) ESCAPE - (int) 'a') {
+		after = FALSE;
+		return;
+	    }
+	    wmove(hw, 0, 0);
+	    wclrtoeol(hw);
+	    mvwaddstr(hw, 0, 0, "Please enter one of the listed prayers.");
+	    draw(hw);
+	    which_prayer = (int) (wgetch(hw) - 'a');
+	}
+    }
+
+
+    if (cleric_spells[which_prayer].s_cost + pray_time > prayer_ability) {
+	msg("Your prayer fails.");
+	return;
+    }
+
+    if (nohw) 
+	msg("Your prayer has been granted.");
+    else {
+	mvwaddstr(hw, 0, 0, "Your prayer has been granted.--More--");
+	wclrtoeol(hw);
+	draw(hw);
+	wait_for(hw,' ');
+    }
+    if (cleric_spells[which_prayer].s_type == TYP_POTION)
+	quaff(		cleric_spells[which_prayer].s_which,
+			cleric_spells[which_prayer].s_flag,
+			FALSE);
+    else if (cleric_spells[which_prayer].s_type == TYP_SCROLL)
+	read_scroll(	cleric_spells[which_prayer].s_which,
+			cleric_spells[which_prayer].s_flag,
+			FALSE);
+    else if (cleric_spells[which_prayer].s_type == TYP_STICK) {
+	 if (!do_zap(	TRUE, 
+			cleric_spells[which_prayer].s_which,
+			cleric_spells[which_prayer].s_flag)) {
+	     after = FALSE;
+	     return;
+	 }
+    }
+    pray_time += cleric_spells[which_prayer].s_cost;
+}
+
+
+
+/*
+ * steal:
+ *	Steal in direction given in delta
+ */
+
+steal()
+{
+    register struct linked_list *item;
+    register struct thing *tp;
+    register const char *mname;
+    coord new_pos;
+    int thief_bonus = -50;
+    bool isinvisible = FALSE;
+
+    new_pos.y = hero.y + delta.y;
+    new_pos.x = hero.x + delta.x;
+
+    if (on(player, ISBLIND)) {
+	msg("You can't see anything.");
+	return;
+    }
+
+    /* Anything there? */
+    if (new_pos.y < 0 || new_pos.y > LINES-3 ||
+	new_pos.x < 0 || new_pos.x > COLS-1 ||
+	mvwinch(mw, new_pos.y, new_pos.x) == ' ') {
+	msg("Nothing to steal from.");
+	return;
+    }
+
+    if ((item = find_mons(new_pos.y, new_pos.x)) == NULL)
+	debug("Steal from what @ %d,%d?", new_pos.y, new_pos.x);
+    tp = THINGPTR(item);
+    if (isinvisible = invisible(tp)) mname = "creature";
+    else mname = monsters[tp->t_index].m_name;
+
+    /* Can player steal something unnoticed? */
+    if (player.t_ctype == C_THIEF) thief_bonus = 10;
+    if (on(*tp, ISUNIQUE)) thief_bonus -= 15;
+    if (isinvisible) thief_bonus -= 20;
+    if (on(*tp, ISINWALL) && off(player, CANINWALL)) thief_bonus -= 50;
+
+    if (rnd(100) <
+	(thief_bonus + 2*dex_compute() + 5*pstats.s_lvl -
+	 5*(tp->t_stats.s_lvl - 3))) {
+	register struct linked_list *s_item, *pack_ptr;
+	int count = 0;
+	unsigned long test;	/* Overflow check */
+
+	s_item = NULL;	/* Start stolen goods out as nothing */
+
+	/* Find a good item to take */
+	for (pack_ptr=tp->t_pack; pack_ptr != NULL; pack_ptr=next(pack_ptr))
+	    if ((OBJPTR(pack_ptr))->o_type != RELIC &&
+		rnd(++count) == 0)
+		s_item = pack_ptr;
+
+	/* 
+	 * Find anything?
+	 *
+	 * if we have a merchant, and his pack is empty then the
+	 * rogue has already stolen once
+	 */
+	if (s_item == NULL) {
+	    if (tp->t_index == NUMMONST)
+		msg("The %s seems to be shielding his pack from you.", mname);
+	    else
+	        msg("The %s apparently has nothing to steal.", mname);
+	    return;
+	}
+
+	/* Take it from monster */
+	if (tp->t_pack) detach(tp->t_pack, s_item);
+
+	/* Give it to player */
+	if (add_pack(s_item, FALSE, NULL) == FALSE) {
+	   (OBJPTR(s_item))->o_pos = hero;
+	   fall(s_item, TRUE);
+	}
+
+	/* Get points for stealing -- but first check for overflow */
+	test = pstats.s_exp + tp->t_stats.s_exp/2;
+	if (test > pstats.s_exp) pstats.s_exp = test;
+
+	/*
+	 * Do adjustments if player went up a level
+	 */
+	check_level(TRUE);
+    }
+
+    else {
+	msg("Your attempt fails.");
+
+	/* Annoy monster (maybe) */
+	if (rnd(35) >= dex_compute() + thief_bonus) {
+	    if (tp->t_index == NUMMONST) {
+		if (!isinvisible)
+		    msg("The %s looks insulted and leaves", mname);
+		killed(item, FALSE, FALSE);
+	    }
+	    else
+	        runto(tp, &hero);
+	}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/potions.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,698 @@
+/*
+ * Function(s) for dealing with potions
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include "rogue.h"
+
+
+
+/*
+ * Increase player's constitution
+ */
+
+add_const(cursed)
+bool cursed;
+{
+    /* Do the potion */
+    if (cursed) {
+	msg("You feel less healthy now.");
+	pstats.s_const--;
+	if (pstats.s_const <= 0)
+	    death(D_CONSTITUTION);
+    }
+    else {
+	msg("You feel healthier now.");
+	pstats.s_const = min(pstats.s_const + 1, 25);
+    }
+
+    /* Adjust the maximum */
+    if (max_stats.s_const < pstats.s_const)
+	max_stats.s_const = pstats.s_const;
+}
+
+/*
+ * Increase player's dexterity
+ */
+
+add_dexterity(cursed)
+bool cursed;
+{
+    int ring_str;	/* Value of ring strengths */
+
+    /* Undo any ring changes */
+    ring_str = ring_value(R_ADDHIT);
+    pstats.s_dext -= ring_str;
+
+    /* Now do the potion */
+    if (cursed) {
+	msg("You feel less dextrous now.");
+	pstats.s_dext--;
+    }
+    else {
+	msg("You feel more dextrous now.  Watch those hands!");
+	pstats.s_dext = min(pstats.s_dext + 1, 25);
+    }
+
+    /* Adjust the maximum */
+    if (max_stats.s_dext < pstats.s_dext)
+	max_stats.s_dext = pstats.s_dext;
+
+    /* Now put back the ring changes */
+    if (ring_str)
+	pstats.s_dext += ring_str;
+}
+
+/*
+ * add_haste:
+ *	add a haste to the player
+ */
+
+add_haste(blessed)
+bool blessed;
+{
+    int hasttime;
+
+    if (blessed) hasttime = HASTETIME*2;
+    else hasttime = HASTETIME;
+
+    if (on(player, ISSLOW)) { /* Is person slow? */
+	extinguish(noslow);
+	noslow();
+
+	if (blessed) hasttime = HASTETIME/2;
+	else return;
+    }
+
+    if (on(player, ISHASTE)) {
+	msg("You faint from exhaustion.");
+	no_command += rnd(hasttime);
+	lengthen(nohaste, roll(hasttime,hasttime));
+    }
+    else {
+	turn_on(player, ISHASTE);
+	fuse(nohaste, 0, roll(hasttime, hasttime), AFTER);
+    }
+}
+
+/*
+ * Increase player's intelligence
+ */
+add_intelligence(cursed)
+bool cursed;
+{
+    int ring_str;	/* Value of ring strengths */
+
+    /* Undo any ring changes */
+    ring_str = ring_value(R_ADDINTEL);
+    pstats.s_intel -= ring_str;
+
+    /* Now do the potion */
+    if (cursed) {
+	msg("You feel slightly less intelligent now.");
+	pstats.s_intel--;
+    }
+    else {
+	msg("You feel more intelligent now.  What a mind!");
+	pstats.s_intel = min(pstats.s_intel + 1, 25);
+    }
+
+    /* Adjust the maximum */
+    if (max_stats.s_intel < pstats.s_intel)
+	    max_stats.s_intel = pstats.s_intel;
+
+    /* Now put back the ring changes */
+    if (ring_str)
+	pstats.s_intel += ring_str;
+}
+
+/*
+ * this routine makes the hero move slower 
+ */
+add_slow()
+{
+    if (on(player, ISHASTE)) { /* Already sped up */
+	extinguish(nohaste);
+	nohaste();
+    }
+    else {
+	msg("You feel yourself moving %sslower.",
+		on(player, ISSLOW) ? "even " : "");
+	if (on(player, ISSLOW))
+	    lengthen(noslow, roll(HASTETIME,HASTETIME));
+	else {
+	    turn_on(player, ISSLOW);
+	    player.t_turn = TRUE;
+	    fuse(noslow, 0, roll(HASTETIME,HASTETIME), AFTER);
+	}
+    }
+}
+
+/*
+ * Increase player's strength
+ */
+
+add_strength(cursed)
+bool cursed;
+{
+
+    if (cursed) {
+	msg("You feel slightly weaker now.");
+	chg_str(-1);
+    }
+    else {
+	msg("You feel stronger now.  What bulging muscles!");
+	chg_str(1);
+    }
+}
+
+/*
+ * Increase player's wisdom
+ */
+
+add_wisdom(cursed)
+bool cursed;
+{
+    int ring_str;	/* Value of ring strengths */
+
+    /* Undo any ring changes */
+    ring_str = ring_value(R_ADDWISDOM);
+    pstats.s_wisdom -= ring_str;
+
+    /* Now do the potion */
+    if (cursed) {
+	msg("You feel slightly less wise now.");
+	pstats.s_wisdom--;
+    }
+    else {
+	msg("You feel wiser now.  What a sage!");
+	pstats.s_wisdom = min(pstats.s_wisdom + 1, 25);
+    }
+
+    /* Adjust the maximum */
+    if (max_stats.s_wisdom < pstats.s_wisdom)
+	max_stats.s_wisdom = pstats.s_wisdom;
+
+    /* Now put back the ring changes */
+    if (ring_str)
+	pstats.s_wisdom += ring_str;
+}
+
+
+/* 
+ * Lower a level of experience 
+ */
+
+lower_level(who)
+short who;
+{
+    int fewer, nsides = 0;
+
+    if (--pstats.s_lvl == 0)
+	death(who);		/* All levels gone */
+    msg("You suddenly feel less skillful.");
+    pstats.s_exp /= 2;
+    switch (player.t_ctype) {
+	case C_FIGHTER:	nsides = HIT_FIGHTER;
+	when C_MAGICIAN:nsides = HIT_MAGICIAN;
+	when C_CLERIC:	nsides = HIT_CLERIC;
+	when C_THIEF:	nsides = HIT_THIEF;
+    }
+    fewer = max(1, roll(1,nsides) + const_bonus());
+    pstats.s_hpt -= fewer;
+    max_stats.s_hpt -= fewer;
+    if (pstats.s_hpt < 1)
+	pstats.s_hpt = 1;
+    if (max_stats.s_hpt < 1)
+	death(who);
+}
+
+quaff(which, flag, is_potion)
+int which;
+int flag;
+bool is_potion;
+{
+    register struct object *obj = NULL;
+    register struct linked_list *item, *titem;
+    register struct thing *th;
+    bool cursed, blessed;
+    char buf[LINELEN];
+
+    blessed = FALSE;
+    cursed = FALSE;
+    item = NULL;
+
+    if (which < 0) {	/* figure out which ourselves */
+	item = get_item(pack, "quaff", POTION);
+	/*
+	 * Make certain that it is somethings that we want to drink
+	 */
+	if (item == NULL)
+	    return;
+
+	obj = OBJPTR(item);
+	/* remove it from the pack */
+	inpack--;
+	detach(pack, item);
+
+	/*
+	 * Calculate the effect it has on the poor guy.
+	 */
+	cursed = (obj->o_flags & ISCURSED) != 0;
+	blessed = (obj->o_flags & ISBLESSED) != 0;
+
+	which = obj->o_which;
+    }
+    else {
+	cursed = flag & ISCURSED;
+	blessed = flag & ISBLESSED;
+    }
+
+    switch(which)
+    {
+	case P_CLEAR:
+	    if (cursed) {
+		if (off(player, ISCLEAR))
+		{
+		    msg("Wait, what's going on here. Huh? What? Who?");
+		    if (find_slot(unconfuse))
+			lengthen(unconfuse, rnd(8)+HUHDURATION);
+		    else
+			fuse(unconfuse, 0, rnd(8)+HUHDURATION, AFTER);
+		    turn_on(player, ISHUH);
+		}
+		else msg("You feel dizzy for a moment, but it quickly passes.");
+	    }
+	    else {
+		if (blessed) {	/* Make player immune for the whole game */
+		    extinguish(unclrhead);  /* If we have a fuse, put it out */
+		    msg("A strong blue aura surrounds your head.");
+		}
+		else {	/* Just light a fuse for how long player is safe */
+		    if (off(player, ISCLEAR)) {
+			fuse(unclrhead, 0, CLRDURATION, AFTER);
+			msg("A faint blue aura surrounds your head.");
+		    }
+		    else {  /* If we have a fuse lengthen it, else we
+			     * are permanently clear.
+			     */
+		        if (find_slot(unclrhead) == FALSE)
+			    msg("Your blue aura continues to glow strongly.");
+			else {
+			    lengthen(unclrhead, CLRDURATION);
+			    msg("Your blue aura brightens for a moment.");
+			}
+		    }
+		}
+		turn_on(player, ISCLEAR);
+		/* If player is confused, unconfuse him */
+		if (on(player, ISHUH)) {
+		    extinguish(unconfuse);
+		    unconfuse();
+		}
+	    }
+	when P_HEALING:
+	    if (cursed) {
+		if (!save(VS_POISON, &player, 0)) {
+		    msg("You feel very sick now.");
+		    pstats.s_hpt /= 2;
+		    pstats.s_const--;
+		    if (pstats.s_const <= 0 || pstats.s_hpt <= 0) 
+			death(D_POISON);
+		}
+		else msg("You feel momentarily sick.");
+	    }
+	    else {
+		if (blessed) {
+		    if ((pstats.s_hpt += roll(pstats.s_lvl, 8)) > max_stats.s_hpt)
+			pstats.s_hpt = ++max_stats.s_hpt;
+		    if (on(player, ISHUH)) {
+			extinguish(unconfuse);
+			unconfuse();
+		    }
+		}
+		else {
+		    if ((pstats.s_hpt += roll(pstats.s_lvl, 4)) > max_stats.s_hpt)
+		    pstats.s_hpt = ++max_stats.s_hpt;
+		}
+		msg("You begin to feel %sbetter.",
+			blessed ? "much " : "");
+		sight();
+		if (is_potion) p_know[P_HEALING] = TRUE;
+	    }
+	when P_ABIL:
+	    {
+		int ctype;
+
+		/*
+		 * if blessed then fix all attributes
+		 */
+		if (blessed) {
+		    add_intelligence(FALSE);
+		    add_dexterity(FALSE);
+		    add_strength(FALSE);
+		    add_wisdom(FALSE);
+		    add_const(FALSE);
+		}
+		/* probably will be own ability */
+		else {
+		    if (rnd(100) < 70) 
+			ctype = player.t_ctype;
+		    else do {
+			ctype = rnd(4);
+			} while (ctype == player.t_ctype);
+
+		    /* Small chance of doing constitution instead */
+		    if (rnd(100) < 10) 
+			add_const(cursed);
+		    else switch (ctype) {
+			case C_FIGHTER: add_strength(cursed);
+			when C_MAGICIAN: add_intelligence(cursed);
+			when C_CLERIC:	add_wisdom(cursed);
+			when C_THIEF:	add_dexterity(cursed);
+			otherwise:	msg("You're a strange type!");
+		    }
+		}
+		if (is_potion) p_know[P_ABIL] = TRUE;
+	    }
+	when P_MFIND:
+	    /*
+	     * Potion of monster detection, if there are monters, detect them
+	     */
+	    if (mlist != NULL)
+	    {
+		msg("You begin to sense the presence of monsters.");
+		waddstr(cw, morestr);
+		overlay(mw, cw);
+		draw(cw);
+		wait_for(cw,' ');
+		msg("");
+		if (is_potion) p_know[P_MFIND] = TRUE;
+	    }
+	    else
+		msg("You have a strange feeling for a moment, then it passes.");
+	when P_TFIND:
+	    /*
+	     * Potion of magic detection.  Show the potions and scrolls
+	     */
+	    if (lvl_obj != NULL)
+	    {
+		register struct linked_list *mobj;
+		register struct object *tp;
+		bool show;
+
+		show = FALSE;
+		wclear(hw);
+		for (mobj = lvl_obj; mobj != NULL; mobj = next(mobj)) {
+		    tp = OBJPTR(mobj);
+		    if (is_magic(tp)) {
+			char mag_type=MAGIC;
+
+			/* Mark cursed items or bad weapons */
+			if ((tp->o_flags & ISCURSED) ||
+			    (tp->o_type == WEAPON &&
+			     (tp->o_hplus < 0 || tp->o_dplus < 0)))
+				mag_type = CMAGIC;
+			else if ((tp->o_flags & ISBLESSED) ||
+				 (tp->o_type == WEAPON &&
+				  (tp->o_hplus > 0 || tp->o_dplus > 0)))
+					mag_type = BMAGIC;
+			show = TRUE;
+			mvwaddch(hw, tp->o_pos.y, tp->o_pos.x, mag_type);
+		    }
+		    if (is_potion) p_know[P_TFIND] = TRUE;
+		}
+		for (titem = mlist; titem != NULL; titem = next(titem)) {
+		    register struct linked_list *pitem;
+
+		    th = THINGPTR(titem);
+		    for(pitem = th->t_pack; pitem != NULL; pitem = next(pitem)){
+			tp = OBJPTR(pitem);
+			if (is_magic(tp)) {
+			    char mag_type=MAGIC;
+
+			    /* Mark cursed items or bad weapons */
+			    if ((tp->o_flags & ISCURSED) ||
+				(tp->o_type == WEAPON &&
+				 (tp->o_hplus < 0 || tp->o_dplus < 0)))
+				    mag_type = CMAGIC;
+			    else if ((tp->o_flags & ISBLESSED) ||
+				     (tp->o_type == WEAPON &&
+				      (tp->o_hplus > 0 || tp->o_dplus > 0)))
+					    mag_type = BMAGIC;
+			    show = TRUE;
+			    mvwaddch(hw, th->t_pos.y, th->t_pos.x, mag_type);
+			}
+			if (is_potion) p_know[P_TFIND] = TRUE;
+		    }
+		}
+		if (show) {
+		    msg("You sense the presence of magic on this level.");
+		    waddstr(cw, morestr);
+		    overlay(hw,cw);
+		    draw(cw);
+		    wait_for(cw,' ');
+		    msg("");
+		    break;
+		}
+	    }
+	    msg("You have a strange feeling for a moment, then it passes.");
+	when P_SEEINVIS:
+	    if (cursed) {
+		if (!find_slot(sight))
+		{
+		    msg("A cloak of darkness falls around you.");
+		    turn_on(player, ISBLIND);
+		    fuse(sight, 0, SEEDURATION, AFTER);
+		    light(&hero);
+		}
+		else
+		    lengthen(sight, SEEDURATION);
+	    }
+	    else {
+		if (off(player, CANSEE)) {
+		    turn_on(player, CANSEE);
+		    msg("Your eyes begin to tingle.");
+		    fuse(unsee, 0, blessed ? SEEDURATION*3 :SEEDURATION, AFTER);
+		    light(&hero);
+		}
+		else if (find_slot(unsee) != FALSE)
+		    lengthen(unsee, blessed ? SEEDURATION*3 : SEEDURATION);
+		sight();
+	    }
+	when P_PHASE:
+	    if (cursed) {
+		msg("You can't move.");
+		no_command = FREEZETIME;
+	    }
+	    else {
+		int duration;
+
+		if (blessed) duration = 3;
+		else duration = 1;
+
+		if (on(player, CANINWALL))
+		    lengthen(unphase, duration*PHASEDURATION);
+		else {
+		    fuse(unphase, 0, duration*PHASEDURATION, AFTER);
+		    turn_on(player, CANINWALL);
+		}
+		msg("You feel %slight-headed!",
+		    blessed ? "very " : "");
+	    }
+	when P_FLY: {
+	    int duration;
+	    bool say_message;
+
+	    say_message = TRUE;
+
+	    if (blessed) duration = 3;
+	    else duration = 1;
+
+	    if (on(player, ISFLY)) {
+		if (find_slot(land))
+		    lengthen(land, duration*FLYTIME);
+		else {
+		    msg("Nothing happens.");	/* Flying by cloak */
+		    say_message = FALSE;
+		}
+	    }
+	    else {
+		fuse(land, 0, duration*FLYTIME, AFTER);
+		turn_on(player, ISFLY);
+	    }
+	    if (say_message) 
+		msg("You feel %slighter than air!", blessed ? "much " : "");
+	}
+	when P_RAISE:
+	    if (cursed) lower_level(D_POTION);
+	    else {
+		msg("You suddenly feel %smore skillful",
+			blessed ? "much " : "");
+		p_know[P_RAISE] = TRUE;
+		raise_level(TRUE);
+		if (blessed) raise_level(TRUE);
+	    }
+	when P_HASTE:
+	    if (cursed) {	/* Slow player down */
+		add_slow();
+	    }
+	    else {
+		if (off(player, ISSLOW))
+		    msg("You feel yourself moving %sfaster.",
+			blessed ? "much " : "");
+		add_haste(blessed);
+		if (is_potion) p_know[P_HASTE] = TRUE;
+	    }
+	when P_RESTORE: {
+	    register int i;
+
+	    msg("Hey, this tastes great.  It make you feel warm all over.");
+	    if (lost_str) {
+		extinguish(res_strength);
+		lost_str = 0;
+	    }
+	    for (i=0; i<lost_dext; i++)
+		extinguish(un_itch);
+	    lost_dext = 0;
+	    res_strength();
+	    res_wisdom();
+	    res_dexterity(0);
+	    res_intelligence();
+	    pstats.s_const = max_stats.s_const;
+	}
+	when P_INVIS:
+	    if (off(player, ISINVIS)) {
+		turn_on(player, ISINVIS);
+		msg("You have a tingling feeling all over your body");
+		fuse(appear, 0, blessed ? GONETIME*3 : GONETIME, AFTER);
+		PLAYER = IPLAYER;
+		light(&hero);
+	    }
+	    else {
+		if (find_slot(appear)) {
+		    msg("Your tingling feeling surges.");
+		    lengthen(appear, blessed ? GONETIME*3 : GONETIME);
+		}
+		else msg("Nothing happens.");	/* Using cloak */
+	    }
+
+	otherwise:
+	    msg("What an odd tasting potion!");
+	    return;
+    }
+    status(FALSE);
+    if (is_potion && p_know[which] && p_guess[which])
+    {
+	free(p_guess[which]);
+	p_guess[which] = NULL;
+    }
+    else if (is_potion && 
+	     !p_know[which] && 
+	     askme &&
+	     (obj->o_flags & ISKNOW) == 0 &&
+	     (obj->o_flags & ISPOST) == 0 &&
+	     p_guess[which] == NULL)
+    {
+	msg(terse ? "Call it: " : "What do you want to call it? ");
+	if (get_str(buf, cw) == NORM)
+	{
+	    p_guess[which] = new((unsigned int) strlen(buf) + 1);
+	    strcpy(p_guess[which], buf);
+	}
+    }
+    if (item != NULL) o_discard(item);
+    updpack(TRUE);
+}
+
+
+/*
+ * res_dexterity:
+ *	Restore player's dexterity
+ *	if called with zero the restore fully
+ */
+
+res_dexterity(howmuch)
+int howmuch;
+{
+    short save_max;
+    int ring_str;
+
+    /* Discount the ring value */
+    ring_str = ring_value(R_ADDHIT);
+    pstats.s_dext -= ring_str;
+
+    if (pstats.s_dext < max_stats.s_dext ) {
+	if (howmuch == 0)
+	    pstats.s_dext = max_stats.s_dext;
+	else
+	    pstats.s_dext = min(pstats.s_dext+howmuch, max_stats.s_dext);
+    }
+
+    /* Redo the rings */
+    if (ring_str) {
+	save_max = max_stats.s_dext;
+	pstats.s_dext += ring_str;
+	max_stats.s_dext = save_max;
+    }
+}
+
+
+/*
+ * res_intelligence:
+ *	Restore player's intelligence
+ */
+
+res_intelligence()
+{
+    short save_max;
+    int ring_str;
+
+    /* Discount the ring value */
+    ring_str = ring_value(R_ADDINTEL);
+    pstats.s_intel -= ring_str;
+
+    if (pstats.s_intel < max_stats.s_intel ) pstats.s_intel = max_stats.s_intel;
+
+    /* Redo the rings */
+    if (ring_str) {
+	save_max = max_stats.s_intel;
+	pstats.s_intel += ring_str;
+	max_stats.s_intel = save_max;
+    }
+}
+
+/*
+ * res_wisdom:
+ *	Restore player's wisdom
+ */
+
+res_wisdom()
+{
+    short save_max;
+    int ring_str;
+
+    /* Discount the ring value */
+    ring_str = ring_value(R_ADDWISDOM);
+    pstats.s_wisdom -= ring_str;
+
+    if (pstats.s_wisdom < max_stats.s_wisdom )
+	pstats.s_wisdom = max_stats.s_wisdom;
+
+    /* Redo the rings */
+    if (ring_str) {
+	save_max = max_stats.s_wisdom;
+	pstats.s_wisdom += ring_str;
+	max_stats.s_wisdom = save_max;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/rings.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,161 @@
+/*
+ * routines dealing specifically with rings
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include "rogue.h"
+
+/*
+ * how much food does this ring use up?
+ */
+ring_eat(hand)
+register int hand;
+{
+    if (cur_ring[hand] == NULL)
+	return 0;
+    switch (cur_ring[hand]->o_which) {
+	case R_VAMPREGEN:
+	    return 3;
+	case R_REGEN:
+	    return 2;
+	case R_HEALTH:
+	case R_SUSABILITY:
+	    return 1;
+	case R_SEARCH:
+	case R_SEEINVIS:
+	    return (rnd(100) < 33);
+	case R_DIGEST:
+	    if (cur_ring[hand]->o_ac >= 0)
+		return (-(cur_ring[hand]->o_ac)-1);
+	    else
+		return (-(cur_ring[hand]->o_ac));
+    }
+    return 0;
+}
+
+ring_on(obj)
+register struct object *obj;
+{
+    register int save_max;
+    char buf[LINELEN];
+
+    /*
+     * Calculate the effect it has on the poor guy.
+     */
+    switch (obj->o_which)
+    {
+	case R_ADDSTR:
+	    save_max = max_stats.s_str;
+	    chg_str(obj->o_ac);
+	    max_stats.s_str = save_max;
+	when R_ADDHIT:
+	    pstats.s_dext += obj->o_ac;
+	when R_ADDINTEL:
+	    pstats.s_intel += obj->o_ac;
+	when R_ADDWISDOM:
+	    pstats.s_wisdom += obj->o_ac;
+	when R_SEEINVIS:
+	    turn_on(player, CANSEE);
+	    msg("Your eyes begin to tingle");
+	    light(&hero);
+	    mvwaddch(cw, hero.y, hero.x, PLAYER);
+	when R_AGGR:
+	    aggravate();
+	when R_WARMTH:
+	    turn_on(player, NOCOLD);
+	when R_FIRE:
+	    turn_on(player, NOFIRE);
+	when R_LIGHT: {
+		if(roomin(&hero) != NULL) {
+			light(&hero);
+			mvwaddch(cw, hero.y, hero.x, PLAYER);
+		}
+	    }
+	when R_SEARCH:
+		daemon(ring_search, 0, AFTER);
+	when R_TELEPORT:
+		daemon(ring_teleport, 0, AFTER);
+    }
+    status(FALSE);
+    if (r_know[obj->o_which] && r_guess[obj->o_which])
+    {
+	free(r_guess[obj->o_which]);
+	r_guess[obj->o_which] = NULL;
+    }
+    else if (!r_know[obj->o_which] && 
+	     askme && 
+	     (obj->o_flags & ISKNOW) == 0 &&
+	     r_guess[obj->o_which] == NULL) {
+	msg(terse ? "Call it: " : "What do you want to call it? ");
+	if (get_str(buf, cw) == NORM)
+	{
+	    r_guess[obj->o_which] = new((unsigned int) strlen(buf) + 1);
+	    strcpy(r_guess[obj->o_which], buf);
+	}
+	msg("");
+    }
+}
+
+/*
+ * print ring bonuses
+ */
+char *
+ring_num(obj)
+register struct object *obj;
+{
+    static char buf[5];
+
+    if (!(obj->o_flags & ISKNOW))
+	return "";
+    switch (obj->o_which)
+    {
+	case R_PROTECT:
+	case R_ADDSTR:
+	case R_ADDDAM:
+	case R_ADDHIT:
+	case R_ADDINTEL:
+	case R_ADDWISDOM:
+	case R_DIGEST:
+	    buf[0] = ' ';
+	    strcpy(&buf[1], num(obj->o_ac, 0));
+	when R_AGGR:
+	case R_LIGHT:
+	case R_HEAVY:
+	case R_TELEPORT:
+	    if (obj->o_flags & ISCURSED)
+		return " cursed";
+	    else
+		return "";
+	otherwise:
+	    return "";
+    }
+    return buf;
+}
+
+/* 
+ * Return the effect of the specified ring 
+ */
+ring_value(type)
+{
+    int result = 0;
+
+    if (ISRING(LEFT_1, type))  result += cur_ring[LEFT_1]->o_ac;
+    if (ISRING(LEFT_2, type)) result += cur_ring[LEFT_2]->o_ac;
+    if (ISRING(LEFT_3, type)) result += cur_ring[LEFT_3]->o_ac;
+    if (ISRING(LEFT_4, type)) result += cur_ring[LEFT_4]->o_ac;
+    if (ISRING(RIGHT_1, type)) result += cur_ring[RIGHT_1]->o_ac;
+    if (ISRING(RIGHT_2, type))  result += cur_ring[RIGHT_2]->o_ac;
+    if (ISRING(RIGHT_3, type)) result += cur_ring[RIGHT_3]->o_ac;
+    if (ISRING(RIGHT_4, type))  result += cur_ring[RIGHT_4]->o_ac;
+    return(result);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/rip.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,768 @@
+/*
+ * File for the fun ends
+ * Death or a total win
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+/* Print flags for scoring */
+#define REALLIFE 1	/* Print out machine and logname */
+#define EDITSCORE 2	/* Edit the current score file */
+#define ADDSCORE 3	/* Add a new score */
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "curses.h"
+#include <time.h>
+#include <signal.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include "network.h"
+#include "rogue.h"
+#include "mach_dep.h"
+
+/*
+ * If you change this structure, change the compatibility routines
+ * scoreout() and scorein() to reflect the change.  Also update SCORELEN.
+ */
+
+struct sc_ent {
+    unsigned long	sc_score;
+    char	sc_name[LINELEN];
+    char	sc_system[SYSLEN];
+    char	sc_login[LOGLEN];
+    short	sc_flgs;
+    short	sc_level;
+    short	sc_ctype;
+    short	sc_monster;
+    short	sc_quest;
+};
+
+#define SCORELEN \
+    (sizeof(unsigned long) + LINELEN + SYSLEN + LOGLEN + 5*sizeof(short))
+
+static char *rip[] = {
+"                       __________",
+"                      /          \\",
+"                     /    REST    \\",
+"                    /      IN      \\",
+"                   /     PEACE      \\",
+"                  /                  \\",
+"                  |                  |",
+"                  |                  |",
+"                  |    killed by     |",
+"                  |                  |",
+"                  |       1984       |",
+"                 *|     *  *  *      | *",
+"         ________)/\\\\_//(\\/(/\\)/\\//\\/|_)_______",
+    0
+};
+
+char	*killname();
+
+
+
+
+
+void
+byebye(sig)
+int sig;
+{
+    NOOP(sig);
+    if (!isendwin()) {
+        clear();
+	endwin();
+    }
+    printf("\n");
+    exit(0);
+}
+
+
+/*
+ * death:
+ *	Do something really fun when he dies
+ */
+
+death(monst)
+register short monst;
+{
+    register char **dp = rip, *killer;
+    register struct tm *lt;
+    time_t date;
+    char buf[80];
+    struct tm *localtime();
+
+    time(&date);
+    lt = localtime(&date);
+    clear();
+    move(8, 0);
+    while (*dp)
+	printw("%s\n", *dp++);
+    mvaddstr(14, 28-((strlen(whoami)+1)/2), whoami);
+    sprintf(buf, "%lu Points", pstats.s_exp );
+    mvaddstr(15, 28-((strlen(buf)+1)/2), buf);
+    killer = killname(monst);
+    mvaddstr(17, 28-((strlen(killer)+1)/2), killer);
+    mvaddstr(18, 26, (sprintf(prbuf, "%4d", 1900+lt->tm_year), prbuf));
+    move(LINES-1, 0);
+    refresh();
+    score(pstats.s_exp, KILLED, monst);
+    exit(0);
+}
+
+char *
+killname(monst)
+register short monst;
+{
+    static char mons_name[LINELEN];
+    int i;
+
+    if (monst > NUMMONST) return("a strange monster");
+
+    if (monst >= 0) {
+	switch (monsters[monst].m_name[0]) {
+	    case 'a':
+	    case 'e':
+	    case 'i':
+	    case 'o':
+	    case 'u':
+		sprintf(mons_name, "an %s", monsters[monst].m_name);
+		break;
+	    default:
+		sprintf(mons_name, "a %s", monsters[monst].m_name);
+	}
+	return(mons_name);
+    }
+    for (i = 0; i< DEATHNUM; i++) {
+	if (deaths[i].reason == monst)
+	    break;
+    }
+    if (i >= DEATHNUM)
+	return ("strange death");
+    return (deaths[i].name);
+}
+
+
+/*
+ * score -- figure score and post it.
+ */
+
+/* VARARGS2 */
+score(amount, flags, monst)
+unsigned long amount;
+short monst;
+{
+    static struct sc_ent top_ten[NUMSCORE];
+    register struct sc_ent *scp;
+    register int i;
+    register struct sc_ent *sc2;
+    register FILE *outf;
+    register char *killer;
+    register int prflags = 0;
+    register int fd;
+    short upquest = 0, wintype = 0, uplevel = 0, uptype = 0;	/* For network updating */
+    char upsystem[SYSLEN], uplogin[LOGLEN];
+    char *thissys;	/* Holds the name of this system */
+    char *compatstr=NULL; /* Holds scores for writing compatible score files */
+#define REASONLEN 3
+    static char *reason[] = {
+	"killed",
+	"quit",
+	"A total winner",
+	"somehow left",
+    };
+    char *packend;
+    memset(top_ten,0,sizeof(top_ten));
+    signal(SIGINT, byebye);
+    if (flags != WINNER && flags != SCOREIT && flags != UPDATE) {
+	if (flags == CHICKEN)
+	    packend = "when you quit";
+	else
+	    packend = "at your untimely demise";
+	mvaddstr(LINES - 1, 0, retstr);
+	refresh();
+	wgetnstr(cw,prbuf,80);
+	showpack(packend);
+    }
+    purse = 0;	/* Steal all the gold */
+
+    /*
+     * Open file and read list
+     */
+
+    if ((fd = open(score_file, O_RDWR | O_CREAT, 0666)) < 0) 
+    {
+       printf("\nCannot open score_file.\n");
+       return;
+    }
+    outf = (FILE *) fdopen(fd, "w");
+
+    /* Get this system's name */
+    thissys = md_gethostname();
+
+    for (scp = top_ten; scp <= &top_ten[NUMSCORE-1]; scp++)
+    {
+	scp->sc_score = 0L;
+	for (i = 0; i < 80; i++)
+	    scp->sc_name[i] = rnd(255);
+	scp->sc_quest= RN;
+	scp->sc_flgs = RN;
+	scp->sc_level = RN;
+	scp->sc_monster = RN;
+	scp->sc_ctype = 0;
+	strncpy(scp->sc_system, thissys, SYSLEN);
+	scp->sc_login[0] = '\0';
+    }
+
+    /*
+     * If this is a SCOREIT optin (rogue -s), don't call byebye.  The
+     * endwin() call in byebye() will result in a core dump.
+     */
+    if (flags == SCOREIT) signal(SIGINT, SIG_DFL);
+    else signal(SIGINT, byebye);
+
+    if (flags != SCOREIT && flags != UPDATE)
+    {
+	mvaddstr(LINES - 1, 0, retstr);
+	refresh();
+	fflush(stdout);
+	wgetnstr(stdscr,prbuf,80);
+    }
+
+    /* Check for special options */
+    if (strcmp(prbuf, "names") == 0)
+	prflags = REALLIFE;
+#ifdef WIZARD
+    else if (wizard) {
+	if (strcmp(prbuf, "edit") == 0) prflags = EDITSCORE;
+	else if (strcmp(prbuf, "add") == 0) {
+	    prflags = ADDSCORE;
+	    waswizard = FALSE;	/* We want the new score recorded */
+	}
+    }
+#endif
+
+    /* Read the score and convert it to a compatible format */
+    scorein(top_ten, fd);	/* Convert it */
+
+    /* Get some values if this is an update */
+    if (flags == UPDATE) {
+	int errcheck, errors = 0;
+
+	upquest = (short) netread(&errcheck, sizeof(short), stdin);
+	if (errcheck) errors++;
+
+	if (fread(whoami, 1, LINELEN, stdin) != LINELEN) errors++;
+
+	wintype = (short) netread(&errcheck, sizeof(short), stdin);
+	if (errcheck) errors++;
+
+	uplevel = (short) netread(&errcheck, sizeof(short), stdin);
+	if (errcheck) errors++;
+
+	uptype = (short) netread(&errcheck, sizeof(short), stdin);
+	if (errcheck) errors++;
+
+	if (fread(upsystem, 1, SYSLEN, stdin) != SYSLEN)
+		errors++;
+	if (fread(uplogin, 1, LOGLEN, stdin) != LOGLEN)
+		errors++;
+	
+	if (errors) {
+	    fclose(outf);
+	    free(compatstr);
+	    return;
+	}
+    }
+
+    /*
+     * Insert player in list if need be
+     */
+    if (!waswizard) {
+	char *login = NULL;
+
+	if (flags != UPDATE) {
+	    login = md_getusername();
+	}
+
+	if (flags == UPDATE)
+	    (void) update(top_ten, amount, upquest, whoami, wintype,
+		   uplevel, monst, uptype, upsystem, uplogin);
+	else {
+#ifdef WIZARD
+	    if (prflags == ADDSCORE) {	/* Overlay characteristic by new ones */
+	 	char buffer[80];
+		int atoi();
+
+		clear();
+		mvaddstr(1, 0, "Score: ");
+		mvaddstr(2, 0, "Quest (number): ");
+		mvaddstr(3, 0, "Name: ");
+		mvaddstr(4, 0, "System: ");
+		mvaddstr(5, 0, "Login: ");
+		mvaddstr(6, 0, "Level: ");
+		mvaddstr(7, 0, "Char type: ");
+		mvaddstr(8, 0, "Result: ");
+
+		/* Get the score */
+		move(1, 7);
+		get_str(buffer, stdscr);
+		amount = atol(buffer);
+
+		/* Get the character's quest -- must be a number */
+		move(2, 16);
+		get_str(buffer, stdscr);
+		quest_item = atoi(buffer);
+
+		/* Get the character's name */
+		move(3, 6);
+		get_str(buffer, stdscr);
+		strncpy(whoami, buffer, LINELEN);
+
+		/* Get the system */
+		move(4, 8);
+		get_str(buffer, stdscr);
+		strncpy(thissys, buffer, SYSLEN);
+
+		/* Get the login */
+		move(5, 7);
+		get_str(buffer, stdscr);
+		strncpy(login, buffer, LOGLEN);
+
+		/* Get the level */
+		move(6, 7);
+		get_str(buffer, stdscr);
+		level = max_level = (short) atoi(buffer);
+
+		/* Get the character type */
+		move(7, 11);
+		get_str(buffer, stdscr);
+		switch (buffer[0]) {
+		    case 'F':
+		    case 'f':
+		    default:
+			player.t_ctype = C_FIGHTER;
+			break;
+
+		    case 'C':
+		    case 'c':
+			player.t_ctype = C_CLERIC;
+			break;
+
+		    case 'M':
+		    case 'm':
+			player.t_ctype = C_MAGICIAN;
+			break;
+
+		    case 'T':
+		    case 't':
+			player.t_ctype = C_THIEF;
+			break;
+		}
+
+		/* Get the win type */
+		move(8, 8);
+		get_str(buffer, stdscr);
+		switch (buffer[0]) {
+		    case 'W':
+		    case 'w':
+		    case 'T':
+		    case 't':
+			flags = WINNER;
+			break;
+
+		    case 'Q':
+		    case 'q':
+			flags = CHICKEN;
+			break;
+
+		    case 'k':
+		    case 'K':
+		    default:
+			flags = KILLED;
+			break;
+		}
+
+		/* Get the monster if player was killed */
+		if (flags == KILLED) {
+		    mvaddstr(9, 0, "Death type: ");
+		    get_str(buffer, stdscr);
+		    if (buffer[0] == 'M' || buffer[0] == 'm')
+			monst = makemonster(FALSE);
+		    else monst = getdeath();
+		}
+	    }
+#endif
+
+	    if (update(top_ten, amount, (short) quest_item, whoami, flags,
+		    (flags == WINNER) ? (short) max_level : (short) level,
+		    monst, player.t_ctype, thissys, login)
+#ifdef NUMNET
+		&& fork() == 0		/* Spin off network process */
+#endif
+		) {
+#ifdef NUMNET
+		/* Send this update to the other systems in the network */
+		int i, j;
+		char cmd[256];	/* Command for remote execution */
+		FILE *rmf, *popen();	/* For input to remote command */
+
+		for (i=0; i<NUMNET; i++)
+		    if (Network[i].system[0] != '!' &&
+			strcmp(Network[i].system, thissys)) {
+			sprintf(cmd,
+			   "usend -s -d%s -uNoLogin -!'%s -u' - 2>/dev/null",
+				Network[i].system, Network[i].rogue);
+
+			/* Execute the command */
+			if ((rmf=popen(cmd, "w")) != NULL) {
+			    unsigned long temp;	/* Temporary value */
+
+			    /* Write out the parameters */
+			    (void) netwrite((unsigned long) amount,
+					  sizeof(unsigned long), rmf);
+
+			    (void) netwrite((unsigned long) monst,
+					  sizeof(short), rmf);
+
+			    (void) netwrite((unsigned long) quest_item,
+					sizeof(short), rmf);
+
+			    (void) fwrite(whoami, 1, strlen(whoami), rmf);
+			    for (j=strlen(whoami); j<LINELEN; j++)
+				putc('\0', rmf);
+
+			    (void) netwrite((unsigned long) flags,
+					  sizeof(short), rmf);
+
+			    temp = (unsigned long)
+				(flags==WINNER ? max_level : level);
+			    (void) netwrite(temp, sizeof(short), rmf);
+
+			    (void) netwrite((unsigned long) player.t_ctype,
+					  sizeof(short), rmf);
+
+			    (void) fwrite(thissys, 1,
+						strlen(thissys), rmf);
+			    for (j=strlen(thissys); j<SYSLEN; j++)
+				putc('\0', rmf);
+
+			    (void) fwrite(login, 1, strlen(login), rmf);
+			    for (j=strlen(login); j<LOGLEN; j++)
+				putc('\0', rmf);
+
+			    /* Close off the command */
+			    (void) pclose(rmf);
+			}
+		    }
+		    _exit(0);	/* Exit network process */
+#endif
+	    }
+	}
+    }
+
+    /*
+     * SCOREIT -- rogue -s option.  Never started curses if this option.
+     * UPDATE -- network scoring update.  Never started curses if this option.
+     * EDITSCORE -- want to delete or change a score.
+     */
+/*   if (flags != SCOREIT && flags != UPDATE && prflags != EDITSCORE)
+	endwin();	*/
+
+    if (flags != UPDATE) {
+	if (flags != SCOREIT) {
+	    clear();
+	    refresh();
+	    endwin();
+	}
+	/*
+	* Print the list
+	*/
+	printf("\nTop %d Adventurers:\nRank     Score\tName\n",
+		NUMSCORE);
+
+	for (scp = top_ten; scp <= &top_ten[NUMSCORE-1]; scp++) {
+	    char *class;
+
+	    if (scp->sc_score != 0) {
+		switch (scp->sc_ctype) {
+		    case C_FIGHTER:	class = "fighter";
+		    when C_MAGICIAN:	class = "magician";
+		    when C_CLERIC:	class = "cleric";
+		    when C_THIEF:	class = "thief";
+		    otherwise:		class = "unknown";
+		}
+
+		/* Make sure we have an in-bound reason */
+		if (scp->sc_flgs > REASONLEN) scp->sc_flgs = REASONLEN;
+
+		printf("%3d %10lu\t%s (%s)", scp - top_ten + 1,
+		    scp->sc_score, scp->sc_name, class);
+   
+		if (prflags == REALLIFE) printf(" [in real life %.*s!%.*s]",
+				SYSLEN, scp->sc_system, LOGLEN, scp->sc_login);
+		printf(":\n\t\t%s on level %d", reason[scp->sc_flgs],
+			    scp->sc_level);
+
+		switch (scp->sc_flgs) {
+		    case KILLED:
+			printf(" by");
+			killer = killname(scp->sc_monster);
+			printf(" %s", killer);
+			break;
+
+		    case WINNER:
+			printf(" with the %s",
+				rel_magic[scp->sc_quest].mi_name);
+			break;
+		}
+
+		if (prflags == EDITSCORE)
+		{
+		    fflush(stdout);
+		    fgets(prbuf,80,stdin);
+		    printf("\n");
+		    if (prbuf[0] == 'd') {
+			for (sc2 = scp; sc2 < &top_ten[NUMSCORE-1]; sc2++)
+			    *sc2 = *(sc2 + 1);
+			top_ten[NUMSCORE-1].sc_score = 0;
+			for (i = 0; i < 80; i++)
+			    top_ten[NUMSCORE-1].sc_name[i] = rnd(255);
+			top_ten[NUMSCORE-1].sc_flgs = RN;
+			    top_ten[NUMSCORE-1].sc_level = RN;
+			    top_ten[NUMSCORE-1].sc_monster = RN;
+			    scp--;
+		    }
+		    else if (prbuf[0] == 'e') {
+			printf("Death type: ");
+			fgets(prbuf,80,stdin);
+			if (prbuf[0] == 'M' || prbuf[0] == 'm')
+			    scp->sc_monster = makemonster(FALSE);
+			else scp->sc_monster = getdeath();
+			clear();
+			refresh();
+		    }
+		}
+		else printf("\n");
+	    }
+	}
+        if ((flags != SCOREIT) && (flags != UPDATE)) {
+            printf("\n[Press return to exit]");
+            fflush(stdout);
+            fgets(prbuf,80,stdin);
+        }
+/*	if (prflags == EDITSCORE) endwin(); */	/* End editing windowing */
+    }
+    fseek(outf, 0L, 0);
+    /*
+     * Update the list file
+     */
+    scoreout(top_ten, outf);
+    fclose(outf);
+}
+
+/*
+ * scorein:
+ *	Convert a character string that has been translated from a
+ * score file by scoreout() back to a score file structure.
+ */
+scorein(scores, fd)
+struct sc_ent scores[];
+int fd;
+{
+    int i;
+    char scoreline[100];
+
+    for(i = 0; i < NUMSCORE; i++)
+    {
+        encread((char *) &scores[i].sc_name, LINELEN, fd);
+        encread((char *) &scores[i].sc_system, SYSLEN, fd);
+        encread((char *) &scores[i].sc_login, LINELEN, fd);
+        encread((char *) scoreline, 100, fd);
+        sscanf(scoreline, " %lu %d %d %d %d %d \n",
+        &scores[i].sc_score,   &scores[i].sc_flgs,
+        &scores[i].sc_level,   &scores[i].sc_ctype,
+        &scores[i].sc_monster, &scores[i].sc_quest);
+    }
+}
+
+/*
+ * scoreout:
+ *	Convert a score file structure to a character string.  We do
+ * this for compatibility sake since some machines write out fields in
+ * different orders.
+ */
+scoreout(scores, outf)
+struct sc_ent scores[];
+FILE *outf;
+{
+    int i;
+    char scoreline[100];
+
+    for(i = 0; i < NUMSCORE; i++)  {
+        memset(scoreline,0,100); 
+        encwrite((char *) scores[i].sc_name, LINELEN, outf); 
+        encwrite((char *) scores[i].sc_system, SYSLEN, outf); 
+        encwrite((char *) scores[i].sc_login, LINELEN, outf); 
+        sprintf(scoreline, " %lu %d %d %d %d %d \n", 
+            scores[i].sc_score,  scores[i].sc_flgs, 
+            scores[i].sc_level,  scores[i].sc_ctype, 
+            scores[i].sc_monster,scores[i].sc_quest);
+        encwrite((char *) scoreline, 100, outf); 
+    } 
+}
+
+/*
+ * showpack:
+ *	Display the contents of the hero's pack
+ */
+showpack(howso)
+char *howso;
+{
+	reg char *iname;
+	reg int cnt, packnum;
+	reg struct linked_list *item;
+	reg struct object *obj;
+
+	idenpack();
+	cnt = 1;
+	clear();
+	mvprintw(0, 0, "Contents of your pack %s:\n",howso);
+	packnum = 'a';
+	for (item = pack; item != NULL; item = next(item)) {
+		obj = OBJPTR(item);
+		iname = inv_name(obj, FALSE);
+		mvprintw(cnt, 0, "%c) %s\n",packnum++,iname);
+		if (++cnt >= LINES - 2 && 
+		    next(item) != NULL) {
+			cnt = 1;
+			mvaddstr(LINES - 1, 0, morestr);
+			refresh();
+			wait_for(stdscr,' ');
+			clear();
+		}
+	}
+	mvprintw(cnt + 1,0,"--- %d  Gold Pieces ---",purse);
+	refresh();
+}
+
+total_winner()
+{
+    register struct linked_list *item;
+    register struct object *obj;
+    register int worth;
+    register char c;
+    register int oldpurse;
+
+    clear();
+    standout();
+    addstr("                                                               \n");
+    addstr("  @   @               @   @           @          @@@  @     @  \n");
+    addstr("  @   @               @@ @@           @           @   @     @  \n");
+    addstr("  @   @  @@@  @   @   @ @ @  @@@   @@@@  @@@      @  @@@    @  \n");
+    addstr("   @@@@ @   @ @   @   @   @     @ @   @ @   @     @   @     @  \n");
+    addstr("      @ @   @ @   @   @   @  @@@@ @   @ @@@@@     @   @     @  \n");
+    addstr("  @   @ @   @ @  @@   @   @ @   @ @   @ @         @   @  @     \n");
+    addstr("   @@@   @@@   @@ @   @   @  @@@@  @@@@  @@@     @@@   @@   @  \n");
+    addstr("                                                               \n");
+    addstr("     Congratulations, you have made it to the light of day!    \n");
+    standend();
+    addstr("\nYou have joined the elite ranks of those who have escaped the\n");
+    addstr("Dungeons of Doom alive.  You journey home and sell all your loot at\n");
+    addstr("a great profit and are appointed leader of a ");
+    switch (player.t_ctype) {
+	case C_MAGICIAN:addstr("magic user's guild.\n");
+	when C_FIGHTER:	addstr("fighters guild.\n");
+	when C_CLERIC:	addstr("monastery.\n");
+	when C_THIEF:	addstr("thief's guild.\n");
+	otherwise:	addstr("tavern.\n");
+    }
+    mvaddstr(LINES - 1, 0, spacemsg);
+    refresh();
+    wait_for(stdscr,' ');
+    clear();
+    mvaddstr(0, 0, "   Worth  Item");
+    oldpurse = purse;
+    for (c = 'a', item = pack; item != NULL; c++, item = next(item))
+    {
+	obj = OBJPTR(item);
+	worth = get_worth(obj);
+	if (obj->o_group == 0)
+	    worth *= obj->o_count;
+	whatis(item);
+	mvprintw(c - 'a' + 1, 0, "%c) %6d  %s", c, worth, inv_name(obj, FALSE));
+	purse += worth;
+    }
+    mvprintw(c - 'a' + 1, 0,"   %5d  Gold Pieces          ", oldpurse);
+    refresh();
+    score(pstats.s_exp + (long) purse, WINNER, '\0');
+    exit(0);
+}
+
+update(top_ten, amount, quest, whoami, flags, level, monst, ctype, system, login)
+struct sc_ent top_ten[];
+unsigned long amount;
+short quest, flags, level, monst, ctype;
+char *whoami, *system, *login;
+{
+    register struct sc_ent *scp, *sc2;
+    int retval=0;	/* 1 if a change, 0 otherwise */
+
+    for (scp = top_ten; scp < &top_ten[NUMSCORE]; scp++) {
+	if (amount >= scp->sc_score)
+	    break;
+
+#ifdef LIMITSCORE	/* Limits player to one entry per class per uid */
+	/* If this good score is the same class and uid, then forget it */
+	if (strncmp(scp->sc_login, login, LOGLEN) == 0 &&
+	    scp->sc_ctype == ctype &&
+	    strncmp(scp->sc_system, system, SYSLEN) == 0) return(0);
+#endif
+    }
+
+    if (scp < &top_ten[NUMSCORE])
+    {
+	retval = 1;
+
+#ifdef LIMITSCORE	/* Limits player to one entry per class per uid */
+    /* If a lower scores exists for the same login and class, delete it */
+    for (sc2 = scp ;sc2 < &top_ten[NUMSCORE]; sc2++) {
+	if (sc2->sc_score == 0L) break;	/* End of useful scores */
+
+	if (strncmp(sc2->sc_login, login, LOGLEN) == 0 &&
+	    sc2->sc_ctype == ctype &&
+	    strncmp(sc2->sc_system, system, SYSLEN) == 0) {
+	    /* We want to delete this entry */
+	    while (sc2 < &top_ten[NUMSCORE-1]) {
+		*sc2 = *(sc2+1);
+		sc2++;
+	    }
+	    sc2->sc_score = 0L;
+	}
+    }
+#endif
+
+	for (sc2 = &top_ten[NUMSCORE-1]; sc2 > scp; sc2--)
+	    *sc2 = *(sc2-1);
+	scp->sc_score = amount;
+	scp->sc_quest = quest;
+	strncpy(scp->sc_name, whoami, LINELEN);
+	scp->sc_flgs = flags;
+	scp->sc_level = level;
+	scp->sc_monster = monst;
+	scp->sc_ctype = ctype;
+	strncpy(scp->sc_system, system, SYSLEN);
+	strncpy(scp->sc_login, login, LOGLEN);
+    }
+
+    return(retval);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/rogue.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,1432 @@
+/*
+ * global variable declaration
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include <ctype.h>
+#include "curses.h"
+#include "rogue.h"
+
+/*
+ * Now all the global variables
+ */
+struct trap traps[MAXTRAPS];
+struct room rooms[MAXROOMS];		/* One for each room -- A level */
+struct room *oldrp;			/* Roomin(&player.t_oldpos) */
+struct thing player;			/* The rogue */
+struct object *cur_armor;		/* What a well dresssed rogue wears */
+struct object *cur_ring[NUM_FINGERS];	/* Which rings are being worn */
+struct object  *cur_misc[NUM_MM];	/* which MM's are in use */
+int cur_relic[MAXRELIC];		/* Currently used relics */
+struct linked_list *lvl_obj = NULL; 
+struct linked_list *mlist = NULL;
+struct linked_list *tlist = NULL;	/* list of monsters fallen down traps */
+struct linked_list *monst_dead = NULL;	/* monster killed by monster	*/
+struct object *cur_weapon = NULL;
+int char_type = -1;			/* what type of character is player */
+int foodlev = 1;			/* how fast he eats food */
+int ntraps;				/* Number of traps on this level */
+int trader = 0;				/* no. of purchases */
+int curprice = -1;			/* current price of item */
+int no_move;				/* Number of turns held in place */
+int seed;				/* Random number seed */
+int dnum;				/* Dungeon number */
+int max_level;				/* Deepest player has gone ever */
+int cur_max;				/* Deepest player has gone currently */
+int lost_dext;				/* amount of lost dexterity */
+int mpos = 0;
+int no_command = 0;
+int level = 1;
+int purse = 0;
+int inpack = 0;
+int total = 0;
+int no_food = 0;			/* how long has he gone with no food */
+int foods_this_level = 0;		/* foods made per level */
+int count = 0;
+int food_left = HUNGERTIME;
+int group = 1;
+int hungry_state = F_OKAY;
+int infest_dam=0;
+int lost_str=0;
+int lastscore = -1;
+int hold_count = 0;
+int trap_tries = 0;
+int pray_time = 0;
+int spell_power = 0;
+int turns = 0;				/* Number of turns player has taken */
+int quest_item = 0;			/* Item player is looking for */
+char nfloors = -1;			/* Number of floors in this dungeon */
+char curpurch[15];			/* name of item ready to buy */
+char PLAYER = VPLAYER;			/* what the player looks like */
+char take;				/* Thing the rogue is taking */
+char prbuf[LINELEN*2];			/* Buffer for sprintfs */
+char outbuf[BUFSIZ];			/* Output buffer for stdout */
+char runch;				/* Direction player is running */
+char *s_names[MAXSCROLLS];		/* Names of the scrolls */
+char *p_colors[MAXPOTIONS];		/* Colors of the potions */
+char *r_stones[MAXRINGS];		/* Stone settings of the rings */
+char *ws_made[MAXSTICKS];		/* What sticks are made of */
+char whoami[LINELEN];			/* Name of player */
+char fruit[LINELEN];			/* Favorite fruit */
+char huh[LINELEN];			/* The last message printed */
+char *s_guess[MAXSCROLLS];		/* Players guess at what scroll is */
+char *p_guess[MAXPOTIONS];		/* Players guess at what potion is */
+char *r_guess[MAXRINGS];		/* Players guess at what ring is */
+char *ws_guess[MAXSTICKS];		/* Players guess at what wand is */
+char *m_guess[MAXMM];			/* Players guess at what MM is */
+char *ws_type[MAXSTICKS];		/* Is it a wand or a staff */
+char file_name[LINELEN];		/* Save file name */
+char score_file[LINELEN];		/* Score file name */
+char home[LINELEN];			/* User's home directory */
+WINDOW *cw;				/* Window that the player sees */
+WINDOW *hw;				/* Used for the help command */
+WINDOW *mw;				/* Used to store mosnters */
+WINDOW *msgw;				/* Used to display messages */
+bool pool_teleport = FALSE;		/* just teleported from a pool */
+bool inwhgt = FALSE;			/* true if from wghtchk() */
+bool after;				/* True if we want after daemons */
+bool waswizard;				/* Was a wizard sometime */
+bool s_know[MAXSCROLLS];		/* Does he know what a scroll does */
+bool p_know[MAXPOTIONS];		/* Does he know what a potion does */
+bool r_know[MAXRINGS];			/* Does he know what a ring does */
+bool ws_know[MAXSTICKS];		/* Does he know what a stick does */
+bool m_know[MAXMM];			/* Does he know what a MM does */
+bool playing = TRUE; 
+bool running = FALSE; 
+bool wizard = FALSE;
+bool notify = TRUE; 
+bool fight_flush = FALSE; 
+bool terse = FALSE; 
+bool auto_pickup = TRUE; 
+bool door_stop = FALSE;
+bool jump = FALSE; 
+bool slow_invent = FALSE; 
+bool firstmove = FALSE; 
+bool askme = FALSE;
+bool in_shell = FALSE; 
+bool daytime = TRUE;
+coord delta;				/* Change indicated to get_dir() */
+LEVTYPE levtype;			/* type of level i'm on */
+
+char *nothing  =	"Nothing seems to happen.";
+char *spacemsg =	"--Press space to continue--";
+char *morestr  =	"-- More --";
+char *retstr   =	"[Press return to continue]";
+
+
+/*
+ * NOTE: the ordering of the points in this array is critical. They MUST
+ *	 be listed in the following sequence:
+ *
+ *		7   4   6
+ *		1   0   2
+ *		5   3   8
+ */
+
+coord grid[9] = {{0,0},
+		 { 0,-1}, { 0, 1}, {-1, 0}, { 1, 0},
+		 {-1,-1}, { 1, 1}, { 1,-1}, {-1, 1}
+		};
+
+struct death_type deaths[DEATHNUM] = {
+    { D_ARROW,		"an arrow"},
+    { D_DART,		"a dart"},
+    { D_BOLT,		"a bolt"},
+    { D_POISON,		"poison"},
+    { D_POTION,		"a cursed potion"},
+    { D_PETRIFY,	"petrification"},
+    { D_SUFFOCATION,	"suffocation"},
+    { D_INFESTATION,	"a parasite"},
+    { D_DROWN,		"drowning"},
+    { D_ROT,		"body rot"},
+    { D_CONSTITUTION,	"poor health"},
+    { D_STRENGTH,	"being too weak"},
+    { D_SIGNAL,		"a bug"},
+    { D_CHOKE,		"dust of choking"},
+    { D_STRANGLE,	"strangulation"},
+    { D_FALL,		"a fall"},
+    { D_RELIC,		"an artifact's wrath"},
+};
+
+
+/*
+ * weapons and their attributes
+ */
+struct init_weps weaps[MAXWEAPONS] = {
+    { "mace",		"2d4",  "1d3", NONE,		ISMETAL, 100, 8 },
+    { "long sword",	"1d12", "1d2", NONE,		ISMETAL, 60, 18 },
+    { "short bow",	"1d1",  "1d1", NONE,		0, 40, 15 },
+    { "arrow",		"1d1",  "1d6", BOW,		ISMANY|ISMISL, 5, 1 },
+    { "dagger",		"1d6",  "1d4", NONE,		ISMETAL|ISMISL|ISMANY, 10, 2 },
+    { "rock",		"1d2",  "1d4", SLING,		ISMANY|ISMISL, 5, 1 },
+    { "two-handed sword","3d6",  "1d2", NONE,		ISMETAL, 250, 40 },
+    { "sling",		"0d0",  "0d0", NONE,  		0, 5, 1 },
+    { "dart",		"1d1",  "1d3", NONE,  		ISMANY|ISMISL, 5, 1 },
+    { "crossbow",	"1d1",  "1d1", NONE,  		0, 100, 15 },
+    { "crossbow bolt",	"1d2", "1d12", CROSSBOW,	ISMANY|ISMISL, 7, 1 },
+    { "spear",		"1d6",  "1d8", NONE,		ISMETAL|ISMISL, 50, 8 },
+    { "trident",	"3d4",  "1d4", NONE,		ISMETAL, 50, 20 },
+    { "spetum",		"2d6",  "1d3", NONE,		ISMETAL, 50, 20 },
+    { "bardiche",	"3d4",  "1d2", NONE,		ISMETAL, 125, 20 },
+    { "pike",		"1d12", "1d8", NONE,		ISMETAL, 80, 18 },
+    { "bastard sword",	"2d8",  "1d2", NONE,		ISMETAL, 100, 30 },
+    { "halberd",	"2d6",  "1d3", NONE,		ISMETAL, 175, 10 },
+    { "battle axe", 	"1d8",	"1d3", NONE,		ISMETAL, 80, 10 },
+};
+
+struct init_armor armors[MAXARMORS] = {
+	{ "leather armor",		11,  8,  70, 100 },
+	{ "ring mail",			22,  7,  50, 250 },
+	{ "studded leather armor",	33,  7,  50, 200 },
+	{ "scale mail",			45,  6,  70, 250 },
+	{ "padded armor",		57,  6, 150, 150 },
+	{ "chain mail",			69,  5, 100, 300 },
+	{ "splint mail",		80,  4, 150, 350 },
+	{ "banded mail",		90,  4, 150, 350 },
+	{ "plate mail",		 	96,  3, 400, 400 },
+	{ "plate armor",		100, 2, 650, 450 },
+};
+
+struct magic_item things[NUMTHINGS] = {
+    { "potion",			260,   10 },	/* potion		*/
+    { "scroll",			260,   30 },	/* scroll		*/
+    { "food",			180,   20 },	/* food			*/
+    { "weapon",			 80,	0 },	/* weapon		*/
+    { "armor",			 80,	0 },	/* armor		*/
+    { "ring",			 50,	5 },	/* ring			*/
+    { "stick",			 60,	0 },	/* stick		*/
+    { "miscellaneous magic",	 30,   50 },	/* miscellaneous magic	*/
+    { "artifact",		  0,   10 },	/* artifact		*/
+};
+
+struct magic_item s_magic[MAXSCROLLS] = {
+    { "monster confusion",	 60, 125, 0, 0 },
+    { "magic mapping",		 50, 150, 0, 0 },
+    { "light",			 80, 100, 21, 15 },
+    { "hold monster",		 30, 200, 33, 20 },
+    { "sleep",			 30, 150, 20, 0 },
+    { "enchantment",		180, 200, 9, 9 },
+    { "identify",		200, 100, 0, 25 },
+    { "scare monster",		 40, 250, 27, 21 },
+    { "gold detection",		 30, 110, 0, 0 },
+    { "teleportation",		 60, 165, 10, 20 },
+    { "create monster",		 30,  75, 0, 0 },
+    { "remove curse",		 70, 120, 9, 15 },
+    { "petrification",		 10, 185, 0, 0 },
+    { "genocide",		 10, 300, 0, 0 },
+    { "cure disease",		 80, 160, 0, 0 },
+    { "acquirement",		 10, 400, 0, 0 },
+    { "protection",		 30, 190, 20, 0 },
+};
+
+struct magic_item p_magic[MAXPOTIONS] = {
+    { "clear thought",		 60, 180, 27, 10 },
+    { "gain ability",		160, 210, 15, 15 },
+    { "see invisible",		 60, 150, 25, 15 },
+    { "healing",		170, 130, 27, 27 },
+    { "monster detection",	 60, 120, 0, 0 },
+    { "magic detection",	 60, 105, 0, 0 },
+    { "raise level",		 20, 350, 11, 10 },
+    { "haste self",		100, 180, 30, 5 },
+    { "restore abilities",	160, 140, 0, 0 },
+    { "phasing",		 50, 210, 21, 20 },
+    { "invisibility",		 50, 230, 0, 15 },
+    { "flying",			 50, 130, 0, 20 },
+};
+
+struct magic_item r_magic[MAXRINGS] = {
+    { "protection",		 50, 200, 33, 25 },
+    { "add strength",		 60, 200, 33, 25 },
+    { "sustain ability",	 50, 500, 0, 0 },
+    { "searching",		 60, 400, 0, 0 },
+    { "extra sight",		 40, 350, 0, 0 },
+    { "alertness",		 40, 380, 0, 0 },
+    { "aggravate monster",	 30, 100, 100, 0 },
+    { "dexterity",		 60, 220, 33, 25 },
+    { "increase damage",	 60, 220, 33, 25 },
+    { "regeneration",		 40, 600, 0, 0 },
+    { "slow digestion",		 40, 240, 15, 15 },
+    { "teleportation",		 20, 100, 100, 0 },
+    { "stealth",		 40, 300, 0, 0 },
+    { "add intelligence",	 60, 240, 33, 25 },
+    { "increase wisdom",	 60, 220, 33, 25 },
+    { "sustain health",		 80, 500, 0,  0 },
+    { "burden",			 20, 100, 100, 0 },
+    { "illumination",		 30, 520, 0, 0 },
+    { "delusion",		 20, 100, 75, 0 },
+    { "fear",			 20, 100, 100, 0},
+    { "heroism",		 30, 390, 0, 0 },
+    { "fire resistance",	 40, 400, 0, 0 },
+    { "warmth",	 		 40, 400, 0, 0 },
+    { "vampiric regeneration",	 10,1000, 0, 0},
+};
+
+struct magic_item ws_magic[MAXSTICKS] = {
+    { "light",			 90, 120, 20, 20 },
+    { "striking",		 60, 115, 0,  0 },
+    { "lightning",		 35, 200, 0,  0 },
+    { "fire",			 35, 200, 0,  0 },
+    { "cold",			 35, 200, 0,  0 },
+    { "polymorph",		 80, 150, 0,  0 },
+    { "magic missile",		 80, 170, 0,  0 },
+    { "slow monster",		 80, 220, 25, 20 },
+    { "drain life",		 90, 210, 20, 0 },
+    { "charging",		 80, 400, 0,  0 },
+    { "teleport monster",	 90, 140, 25, 20 },
+    { "cancellation",		 40, 130, 0,  0 },
+    { "confuse monster",   	 35, 100, 15,  0},
+    { "disintegration",	  	 10, 300, 33, 0},
+    { "petrification",		 10, 300, 0,  0},
+    { "paralyze monster",	 30, 180, 15,  0},
+    { "degenerate monster",	 30, 250, 30, 0},
+    { "curing",			 10, 250, 25, 0},
+    { "wonder",			 50, 110,  0, 0},
+    { "fear",			 30, 180,  0, 0},
+};
+
+/*
+ * WARNING: unique miscellaneous magic items must be put at the end
+ *	    of this list. They MUST be the last items. The function
+ *	    create_obj() in wizard.c depends on it.
+ */
+struct magic_item m_magic[MAXMM] = {
+    { "alchemy jug",	 	  40,   240,  0, 0},
+    { "beaker of potions",	  60,   300,  0, 0},
+    { "book of spells",		  60,   300,  0, 0},
+    { "boots of elvenkind",	  50,   500,  0, 0},
+    { "bracers of defense",	 140,   100, 15, 0},
+    { "chime of opening",	  50,   250,  0, 0},
+    { "chime of hunger",	  50,   100,100, 0},
+    { "cloak of displacement",	  60,   500,  0, 0},
+    { "cloak of protection",	  70,   200, 15, 0},
+    { "drums of panic",		  40,   350,  0, 0},
+    { "dust of disappearance",	  40,   300,  0, 0},
+    { "dust of choking",	  30,   100,100, 0},
+    { "gauntlets of dexterity",	  30,   600, 25, 0},
+    { "gauntlets of ogre power",  30,   600, 25, 0},
+    { "jewel of attacks",	  40,   150,100, 0},
+    { "keoghtoms ointment",	  50,   200,  0, 0},
+    { "robe of powerlessness",	  30,   100,100, 0},
+    { "gauntlets of fumbling",	  30,   100,100, 0},
+    { "necklace of adaptation",	  20,   500,  0, 0},
+    { "necklace of strangulation",30,   110,100, 0},
+    { "boots of dancing",	  30,	120,100, 0},
+    { "book of skills",		  20,	650,  0, 0},
+};
+
+
+struct magic_item rel_magic[MAXRELIC] = {
+    { "Daggers of Musty Doit",	   0, 50000,  0, 0},
+    { "Cloak of Emori",		   0, 50000,  0, 0},
+    { "Ankh of Heil",		   0, 50000,  0, 0},
+    { "Staff of Ming",		   0, 50000,  0, 0},
+    { "Wand of Orcus",		   0, 50000,  0, 0},
+    { "Rod of Asmodeus",	   0, 50000,  0, 0},
+    { "Amulet of Yendor",	   0, 50000,  0, 0},
+    { "Mandolin of Brian",	   0, 50000,  0, 0},
+    { "Horn of Geryon",		   0, 50000,  0, 0},
+    { "Morning Star of Hruggek",   0, 50000,  0, 0},
+    { "Flail of Yeenoghu",	   0, 50000,  0, 0},
+};
+
+/*
+ * these are the spells that a magic user can cast
+ */
+struct spells magic_spells[MAXSPELLS] = {
+	{ P_TFIND,		3,	TYP_POTION,	0	  },
+	{ S_IDENT,		5,	TYP_SCROLL,	0	  },
+	{ S_LIGHT,		7,	TYP_SCROLL,	ISBLESSED },
+	{ S_REMOVE,		7,	TYP_SCROLL,	0	  },
+	{ S_CONFUSE,		10,	TYP_SCROLL,	0	  },
+	{ S_MAP,		10,	TYP_SCROLL,	0	  },
+	{ WS_MISSILE,		15,	TYP_STICK,	0	  },
+	{ P_CLEAR,		20,	TYP_POTION,	0	  },
+	{ S_TELEP,		20,	TYP_SCROLL,	0	  },
+	{ S_SLEEP,		20,	TYP_SCROLL,	0	  },
+	{ P_SEEINVIS,		20,	TYP_POTION,	0	  },
+	{ WS_COLD,		25,	TYP_STICK,	0	  },
+	{ WS_ELECT,		25,	TYP_STICK,	0	  },
+	{ WS_FIRE,		25,	TYP_STICK,	0	  },
+	{ P_HASTE,		30,	TYP_POTION,	0	  },
+	{ WS_CANCEL,		30,	TYP_STICK,	0	  },
+	{ P_PHASE,		40,	TYP_POTION,	0	  },
+	{ S_HOLD,		50,	TYP_SCROLL,	0	  },
+	{ S_PROTECT,		60,	TYP_SCROLL,	0	  },
+	{ S_ALLENCH,		70,	TYP_SCROLL,	0	  },
+};
+
+/*
+ * these are the spells that a cleric can cast
+ */
+struct spells cleric_spells[MAXPRAYERS] = {
+	{ P_MFIND,		3,	TYP_POTION,	0	  },
+	{ P_TFIND,		7,	TYP_POTION,	0	  },
+	{ S_IDENT,		15,	TYP_SCROLL,	0	  },
+	{ S_LIGHT,		15,	TYP_SCROLL,	ISBLESSED },
+	{ S_REMOVE,		20,	TYP_SCROLL,	0	  },
+	{ P_HEALING,		25,	TYP_POTION,	0	  },
+	{ S_CURING,		30,	TYP_SCROLL,	0	  },
+	{ S_MAP,		30,	TYP_SCROLL,	0	  },
+	{ P_CLEAR,		30,	TYP_POTION,	0	  },
+	{ P_SEEINVIS,		35,	TYP_POTION,	0	  },
+	{ P_RESTORE,		40,	TYP_POTION,	0	  },
+	{ P_PHASE,		40,	TYP_POTION,	0	  },
+	{ S_TELEP,		45,	TYP_SCROLL,	0	  },
+	{ WS_CURING,		50,	TYP_STICK,	ISBLESSED },
+	{ WS_DRAIN,		50,	TYP_STICK,	0	  },
+};
+
+char *cnames[4][11] = {
+{	"Veteran",		"Warrior",	
+	"Swordsman",		"Hero",
+	"Swashbuckler",		"Myrmidon",	
+	"Champion",		"Superhero",
+	"Lord",			"Lord",		
+	"Lord"
+},
+{	"Prestidigitator",	"Evoker",	
+	"Conjurer",		"Theurgist",
+	"Thaumaturgist",	"Magician",	
+	"Enchanter",		"Warlock",
+	"Sorcerer",		"Necromancer",
+	"Wizard"
+},
+{	"Acolyte",		"Adept",
+	"Priest",		"Curate",
+	"Prefect",		"Canon",
+	"Lama",			"Patriarch",
+	"High Priest",		"High Priest",
+	"High Priest"
+},
+{	"Rogue",		"Footpad",
+	"Cutpurse",		"Robber",
+	"Burglar",		"Filcher",
+	"Sharper",		"Magsman",
+	"Thief",		"Master Thief",
+	"Master Thief"
+}
+} ;
+
+struct h_list helpstr[] = {
+    '?',	"	prints help",
+    '/',	"	identify object",
+    'h',	"	left",
+    'j',	"	down",
+    'k',	"	up",
+    'l',	"	right",
+    'y',	"	up & left",
+    'u',	"	up & right",
+    'b',	"	down & left",
+    'n',	"	down & right",
+    'H',	"	run left",
+    'J',	"	run down",
+    'K',	"	run up",
+    'L',	"	run right",
+    'Y',	"	run up & left",
+    'U',	"	run up & right",
+    'B',	"	run down & left",
+    'N',	"	run down & right",
+    't',	"<dir>	throw something",
+    'f',	"<dir>	forward until find something",
+    'z',	"<dir>	zap a wand or staff",
+    '>',	"	go down a staircase",
+    '<',	"	go up a staircase",
+    's',	"	search for trap/secret door",
+    '.',	"	rest for a while",
+    'i',	"	inventory",
+    'I',	"	inventory single item",
+    'q',	"	quaff potion",
+    'r',	"	read paper",
+    'e',	"	eat food",
+    'w',	"	wield a weapon",
+    'W',	"	wear something",
+    'T',	"	take off something",
+    'd',	"	drop object",
+    'P',	"	pick up object(s)",
+    'c',	"	call object (generic)",
+    'm',	"	mark object (specific)",
+    'o',	"	examine/set options",
+    'C',	"	cast a spell",
+    'p',	"	pray",
+    'a',	"	affect the undead",
+    '^',	"	set a trap",
+    'G',	"	sense gold",
+    'D',	"	dip something (into a pool)",
+    CTRL('T'),	"<dir>	take (steal) from (direction)",
+    CTRL('U'),	"	use miscellaneous magic item",
+    CTRL('L'),	"	redraw screen",
+    CTRL('R'),	"	repeat last message",
+    ESCAPE,	"	cancel command",
+    'v',	"	print program version number",
+    '!',	"	shell escape",
+    'S',	"	save game",
+    'Q',	"	quit",
+    0, 0
+} ;
+
+struct h_list wiz_help[] = {
+    CTRL('A'),	"	system activity",
+    CTRL('C'),	"	move to	another	dungeon	level",
+    CTRL('D'),	"	down 1 dungeon level",
+    CTRL('E'),	"	food remaining",
+    CTRL('F'),	"	display entire level",
+    CTRL('H'),	"	jump 9 experience levels",
+    CTRL('I'),	"	inventory of level",
+    CTRL('J'),	"	teleport",
+    CTRL('N'),	"	recharge staff",
+    CTRL('P'),	"	toggle wizard status",
+    CTRL('U'),	"	up 1 dungeon level",
+    CTRL('X'),	"	detect monsters",
+    CTRL('Z'),	"	identify",
+    'M',	"	make object",
+    0, 0
+};
+
+
+#define HPT(x) x
+struct monster monsters[NUMMONST+1] = {
+/* {"Name",
+		CARRY,	NORMAL,	WANDER,	APPEAR,	INTEL,
+		{ATTRIBUTES},
+		"SUMMONED_CREATURE", NUMBER_SUMMONED,
+		ADDED_EXPERIENCE/HIT_POINT,
+		{str	exp,	level,	"armor", hit_points,
+		"damage"}}, */
+{"unknown",
+		0,	FALSE,	FALSE,	'\0',	"",
+		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+		0,
+		0, 0,
+		{10,	0,	0,	0,	HPT(""),
+		""}},
+{"bat",
+		0,	TRUE,	FALSE,	'b',	"2-4",
+		{ISMEAN, ISHUH, CANDISEASE, ISFLY, ISHASTE},
+		0, 0,
+		0,
+		{10,	5,	2,	1,	HPT("1d4"),
+		"1d2"}},
+{"giant rat",
+		0,	TRUE,	TRUE,	'R',	"2-4",
+		{ISMEAN, CANDISEASE},
+		0, 0,
+		1,
+		{10,	7,	1,	7,	HPT("1d4"),
+		"1d3"}},
+{"kobold",
+		10,	TRUE,	TRUE,	'K',	"8",
+		{ISMEAN, CANSHOOT, CARRYWEAPON},
+		0, 0,
+		1,
+		{9,	5,	1,	7,	HPT("1d4"),
+		"1d4"}},
+{"gnome",
+		10,	TRUE,	TRUE,	'G',	"11-12",
+		{CANSHOOT, CARRYPOTION, CARRYWEAPON},
+		0, 0,
+		1,
+		{10,	8,	1,	5,	HPT("1d6"),
+		"1d6"}},
+{"halfling",
+		10,	TRUE,	TRUE,	'H',	"11-12",
+		{CANSHOOT, CARRYPOTION, CARRYWEAPON},
+		0, 0,
+		1,
+		{8,	9,	1,	4,	HPT("1d6"),
+		"1d6"}},
+{"dwarf",
+		15,	TRUE,	TRUE,	'D',	"11-12",
+		{CANSHOOT, CARRYPOTION, CARRYWEAPON},
+		0, 0,
+		1,
+		{14,	10,	1,	4,	HPT("1d8"),
+		"1d8"}},
+{"orc",
+		15,	TRUE,	TRUE,	'O',	"8",
+		{ISMEAN, CANSHOOT, CARRYGOLD, CARRYWEAPON},
+		0, 0,
+		1,
+		{12,	10,	1,	6,	HPT("1d8"),
+		"1d8"}},
+{"manes",
+		0,	TRUE,	TRUE,	'M',	"2-4",
+		{ISMEAN, MAGICHIT, ISUNDEAD, TURNABLE},
+		0, 0,
+		1,
+		{10,	18,	1,	7,	HPT("1d8"),
+		"1d2/1d2/1d4"}},
+{"elf",
+		50,	TRUE,	TRUE,	'E',	"13-20",
+		{CANSHOOT, CARRYPOTION, CARRYSCROLL, CARRYWEAPON},
+		0, 0,
+		2,
+		{12,	20,	1,	5,	HPT("1d8+1"),
+		"1d10"}},
+{"hobgoblin",
+		10,	TRUE,	TRUE,	'h',	"8-10",
+		{ISMEAN, CANSHOOT, CARRYWEAPON},
+		0, 0,
+		2,
+		{14,	20,	1,	5,	HPT("1d8+1"),
+		"1d8"}},
+{"fire beetle", 
+		0,	TRUE,	TRUE,	'B',	"0",
+		{ISMEAN, HASFIRE},
+		0, 0,
+		2,
+		{10,	20,	1,	4,	HPT("1d8+2"),
+		"2d4"}},
+{"giant ant",
+		0,	TRUE,	TRUE,	'A',	"1",
+		{ISMEAN, CANPOISON},
+		0, 0,
+		3,
+		{10,	40,	2,	3,	HPT("2d8"),
+		"1d6/1d6"}},
+{"zombie",
+		0,	TRUE,	TRUE,	'Z',	"0",
+		{ISMEAN, ISUNDEAD, TURNABLE},
+		0, 0,
+		2,
+		{10,	20,	2,	8,	HPT("2d8"),
+		"1d8"}},
+{"ear seeker",
+		0,	TRUE,	TRUE,	'e',	"0",
+		{ISMEAN, CANINFEST},
+		0, 0,
+		0,
+		{10,	0,	1,	9,	HPT("1d1"),
+		"0d0"}},
+{"shrieker",
+		0,	TRUE,	FALSE,	'S',	"0",
+		{CANSHRIEK, NOMOVE, NOSTAB},
+		0, 0,
+		1,
+		{10,	5,	3,	7,	HPT("3d8"),
+		"0d0"}},
+{"stirge",
+		0,	TRUE,	TRUE,	's',	"1",
+		{ISMEAN, CANDRAW, ISFLY},
+		0, 0,
+		2,
+		{10,	36,	4,	8,	HPT("1d8+1"),
+		"1d3"}},
+{"gas spore",
+		0,	TRUE,	FALSE,	'a',	"0",
+		{ISMEAN, CANEXPLODE, CANINFEST, ISFLY},
+		0, 0,
+		5,
+		{10,	90,	1,	9,	HPT("1d1"),
+		"1d1"}},
+{"troglodyte",
+		5,	TRUE,	TRUE,	'T',	"5-7",
+		{ISMEAN, CANSMELL, CANSHOOT, CARRYGOLD, CARRYWEAPON},
+		0, 0,
+		2,
+		{10,	36,	2,	5,	HPT("2d8"),
+		"1d3/1d3/2d5"}},
+{"lemure",
+		0,	TRUE,	FALSE,	'L',	"2-4",
+		{ISMEAN, ISREGEN, MAGICHIT, ISUNDEAD, TURNABLE},
+		0, 0,
+		3,
+		{10,	65,	3,	7,	HPT("3d8"),
+		"1d3"}},
+{"bugbear",
+		5,	TRUE,	TRUE,	'b',	"5-8",
+		{ISMEAN, CANSHOOT, CANSURPRISE, CARRYGOLD, CARRYPOTION,
+		 CARRYWEAPON},
+		0, 0,
+		4,
+		{16,	135,	3,	5,	HPT("3d8+1"),
+		"2d4"}},
+{"wererat",
+		20,	TRUE,	TRUE,	'r',	"11-12",
+		{ISMEAN, MAGICHIT, CARRYFOOD},
+		0, 0,
+		4,
+		{10,	150,	3,	6,	HPT("3d8+1"),
+		"1d8"}},
+{"ghoul",
+		0,	TRUE,	TRUE,	'g',	"5-7",
+		{ISMEAN, CANPARALYZE, ISUNDEAD, TURNABLE},
+		0, 0,
+		2,
+		{10,	65,	2,	6,	HPT("2d8"),
+		"1d3/1d3/1d6"}},
+{"leprechaun",
+		100,	TRUE,	FALSE,	'l',	"15-16",
+		{CARRYGOLD, STEALGOLD},
+		0, 0,
+		1,
+		{10,	80,	6,	3,	HPT("1d4+1"),
+		"0d0"}},
+{"ogre",
+		50,	TRUE,	TRUE,	'o',	"5-7",
+		{ISMEAN, CARRYGOLD, CARRYWEAPON},
+		0, 0,
+		5,
+		{18,	90,	4,	5,	HPT("4d8+1"),
+		"1d10"}},
+{"centaur",
+		15,	TRUE,	TRUE,	'C',	"5-10",
+		{CANSHOOT, CARRYPOTION, CARRYGOLD},
+		0, 0,
+		4,
+		{10,	85,	4,	4,	HPT("4d8"),
+		"1d6/1d6"}},
+{"nymph",
+		100,	TRUE,	FALSE,	'N',	"15-16",
+		{STEALMAGIC, CARRYSCROLL, CARRYPOTION},
+		0, 0,
+		3,
+		{10,	350,	4,	9,	HPT("3d8"),
+		"0d0"}},
+{"violet fungi", 
+		0,	TRUE,	FALSE,	'F',	"0",
+		{ISMEAN, CANHOLD, NOMOVE, CANROT, NOSTAB},
+		0, 0,
+		4,
+		{10,	135,	3,	7,	HPT("3d8"),
+		"5d1"}},
+{"giant tick",
+		0,	TRUE,	TRUE,	't',	"0",
+		{ISMEAN, CANDRAW, CANDISEASE},
+		0, 0,
+		2,
+		{10,	105,	3,	3,	HPT("3d8"),
+		"1d4"}},
+{"gelatinous cube", 
+		90, TRUE,	TRUE,	'c',	"0",
+		{ISMEAN, ISSCAVENGE, CANPARALYZE, NOSTAB, CARRYFOOD},
+		0, 0,
+		4,
+		{10,	150,	4,	8,	HPT("4d8"),
+		"2d4"}},
+{"blink dog",
+		0,	TRUE,	TRUE,	'B',	"8-10",
+		{ISMEAN, CANBLINK},
+		0, 0,
+		5,
+		{10,	170,	4,	5,	HPT("4d8"),
+		"1d6"}},
+{"very young dragon", 
+		10,	TRUE,	FALSE,	'd',	"15-16",
+		{ISMEAN, CANBRANDOM, ISGREED, CARRYGOLD, CARRYSTICK},
+		0, 0,
+		9,
+		{10,	100,	9,	-1,	HPT("9d1"),
+		"1d4/1d4/2d4"}},
+{"rust monster", 
+		0,	TRUE,	TRUE,	'R',	"1",
+		{ISMEAN, CANRUST},
+		0, 0,
+		4,
+		{10,	185,	5,	2,	HPT("3d8"),
+		"0d0/0d0"}},
+{"ghast",
+		0,	TRUE,	TRUE,	'G',	"11-12",
+		{CANPARALYZE, CANSTINK, ISMEAN, ISUNDEAD, TURNABLE},
+		0, 0,
+		4,
+		{10,	190,	4,	4,	HPT("4d8"),
+		"1d4/1d4/1d8"}},
+{"blindheim",
+		0,	TRUE,	FALSE,	'b',	"1",
+		{CANBLIND, ISMEAN},
+		0, 0,
+		4,
+		{8,	200,	2,	1,	HPT("4d8+2"),
+		"1d8"}},
+{"shadow",
+		0,	TRUE,	TRUE,	'S',	"5-7",
+		{ISSHADOW, ISMEAN, CANCHILL, ISUNDEAD, TURNABLE},
+		0, 0,
+		4,
+		{10,	255,	3,	7,	HPT("3d8+3"),
+		"1d4+1"}},
+{"gargoyle",
+		5,	TRUE,	TRUE,	'g',	"5-7",
+		{ISMEAN, MAGICHIT, CARRYSTICK},
+		0, 0,
+		5,
+		{10,	165,	4,	5,	HPT("4d8+4"),
+		"1d3/1d3/1d6/1d4"}},
+{"su-monster", 10,	TRUE,	TRUE,	's',	"8-10",
+		{ISMEAN, CARRYSCROLL, CARRYGOLD, CARRYFOOD},
+		0, 0,
+		6,
+		{10,	225,	5,	6,	HPT("5d8+5"),
+		"4d4/2d4"}},
+{"gray ooze", 
+		50,	TRUE,	FALSE,	'o',	"1",
+		{ISMEAN, NOMOVE, CANRUST, ISSCAVENGE, NOCOLD, NOFIRE, NOSTAB,
+		 CARRYSTICK, CARRYFOOD},
+		0, 0,
+		5,
+		{10,	200,	3,	8,	HPT("3d8+3"),
+		"2d8"}},
+{"owlbear",
+		5,	TRUE,	TRUE,	'O',	"5-7",
+		{ISMEAN, CANHUG, CARRYRING, CARRYFOOD},
+		0, 0,
+		8,
+		{10,	225,	5,	5,	HPT("5d8+2"),
+		"1d6/1d6/2d6"}},
+{"quasit",
+		30,	TRUE,	TRUE,	'Q',	"5-7",
+		{ISMEAN, ISREGEN, MAGICHIT, CANSURPRISE, CANITCH,
+		 CARRYSCROLL, CARRYGOLD, CARRYPOTION, NOCOLD, NOFIRE, NOBOLT},
+		0, 0,
+		3,
+		{10,	325,	7,	2,	HPT("3d8"),
+		"1d2/1d2/1d4"}},
+{"doppleganger", 
+		0,	TRUE,	TRUE,	'D',	"11-12",
+		{ISMEAN, CANSURPRISE},
+		0, 0,
+		4,
+		{10,	330,	10,	5,	HPT("4d8"),
+		"1d12"}},
+{"yeti",	
+		30,	TRUE,	TRUE,	'Y',	"8-10",
+		{ISMEAN, CANPARALYZE, CANHUG, NOCOLD, CANSURPRISE,
+		 CARRYGOLD, CARRYPOTION},
+		0, 0,
+		8,
+		{13,	500,	6,	6,	HPT("4d8+4"),
+		"1d6/1d6"}},
+{"leucrotta", 
+		0,	TRUE,	FALSE,	'L',	"8-10",
+		{ISMEAN},
+		0, 0,
+		8,	
+		{10,	475,	6,	4,	HPT("6d8+1"),
+		"3d6/1d6/1d6"}},
+{"imp", 
+		25,	TRUE,	TRUE,	'I',	"8-10",
+		{ISMEAN, ISREGEN, MAGICHIT, CANPOISON, CANSURPRISE,
+		 CANTELEPORT, CARRYRING, CARRYSTICK, NOCOLD, NOBOLT, NOFIRE},
+		0, 0,
+		3,
+		{10,	275,	2,	2,	HPT("2d8+2"),
+		"1d4"}},
+{"cockatrice", 
+		0,	TRUE,	TRUE,	'C',	"1",
+		{ISMEAN, TOUCHSTONE},
+		0, 0,
+		5,
+		{10,	315,	5,	6,	HPT("5d8"),
+		"1d3"}},
+{"wight",
+		0,	TRUE,	TRUE,	'W',	"8-10",
+		{ISMEAN, CANDRAIN, MAGICHIT, ISUNDEAD, TURNABLE},
+		0, 0,
+		5,
+		{10,	540,	4,	5,	HPT("4d8+3"),
+		"1d4"}},
+{"troll",
+		50,	TRUE,	FALSE,	'T',	"5-7",
+		{ISMEAN, ISREGEN, CARRYFOOD, CARRYGOLD, CARRYSTICK},
+		0, 0,
+		8,
+		{18,	600,	6,	4,	HPT("6d8+6"),
+		"1d4+4/1d4+4/2d6"}},
+{"jackalwere", 
+		50,	TRUE,	TRUE,	'J',	"11-12",
+		{ISMEAN, CANSHOOT, CANSNORE, MAGICHIT, CARRYFOOD, CARRYGOLD,
+		 CARRYSCROLL},
+		0, 0,
+		4,
+		{10,	800,	4,	4,	HPT("4d8"),
+		"2d4"}},
+{"wraith",
+		0,	TRUE,	TRUE,	'w',	"11-12",
+		{ISMEAN, CANDRAIN, MAGICHIT, ISUNDEAD, TURNABLE},
+		0, 0,
+		6,
+		{10,	575,	5,	4,	HPT("5d8+3"),
+		"1d6"}},
+{"erinyes",
+		25,	TRUE,	TRUE,	'E',	"8-10",
+		{ISMEAN, CANFRIGHTEN, CANSUMMON, TURNABLE, CANPAIN, CANSEE, 
+		 NOFIRE, CANTELEPORT, CARRYRING, CARRYSTICK},
+		"ghoul", 3, 
+		8,
+		{10,	875,	7,	2,	HPT("6d8+6"),
+		"2d4"}},
+{"lava child", 
+		0,	TRUE,	TRUE,	'l',	"8-10",
+		{ISMEAN, NOMETAL},
+		0, 0,
+		8,	
+		{10,	950,	5,	4,	HPT("5d8+1"),
+		"1d6/1d6/2d12"}},
+{"basilisk",
+		0,	TRUE,	FALSE,	'B',	"1",
+		{ISMEAN, LOOKSTONE},
+		0, 0,
+		8,
+		{10,	1000,	6,	4,	HPT("6d8+1"),
+		"1d10"}},
+{"mummy",
+		20,	TRUE,	FALSE,	'm',	"5-7",
+		{ISMEAN,CANINFEST, MAGICHIT, CANFRIGHTEN, HALFDAMAGE, ISUNDEAD, 
+		 TURNABLE, CARRYRING, CARRYSTICK},
+		0, 0,
+		8,
+		{10,	1150,	6,	3,	HPT("6d8+3"),
+		"1d12"}},
+{"otyugh",
+		0,	TRUE,	TRUE,	'o',	"5-10",
+		{ISMEAN, CANDISEASE},
+		0, 0,
+		8,
+		{10,	700,	7,	3,	HPT("7d8"),
+		"1d8/1d8/1d4+1"}},
+{"adult dragon", 
+		30,	TRUE,	FALSE,	'd',	"15-16",
+		{ISMEAN, CANBRANDOM, ISGREED, CANFRIGHTEN, CARRYGOLD,
+		 CARRYPOTION, CARRYSTICK},
+		0, 0,
+		9,
+		{10,	1000,	9,	-1,	HPT("45d1"),
+		"1d6/1d6/2d6"}},
+{"invisible stalker", 
+		0, TRUE,	TRUE,	'i',	"13-14",
+		{ISMEAN, ISINVIS},
+		0, 0,
+		10,
+		{10,	1090,	8,	3,	HPT("8d8"),
+		"4d4"}},
+{"xorn",
+		0,	TRUE,	TRUE,	'X',	"8-10",
+		{ISMEAN, CANINWALL, NOCOLD, NOFIRE, CANSURPRISE, NOBOLT},
+		0, 0,
+		10,
+		{10,	1275,	7,	-2,	HPT("7d8+7"),
+		"1d3/1d3/1d3/4d6"}},
+{"will-o-wisp", 100,	TRUE,	FALSE,	'W',	"15-16",
+		{ISMEAN, CANSURPRISE, ISFLY, CARRYGOLD, CARRYMISC, NOBOLT},
+		0, 0,
+		12,
+		{10,	2000,	9,	-8,	HPT("9d8"),
+		"2d8"}},
+{"chimera",
+		0,	TRUE,	FALSE,	'c',	"2-4",
+		{ISMEAN, CANBFIRE, NOFIRE},
+		0, 0,
+		12,
+		{10,	1000,	9,	6,	HPT("9d8"),
+		"1d3/1d3/1d4/1d4/2d4/3d4"}},
+{"mimic",
+		20,	TRUE,	FALSE,	'M',	"2-10",
+		{ISDISGUISE, CANHOLD, CARRYFOOD, CARRYRING, CARRYGOLD},
+		0, 0,
+		12,
+		{10,	1300,	9,	7,	HPT("9d8"),
+		"3d4"}},
+{"horned devil", 
+		5,	TRUE,	TRUE,	'H',	"13-14",
+		{ISMEAN, CANFRIGHTEN, CANINFEST, CANPOISON, MAGICHIT, CANSUMMON,
+		 NOFIRE, CANTELEPORT, CARRYGOLD, CARRYRING, CARRYSTICK},
+		"wight", 2, 
+		6,
+		{10,	1320,	7,	-3,	HPT("5d8+5"),
+		"1d4/1d4/1d4+1/1d3"}},
+{"specter",
+		0,	TRUE,	TRUE,	'S',	"13-14",
+		{ISMEAN, DOUBLEDRAIN, ISUNDEAD, TURNABLE},
+		0, 0,
+		10,
+		{10,	1650,	7,	2,	HPT("7d8+3"),
+		"1d8"}},
+{"lamia", 
+		0,	TRUE,	TRUE,	'L',	"13-14",
+		{ISMEAN, TAKEWISDOM},
+		0, 0,
+		9,	
+		{10,	1500,	9,	3,	HPT("9d8"),
+		"1d4/1d4"}},
+{"neo-otyugh",
+		0,	TRUE,	TRUE,	'N',	"10-12",
+		{ISMEAN, CANDISEASE},
+		0, 0,
+		10,
+		{12,	1500,	10,	0,	HPT("12d8"),
+		"2d6/2d6/1d3"}},
+{"barbed devil", 
+		0,	TRUE,	TRUE,	'B',	"11-12",
+		{TOUCHFEAR, CANSUMMON, ISMEAN, CANHOLD, TURNABLE, NOFIRE,
+		 CANTELEPORT},
+		"ghast", 4, 
+		10,
+		{10,	1425,	8,	0,	HPT("8d8"),
+		"2d4/2d4/3d4"}},
+{"vrock",
+		10,	TRUE,	TRUE,	'V',	"5-7",
+		{ISMEAN, CANSUMMON, CANSEE, TURNABLE, CANTELEPORT, CARRYGOLD,
+		 CARRYRING, CARRYSTICK},
+		"erinyes", 2, 
+		10,
+		{10,	1500,	8,	0,	HPT("8d8"),
+		"1d4/1d4/1d8/1d8/1d6"}},
+{"shambling mound", 
+		25, TRUE,	TRUE,	's',	"5-7",
+		{ISMEAN, CANSUFFOCATE, NOCOLD, NOFIRE, CANHOLD, CARRYGOLD,
+		 CARRYFOOD, CARRYRING},
+		0, 0,
+		10,
+		{10,	1800,	9,	0,	HPT("9d8"),
+		"2d8/2d8"}},
+{"umber hulk",
+		40,	TRUE,	TRUE,	'U',	"8-10",
+		{ISMEAN, CANHUH, CANINWALL, CANTUNNEL, CARRYSCROLL,
+		 CARRYPOTION, CARRYFOOD},
+		0, 0,
+		12,
+		{10,	1700,	8,	2,	HPT("8d8+8"),
+		"3d4/3d4/2d5"}},
+{"ettin",
+		0,	TRUE,	TRUE,	'e',	"0",
+		{ISMEAN, CANSHOOT},
+		0, 0,
+		14,
+		{10,	1950,	10,	3,	HPT("10d8"),
+		"2d8/3d6"}},
+{"black pudding", 
+		30,	TRUE,	FALSE,	'P',	"0",
+		{ISMEAN, CANRUST, NOCOLD, BOLTDIVIDE, BLOWDIVIDE, ISSCAVENGE, 
+		 NOSTAB, CARRYSCROLL, CARRYSTICK, CARRYPOTION, CARRYRING},
+		0, 0,
+		14,
+		{10,	2000,	10,	6,	HPT("10d8"),
+		"3d8"}},
+{"hezrou",
+		15,	TRUE,	TRUE,	'h',	"5-7",
+		{ISMEAN, CANFRIGHTEN, CANSEE, CANSUMMON, TURNABLE, CANTELEPORT,
+		 CARRYPOTION, CARRYRING, CARRYSTICK},
+		"wight", 3, 
+		12,
+		{10,	2000,	9,	-2,	HPT("9d8"),
+		"1d3/1d3/4d4"}},
+{"glabrezu",
+		25,	TRUE,	FALSE,	'G',	"8-10",
+		{ISMEAN, CANFRIGHTEN, CANSEE, CANSUMMON, TURNABLE, CANTELEPORT,
+		 CARRYSCROLL, CARRYPOTION, CARRYGOLD},
+		"wraith", 3, 
+		14,
+		{10,	2400,	10,	-4,	HPT("10d8"),
+		"2d6/2d6/1d3/1d3/1d4+1"}},
+{"bone devil",
+		0,	TRUE,	TRUE,	'b',	"11-12",
+		{ISMEAN, CANFRIGHTEN, CANSEE, CANSUMMON, CANSURPRISE, CANCHILL, 
+		 TURNABLE, NOFIRE, NOCOLD, CANTELEPORT},
+		"ghast", 3, 
+		12,
+		{10,	2800,	9,	-1,	HPT("9d8"),
+		"2d4"}},
+{"white pudding", 
+		30,	TRUE,	FALSE,	'w',	"0",
+		{ISMEAN, CANDISSOLVE, NOCOLD, BOLTDIVIDE, BLOWDIVIDE, 
+		 ISSCAVENGE, NOSTAB, CARRYRING, CARRYSTICK, CARRYSCROLL,
+		 CARRYPOTION},
+		0, 0,
+		14,
+		{10,	2200,	9,	8,	HPT("10d8"),
+		"7d4"}},
+{"vampire",
+		20,	TRUE,	TRUE,	'v',	"15-16",
+		{ISMEAN, ISREGEN, CANSUCK, ISUNDEAD, TURNABLE, CARRYMISC},
+		0, 0,
+		12,
+		{20,	3800,	8,	1,	HPT("8d8+3"),
+		"1d6+4"}},
+{"ghost",	
+		20,	TRUE,	FALSE,	'g',	"13-14",
+		{ISMEAN, CANFRIGHTEN, CANAGE, ISUNDEAD, TURNABLE, CARRYMISC, 
+		 CMAGICHIT, CANINWALL},
+		0, 0,
+		10,
+		{13,	5000,	12,	0,	HPT("10d8"),
+		"1d12"}},
+{"intellect devourer",
+		0,	TRUE,	FALSE,	'D',	HPT("11-12"),
+		{ISMEAN, TAKEINTEL, CMAGICHIT, HALFDAMAGE, CANSURPRISE, NOFIRE, 
+		 NOCOLD},
+		0, 0,
+		9,
+		{10,	5000,	7,	4,	HPT("6d8+6"),	
+		"1d4/1d4/1d4/1d4"}},
+{"ice devil",
+		30,	TRUE,	FALSE,	'I',	"13-14",
+		{ISMEAN, CANSEE, ISREGEN, CANFRIGHTEN, CANSUMMON, CANBICE, 
+		 NOCOLD, NOFIRE, CANSLOW, CANTELEPORT, CARRYSCROLL, CARRYRING,
+		 CARRYSTICK},
+		"bone devil", 2, 
+		16,
+		{20,	4400,	11,	-4,	HPT("11d8"),
+		"1d4/1d4/2d4/3d4"}},
+{"purple worm", 
+		70,	TRUE,	TRUE,	'p',	"0",
+		{ISMEAN, CANPOISON, CANINWALL, CANTUNNEL, CARRYFOOD, CARRYGOLD},
+		0, 0,
+		20,
+		{10,	4900,	15,	6,	HPT("15d8"),
+		"2d12/2d4"}},
+{"ancient brass dragon", 
+		70,	TRUE,	FALSE,	'r',	"13-14",
+		{CANBSGAS, CANBFGAS, ISGREED, CANSEE, NOSLEEP, NOFEAR,
+		 CARRYGOLD, CARRYRING},
+		0, 0,
+		50,
+		{10,	10000,	8,	2,	HPT("0d8+64"),
+		"1d4/1d4/4d4"}},
+{"pit fiend",
+		100,	TRUE,	TRUE,	'f',	"15-16",
+		{ISMEAN, CANSEE, BMAGICHIT, CANFRIGHTEN, CANHOLD, CANSUMMON, 
+		 CANBFIRE, NOFIRE, CANTELEPORT, CARRYSTICK, HASFIRE},
+		"barbed devil", 3, 
+		18,
+		{22,	10000,	13,	-3,	HPT("13d8"),
+		"1d4+4/1d6+6"}},
+{"ancient white dragon", 
+		70,	TRUE,	TRUE,	'W',	"8-9",
+		{ISMEAN, CANBICE, ISGREED, CANSEE, NOCOLD, CARRYGOLD,
+		 CARRYRING},
+		0, 0,
+		50,
+		{10,	15000,	7,	3,	HPT("0d8+56"),
+		"1d4/1d4/2d8"}},
+{"ancient black dragon", 
+		70,	TRUE,	TRUE,	'a',	"8-10",
+		{ISMEAN, CANBACID, NOACID, ISGREED, CANSEE, CARRYGOLD,
+		 CARRYSTICK},
+		0, 0,
+		50,
+		{10,	20000,	8,	3,	HPT("0d8+64"),
+		"1d4/1d4/3d6"}},
+{"lich",
+		60,	TRUE,	TRUE,	'l',	"19-20",
+		{ISMEAN, CANDRAIN, CANSEE, CANPARALYZE, CANFRIGHTEN, MAGICHIT, 
+		 ISUNDEAD, TURNABLE, NOBOLT, CANMISSILE, CANSUMMON, CARRYGOLD,
+		 CARRYSCROLL, CARRYPOTION, CARRYRING},
+		"specter", 2,
+		16,
+		{10,	20000,	17,	0,	HPT("11d8"),
+		"1d10"}},
+{"titan",
+		80,	TRUE,	FALSE,	't',	"17-20",
+		{ISSHADOW, CANSEE, CANMISSILE, CARRYRING, CARRYSTICK, 
+		 CANTELEPORT},
+		0, 0,
+		30,
+		{13,	20000,	19,	-3,	HPT("22d8"),
+		"8d6"}},
+{"ancient copper dragon", 
+		70,	TRUE,	FALSE,	'c',	"13-14",
+		{CANBACID, NOACID, CANBSLGAS, ISGREED, CANSEE, NOSLOW,
+		 CARRYGOLD, CARRYSTICK},
+		0, 0,
+		50,
+		{10,	20000,	9,	1,	HPT("0d8+72"),
+		"1d4/1d4/5d4"}},
+{"ancient green dragon", 
+		50,	TRUE,	TRUE,	'E',	"10-12",
+		{ISMEAN, CANBGAS, ISGREED, CANSEE, NOGAS, CARRYGOLD,
+		 CARRYRING, CARRYSTICK},
+		0, 0,
+		50,
+		{10,	20000,	9,	2,	HPT("0d8+72"),
+		"1d6/1d6/2d10"}},
+{"ancient bronze dragon", 
+		50,	TRUE,	FALSE,	'L',	"15-16",
+		{CANBCGAS, CANBBOLT, CANBFGAS, ISGREED, CANSEE, NOFEAR, NOBOLT, 
+		 ISCLEAR, CARRYGOLD, CARRYRING, CARRYSTICK},
+		0, 0,
+		50,
+		{10,	20000,	10,	0,	HPT("0d8+80"),
+		"1d6/1d6/4d6"}},
+{"ancient blue dragon", 
+		50,	TRUE,	TRUE,	'u',	"12-14",
+		{ISMEAN, CANBBOLT, ISGREED, CANSEE, NOBOLT, CARRYGOLD,
+		 CARRYSCROLL, CARRYRING, CARRYSTICK},
+		0, 0,
+		50,
+		{10,	20000,	10,	2,	HPT("0d8+80"),
+		"1d6/1d6/3d8"}},
+{"ancient silver dragon", 
+		40,	TRUE,	FALSE,	'S',	"15-16",
+		{CANBICE, CANBPGAS, ISGREED, CANSEE, CANMISSILE, NOCOLD, 
+		 NOPARALYZE, CARRYGOLD, CARRYSCROLL, CARRYRING, CARRYSTICK},
+		0, 0,
+		50,
+		{10,	20000,	11,	-1,	HPT("0d8+88"),
+		"1d6/1d6/5d6"}},
+{"frost giant",
+		50,	TRUE,	TRUE,	'F',	"5-10",
+		{ISMEAN, NOCOLD, CARRYGOLD, CARRYSTICK},
+		0, 0,
+		40,
+		{25,	20000,	15,	4,	HPT("10d8+4"),
+		"4d6"}},
+{"ancient red dragon", 
+		40,	TRUE,	TRUE,	'R',	"15-16",
+		{ISMEAN, CANBFIRE, ISGREED, CANSEE, NOFIRE, CARRYGOLD,
+		 CARRYPOTION, CARRYRING, CARRYSTICK},
+		0, 0,
+		50,
+		{10,	20000,	11,	-1,	HPT("0d8+88"),
+		"1d8/1d8/3d10"}},
+{"ancient gold dragon", 
+		50,	TRUE,	TRUE,	'G',	"17-18",
+		{CANBFIRE, CANBGAS, ISGREED, CANSEE, CANMISSILE, NOFIRE, NOGAS,
+		 CARRYGOLD, CARRYPOTION, CARRYRING, CARRYSTICK, CANTELEPORT},
+		0, 0,
+		50,
+		{10,	20000,	12,	-2,	HPT("0d8+96"),
+		"1d8/1d8/6d6"}},
+{"fire giant",
+		30,	TRUE,	TRUE,	'f',	"6-10",
+		{ISMEAN, CARRYGOLD, NOFIRE, CARRYSTICK},
+		0, 0,
+		45,
+		{27,	26000,	15,	4,	HPT("11d8+5"),
+		"5d6"}},
+{"storm giant",
+		30,	TRUE,	TRUE,	's',	"8-10",
+		{ISMEAN, NOBOLT, CANBBOLT, CARRYRING},
+		0, 0,
+		50,
+		{30,	30000,	15,	2,	HPT("15d8+8"),
+		"7d6"}},
+{"dwarven thief (Musty Doit)",
+		50,	TRUE,	TRUE,	'm',	"16",
+		{ISMEAN, ISUNIQUE, ISINVIS, NOFIRE, NOGAS, NOSTAB, STEALGOLD,
+		 STEALMAGIC, CANPAIN, ISFLY, CARRYGOLD, CANSURPRISE, CANSEE,
+		 CARRYDAGGER, CARRYMISC, CARRYPOTION, CANBSTAB, ISSCAVENGE},
+		0, 0,
+		0,
+		{11,	300000,	20,	-5,	HPT("0d8+95"),
+		"6d4+70/6d4+70"}},
+{"demon prince (Jubilex)", 
+		100,	TRUE,	FALSE,	'J',	"18",
+		{ISMEAN, ISUNIQUE, CANFRIGHTEN, ISREGEN, BMAGICHIT, ISSHADOW, 
+		 CANHOLD, CANDISEASE, CANSUMMON, CANSEE, CANROT, CANINFEST, 
+		 CANRUST, NOSTAB, CANTELEPORT, CARRYMISC},
+		"black pudding", 4, 
+		0,
+		{10,	100000,	20,	-7,	HPT("0d8+88"),
+		"4d10"}},
+{"arch devil (Geryon)", 
+		100,	TRUE,	FALSE,	'g',	"16",
+		{ISMEAN, ISUNIQUE, BMAGICHIT, CANSEE, ISSHADOW, CANFRIGHTEN, 
+		 CANHUH, CANPOISON, CANSUMMON, NOFIRE, CANTELEPORT,
+		 CARRYMISC, CARRYHORN},
+		"ice devil", 5, 
+		0,
+		{13,	110000,	30,	-3,	HPT("0d8+133"),
+		"3d6/3d6/2d4"}},
+{"arch devil (Dispater)", 
+		100,	TRUE,	FALSE,	'd',	"18",
+		{ISMEAN, ISUNIQUE, CANSEE, CANFRIGHTEN, CANHUH, BMAGICHIT, 
+		 CANSUMMON, NOFIRE, CANTELEPORT, CARRYMISC},
+		"ghost", 9, 
+		0,
+		{10,	120000,	36,	-2,	HPT("0d8+144"),
+		"4d6"}},
+{"demon prince (Yeenoghu)", 
+		100,	TRUE,	FALSE,	'Y',	"16",
+		{ISMEAN, ISREGEN, ISUNIQUE, MAGICHIT, CANSEE, ISSHADOW, CANHOLD,
+		 CARRYFLAIL, CANFRIGHTEN, CANPARALYZE, CANSUMMON, CANHUH, 
+		 CANMISSILE, CANTELEPORT, CARRYMISC},
+		"lich", 5, 
+		0,
+		{10,	130000,	23,	-5,	HPT("0d8+100"),
+		"3d6/3d6"}},
+{"witch (Emori)",
+		50,	TRUE,	FALSE,	'w',	"18",
+		{ISMEAN, CANMISSILE, ISINVIS, CANBBOLT, CANBFIRE, CANBICE,
+		 CANSEE, CANSUMMON, ISUNIQUE, CANSNORE, ISFLY, TAKEINTEL,
+		 CANDANCE, CANDISEASE, NOBOLT, NOCOLD, NOFIRE, CARRYCLOAK,
+		 ISCLEAR, CARRYSCROLL, CARRYSTICK, CANTELEPORT},
+		"shambling mound", 5,
+		0,
+		{11,	240000,	25,	 6,	HPT("0d8+102"),
+		"1d4/1d4"}},
+{"cleric of Thoth (Heil)",
+		100,	TRUE,	FALSE,	'h',	"16",
+		{ISMEAN, CANSEE, NOFEAR, ISREGEN, CANHOLD, CANBFIRE, ISUNIQUE, 
+		 DOUBLEDRAIN, CANSUMMON, NOFIRE, TOUCHFEAR, CANDISEASE,
+		 CANSEE, TAKEWISDOM, CARRYANKH, CARRYRING, ISINVIS, ISFLY},
+		 "mummy", 9,
+		 0,
+		 {15,	295000,	20,	-8,	HPT("0d8+116"),
+		 "0d6+11"}},
+{"magician (Tsoming Zen)",
+		80,	TRUE,	FALSE,	'z',	"18",
+		{ISMEAN, ISUNIQUE, ISINVIS, ISREGEN, CANBFIRE, CANBICE,
+		 CANBBOLT, CANMISSILE, NOFIRE, CANHOLD, CANFRIGHTEN, CANDISEASE,
+		 CANPAIN, CANSUMMON, CANSEE, ISFLY, CANBLINK, CANTELEPORT,
+		 CARRYSTAFF, CARRYSTICK, NOSLOW, NOBOLT, NOCOLD},
+		 "blink dog", 5,
+		 0,
+		 {16,	310000,	21,	  0,	HPT("0d8+125"),
+		 "2d4+1/2d4+1/2d4+1/2d4+1"}},
+{"poet (Brian)",
+		80,	TRUE,	TRUE,	'p',	"16",
+		{ISMEAN, ISUNIQUE, STEALGOLD, ISSHADOW, CANSUMMON, ISREGEN,
+		 CANDISEASE, NOCOLD, NOBOLT, NOFIRE, NOFEAR, CANTUNNEL, CANSEE,
+		 CANINWALL, ISCLEAR, CARRYMANDOLIN, CARRYPOTION, CARRYRING},
+		"umber hulk", 6,
+		0,
+		{19,	320000,	20,	-2,	HPT("0d8+153"),
+		"8d8+48/4d4+36"}},
+{"lesser god (Hruggek)",
+		100,	TRUE,	FALSE,	'H',	"17",
+		{ISMEAN, CANSEE, ISUNIQUE, CANSUMMON, ISREGEN, 
+		 CANTELEPORT, CARRYMISC, CARRYMSTAR},
+		"purple worm", 6,
+		0,
+		{19,	140000,	25,	0,	HPT("0d8+221"),
+		"2d8/2d8"}},
+{"lesser god (Kurtulmak)",
+		100,	TRUE,	TRUE,	'K',	"19",
+		{ISMEAN, CANFRIGHTEN, CANPOISON, CANSEE, ISUNIQUE, CANSUMMON,
+		 CANTELEPORT, CARRYMISC},
+		"lich", 3,
+		0,
+		{19,	150000,	27,	0,	HPT("0d8+219"),
+		"2d12/1d6"}},
+{"demigod (Vaprak \"The Destroyer\")",
+		100,	TRUE,	TRUE,	'v',	"18",
+		{ISMEAN, ISUNIQUE, ISREGEN, MAGICHIT, CANSEE, CANSUMMON,
+		 CANTELEPORT, CARRYMISC},
+		"troll", 9,
+		0,
+		{16,	160000,	26,	0,	HPT("0d8+198"),
+		"2d10/2d10/1d12"}},
+{"platinum dragon (Bahamut)", 
+		100,	TRUE,	FALSE,	'P',	"20",
+		{ISUNIQUE, CANBICE, CANBGAS, CANBBOLT, CANBRANDOM, CANSEE, 
+		 NOCOLD, NOBOLT, NOGAS, NOFIRE, NOFEAR, NOSLEEP, NOSLOW, 
+		 NOPARALYZE, CANMISSILE, CANSONIC, CANFRIGHTEN, CANSUMMON,
+		 CARRYSTICK, CARRYMISC, CANTELEPORT},
+		"ancient gold dragon", 4,
+		0,
+		{10,	170000,	38,	-3,	HPT("0d8+168"),
+		"2d6/2d6/6d8"}},
+{"arch devil (Baalzebul)", 
+		100,	TRUE,	FALSE,	'B',	"18",
+		{ISMEAN, ISSHADOW, ISUNIQUE, BMAGICHIT, CANHOLD, CANPOISON, 
+		 CANFRIGHTEN, CANHUH, CANSUMMON, CANSEE, NOFIRE, CANTELEPORT,
+		 CARRYMISC},
+		"horned devil", 9, 
+		0,
+		{10,	180000,	37,	-5,	HPT("0d8+166"),
+		"2d6"}},
+{"chromatic dragon (Tiamat)", 
+		100,	TRUE,	FALSE,	'C',	"18",
+		{ISMEAN, ISUNIQUE, CANBFIRE, CANBACID, CANBBOLT, CANBICE, 
+		 CANBGAS, CANBRANDOM, CANSEE, NOFIRE, NOBOLT, NOCOLD, NOACID, 
+		 NOGAS, CANSUMMON, CANMISSILE, CANFRIGHTEN, CARRYMISC,
+		 CARRYRING, CANTELEPORT},
+		"ancient red dragon", 6,
+		0,
+		{10,	190000,	29,	0,	HPT("0d8+128"),
+		"2d8/3d6/2d10/3d8/3d10/1d6"}},
+{"demon prince (Orcus)", 
+		100,	TRUE,	FALSE,	'O',	"20",
+		{ISMEAN, ISUNIQUE, BMAGICHIT, CANPOISON, CANFRIGHTEN, CANSEE, 
+		 CANBBOLT, CANSUMMON, NOBOLT, CANTELEPORT, CARRYWAND, 
+		 CARRYMISC, CANTELEPORT},
+		"vampire", 9, 
+		0,
+		{13,	200000,	27,	-6,	HPT("0d8+120"),
+		"1d10+3/2d4"}},
+{"arch devil (Asmodeus)", 
+		100,	TRUE,	FALSE,	'A',	"20",
+		{ISMEAN, ISUNIQUE, CANSEE, ISSHADOW, CANHOLD, BMAGICHIT, 
+		 CANFRIGHTEN, CANHUH, CANSLOW, CANSUMMON, NOFIRE,
+		 CANTELEPORT, CARRYROD, CARRYMISC},
+		"pit fiend", 5, 
+		0,
+		{10,	210000,	45,	-7,	HPT("0d8+199"),
+		"1d10+4"}},
+{"demon prince (Demogorgon)", 
+		100,	TRUE,	FALSE,	'D',	"20",
+		{ISMEAN, CANHUH, BMAGICHIT, DOUBLEDRAIN, CANINFEST, CANSEE, 
+		 CANFRIGHTEN, ISUNIQUE, CANSUMMON, CANROT, CANTELEPORT,
+		 CANDISEASE, CARRYMISC},
+		"glabrezu", 9, 
+		0,
+		{10,	220000,	45,	-8,	HPT("0d8+200"),
+		"1d6/1d6"}},
+{"greater god (Maglubiyet)",
+		100,	TRUE,	FALSE,	'M',	"19",
+		{ISMEAN, ISUNIQUE, CMAGICHIT, CANSEE, ISREGEN, CANSUMMON,
+		 CANTELEPORT, CARRYMISC},
+		"lich", 6,
+		0,
+		{10,	230000,	45,	-1,	HPT("0d8+350"),
+		"4d10"}},
+{"greater god (Gruumsh)",
+		100,	TRUE,	FALSE,	'G',	"19",
+		{ISMEAN, ISUNIQUE, CMAGICHIT, CANSEE, ISREGEN, CANSUMMON,
+		 CANTELEPORT, CARRYMISC},
+		"lich", 9,
+		0,
+		{10,	240000,	45,	-1,	HPT("0d8+350"),
+		"4d10"}},
+{"lesser god (Thrym)",
+		100,	TRUE,	FALSE,	'T',	"16",
+		{ISMEAN, NOCOLD, ISUNIQUE, ISREGEN, CMAGICHIT, CANSEE, 
+		 CANSUMMON, CARRYMISC, CANTELEPORT},
+		"frost giant", 9,
+		0,
+		{25,	250000,	45,	-2,	HPT("0d8+300"),
+		"4d10/4d10"}},
+{"lesser god (Surtur)",
+		100,	TRUE,	FALSE,	't',	"19",
+		{ISMEAN, NOFIRE, ISUNIQUE, ISREGEN, CMAGICHIT, CANSEE, 
+		 CANSUMMON, CANMISSILE, CANTELEPORT, CARRYMISC},
+		"fire giant", 9,
+		0,
+		{25,	260000,	45,	-2,	HPT("0d8+380"),
+		"5d10/5d10"}},
+{"lesser god (Skoraeus Stonebones)",
+		100,	TRUE,	FALSE,	'b',	"19",
+		{ISMEAN, ISUNIQUE, ISREGEN, CMAGICHIT, CANSEE, CANSUMMON, 
+		 CANMISSILE, CANINWALL, CANTELEPORT, CARRYMISC, CARRYSTICK},
+		"storm giant", 9,
+		0,
+		{25,	270000,	45,	-1,	HPT("0d8+380"),
+		"6d10/6d10"}},
+{"ruler of greater titans (Yendor)",
+		100,	TRUE,	TRUE,	'y',	 "25",
+		{ISMEAN, CANINWALL, ISUNIQUE, ISREGEN, CMAGICHIT,
+		 CANSUMMON, CANMISSILE, CANFRIGHTEN, CANBFIRE, NOFIRE, 
+		 CANHOLD, CARRYAMULET, CANSEE, CANDANCE, ISSHADOW,
+		 CANTELEPORT, CARRYMISC, CARRYRING, CARRYSTICK},
+		"titan", 15,
+		0,
+		{25,	300000, 45,	-3,	HPT("0d8+400"),
+		"7d10/7d10"}},
+{"quartermaster", 
+		50,	FALSE,	TRUE,	'q',	"18",
+		{CANSELL, CARRYPOTION, CARRYSCROLL, CARRYMISC, CARRYRING,
+		 CARRYSTICK, CANTELEPORT},
+		0, 0,
+		2,
+		{12,	20,	1,	-4, 	HPT("1d8+1"),
+		"1d10"}},
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/rogue.h	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,1117 @@
+/*
+ * Rogue definitions and variable declarations
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#define reg	register	/* register abbr.	*/
+#define NOOP(x) (x += 0)
+#define CCHAR(x) ( (char) (x & A_CHARTEXT) )
+
+/*
+ * Maximum number of different things
+ */
+
+#define MAXDAEMONS	10
+#define MAXFUSES	20
+
+#define NCOLORS         32
+#define NSTONES         47
+#define NWOOD           24
+#define NMETAL          16
+#define NSYLLS          159
+
+#define	MAXROOMS	9
+#define	MAXTHINGS	9
+#define	MAXOBJ		9
+#define MAXSTATS	62	/* max total of all stats at startup */
+#define	MAXPACK		23
+#define	MAXCONTENTS	10
+#define MAXENCHANT	10	/* max number of enchantments on an item */
+#define	MAXTREAS	15	/* number monsters/treasure in treasure room */
+#define	MAXTRAPS	20
+#define	MAXTRPTRY	8	/* attempts/level allowed for setting traps */
+#define	MAXDOORS	4	/* Maximum doors to a room */
+#define	MAXPRAYERS	15	/* Maximum number of prayers for cleric */
+#define	MAXSPELLS	20	/* Maximum number of spells (for magician) */
+#define	NUMMONST	120	/* Current number of monsters */
+#define NUMUNIQUE	24	/* number of UNIQUE creatures */
+#define	NLEVMONS	3	/* Number of new monsters per level */
+#define	MAXFOODS	1
+#define NUMSCORE	20	/* number of entries in score file */
+#define HARDER		35	/* at this level start making things harder */
+#define MAXPURCH	4	/* max purchases per trading post visit */
+#define LINELEN		80	/* characters in a buffer */
+#define JUG_EMPTY	-1	/* signifys that the alchemy jug is empty */
+
+/* Movement penalties */
+#define BACKPENALTY 3
+#define SHOTPENALTY 2		/* In line of sight of missile */
+#define DOORPENALTY 1		/* Moving out of current room */
+
+/*
+ * these defines are used in calls to get_item() to signify what
+ * it is we want
+ */
+#define	ALL		-1
+#define	WEARABLE	-2
+#define	CALLABLE	-3
+#define WIELDABLE	-4
+#define USEABLE		-5
+#define IDENTABLE	-6
+#define REMOVABLE	-7
+#define PROTECTABLE	-8
+#define ZAPPABLE	-9
+
+/*
+ * stuff to do with encumberance
+ */
+#define NORMENCB	1500	/* normal encumberance */
+#define F_OKAY		 0	/* have plenty of food in stomach */
+#define F_HUNGRY	 1	/* player is hungry */
+#define F_WEAK		 2	/* weak from lack of food */
+#define F_FAINT		 3	/* fainting from lack of food */
+
+/*
+ * return values for get functions
+ */
+#define	NORM	0	/* normal exit */
+#define	QUIT	1	/* quit option setting */
+#define	MINUS	2	/* back up one option */
+
+/* 
+ * The character types
+ */
+#define	C_FIGHTER	0
+#define	C_MAGICIAN	1
+#define	C_CLERIC	2
+#define	C_THIEF		3
+#define	C_MONSTER	4
+
+/*
+ * Number of hit points for going up a level
+ */
+#define HIT_FIGHTER	10
+#define HIT_MAGICIAN	8
+#define HIT_CLERIC	8
+#define HIT_THIEF	6
+
+/*
+ * values for games end
+ */
+#define UPDATE  -2
+#define SCOREIT -1
+#define KILLED 	 0
+#define CHICKEN  1
+#define WINNER   2
+
+/*
+ * definitions for function step_ok:
+ *	MONSTOK indicates it is OK to step on a monster -- it
+ *	is only OK when stepping diagonally AROUND a monster
+ */
+#define MONSTOK 1
+#define NOMONST 2
+
+/*
+ * used for ring stuff
+ */
+#define LEFT_1		 0
+#define LEFT_2		 1
+#define LEFT_3		 2
+#define LEFT_4		 3
+#define RIGHT_1		 4
+#define RIGHT_2		 5
+#define RIGHT_3		 6
+#define RIGHT_4		 7
+#define NUM_FINGERS	 8
+
+/*
+ * used for micellaneous magic (MM) stuff
+ */
+#define WEAR_BOOTS	0
+#define WEAR_BRACERS	1
+#define WEAR_CLOAK	2
+#define WEAR_GAUNTLET	3
+#define WEAR_JEWEL	4
+#define WEAR_NECKLACE	5
+#define NUM_MM		6
+
+/*
+ * All the fun defines
+ */
+#define next(ptr) (*ptr).l_next
+#define prev(ptr) (*ptr).l_prev
+#define ldata(ptr) (*ptr).l_data
+#define inroom(rp, cp) (\
+    (cp)->x <= (rp)->r_pos.x + ((rp)->r_max.x - 1) && (rp)->r_pos.x <= (cp)->x \
+ && (cp)->y <= (rp)->r_pos.y + ((rp)->r_max.y - 1) && (rp)->r_pos.y <= (cp)->y)
+#define winat(y, x) (mvwinch(mw, y, x)==' '?mvwinch(stdscr, y, x):winch(mw))
+#define debug if (wizard) msg
+#define RN (((seed = seed*11109+13849) & 0x7fff) >> 1)
+#define unc(cp) (cp).y, (cp).x
+#define cmov(xy) move((xy).y, (xy).x)
+#define DISTANCE(y1, x1, y2, x2) ((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1))
+#define OBJPTR(what)	(struct object *)((*what).l_data)
+#define THINGPTR(what)	(struct thing *)((*what).l_data)
+#define DOORPTR(what)	(coord *)((*what).l_data)
+#define when break;case
+#define otherwise break;default
+#define until(expr) while(!(expr))
+#define ce(a, b) ((a).x == (b).x && (a).y == (b).y)
+#define draw(window) wrefresh(window)
+#define hero player.t_pos
+#define pstats player.t_stats
+#define max_stats player.maxstats
+#define pack player.t_pack
+#define attach(a, b) _attach(&a, b)
+#define detach(a, b) _detach(&a, b)
+#define o_free_list(a) _o_free_list(&a)
+#define t_free_list(a) _t_free_list(&a)
+#undef max
+#undef min
+#define max(a, b) ((a) > (b) ? (a) : (b))
+#define min(a, b) ((a) < (b) ? (a) : (b))
+#define on(thing, flag) \
+    (((thing).t_flags[(flag >> FLAGSHIFT) & FLAGINDEX] & flag) != 0)
+#define off(thing, flag) \
+    (((thing).t_flags[(flag >> FLAGSHIFT) & FLAGINDEX] & flag) == 0)
+#define turn_on(thing, flag) \
+    ((thing).t_flags[(flag >> FLAGSHIFT) & FLAGINDEX] |= (flag & ~FLAGMASK))
+#define turn_off(thing, flag) \
+    ((thing).t_flags[(flag >> FLAGSHIFT) & FLAGINDEX] &= ~flag)
+
+#undef CTRL
+#define CTRL(ch) (ch & 037)
+
+#define ALLOC(x) calloc((unsigned int) x,1)
+#define FREE(x) free((char *) x)
+#define	EQSTR(a, b, c)	(strncmp(a, b, c) == 0)
+#define	EQUAL(a, b)	(strcmp(a, b) == 0)
+#define GOLDCALC (rnd(50 + 10 * level) + 2)
+#define ISRING(h, r) (cur_ring[h] != NULL && cur_ring[h]->o_which == r)
+#define ISWEARING(r)	(ISRING(LEFT_1, r) || ISRING(LEFT_2, r) ||\
+			 ISRING(LEFT_3, r) || ISRING(LEFT_4, r) ||\
+			 ISRING(RIGHT_1, r) || ISRING(RIGHT_2, r) ||\
+			 ISRING(RIGHT_3, r) || ISRING(RIGHT_4, r))
+#define newgrp() ++group
+#define o_charges o_ac
+#define ISMULT(type) (type == FOOD)
+#define isrock(ch) ((ch == WALL) || (ch == '-') || (ch == '|'))
+#define invisible(monst) \
+	    (((on(*monst, ISINVIS) || \
+	       (on(*monst, ISSHADOW) && rnd(100) < 90)) && \
+	      off(player, CANSEE)) || \
+	     (on(*monst, CANSURPRISE) && !ISWEARING(R_ALERT)))
+#define is_stealth(tp) \
+    (rnd(25) < (tp)->t_stats.s_dext || (tp == &player && ISWEARING(R_STEALTH)))
+
+#define has_light(rp) (((rp)->r_flags & HASFIRE) || ISWEARING(R_LIGHT))
+#define mi_wght mi_worth
+
+/*
+ * Ways to die
+ */
+#define	D_PETRIFY	-1
+#define	D_ARROW		-2
+#define	D_DART		-3
+#define	D_POISON	-4
+#define	D_BOLT		-5
+#define	D_SUFFOCATION	-6
+#define	D_POTION	-7
+#define	D_INFESTATION	-8
+#define D_DROWN		-9
+#define D_ROT		-10
+#define D_CONSTITUTION  -11
+#define D_STRENGTH	-12
+#define D_SIGNAL	-13
+#define D_CHOKE		-14
+#define D_STRANGLE	-15
+#define D_FALL		-16
+#define D_RELIC		-17
+#define DEATHNUM	17	/* number of ways to die */
+
+/*
+ * Things that appear on the screens
+ */
+#define	WALL		' '
+#define	PASSAGE		'#'
+#define	DOOR		'+'
+#define	FLOOR		'.'
+#define VPLAYER 	'@'
+#define IPLAYER 	'_'
+#define	POST		'^'
+#define	TRAPDOOR	'>'
+#define	ARROWTRAP	'{'
+#define	SLEEPTRAP	'$'
+#define	BEARTRAP	'}'
+#define	TELTRAP		'~'
+#define	DARTTRAP	'`'
+#define POOL		'"'
+#define MAZETRAP	'\''
+#define	SECRETDOOR	'&'
+#define	STAIRS		'%'
+#define	GOLD		'*'
+#define	POTION		'!'
+#define	SCROLL		'?'
+#define	MAGIC		'$'
+#define	BMAGIC		'>'	/*	Blessed	magic	*/
+#define	CMAGIC		'<'	/*	Cursed	magic	*/
+#define	FOOD		':'
+#define	WEAPON		')'
+#define MISSILE		'*'	/*	Magic Missile	*/
+#define	ARMOR		']'
+#define	MM		';'
+#define RELIC		','
+#define	RING		'='
+#define	STICK		'/'
+#define FOREST		'\\'
+
+/*
+ * Various constants
+ */
+#define	PASSWD		"SihQX7.LYSmbo"
+#define	BEARTIME	3
+#define	SLEEPTIME	4
+#define	FREEZETIME	6
+#define PAINTIME	(roll(1, 6))
+#define	HEALTIME	30
+#define	CHILLTIME	(roll(20, 4))
+#define	SMELLTIME	20
+#define	STONETIME	8
+#define HASTETIME	6
+#define	SICKTIME	10
+#define	STPOS		0
+#define	WANDERTIME	(max(5, HARDER-rnd(vlevel)))
+#define	BEFORE		1
+#define	AFTER		2
+#define	HUHDURATION	20
+#define	SEEDURATION	850
+#define	CLRDURATION	15
+#define GONETIME	200
+#define FLYTIME		300
+#define DUSTTIME	(20+roll(1,10))
+#define	PHASEDURATION	300
+#define	HUNGERTIME	1300
+#define	MORETIME	150
+#define	STINKTIME	6
+#define	STOMACHSIZE	2000
+#define	ESCAPE		27
+#define	BOLT_LENGTH	10
+#define	MARKLEN		20
+#define DAYLENGTH	400
+#define ALCHEMYTIME	(400+rnd(100))
+
+/*
+ * Save against things
+ */
+#define	VS_POISON		00
+#define	VS_PARALYZATION		00
+#define	VS_DEATH		00
+#define	VS_PETRIFICATION	01
+#define	VS_WAND			02
+#define	VS_BREATH		03
+#define	VS_MAGIC		04
+
+/*
+ * attributes for treasures in dungeon
+ */
+#define ISCURSED     	       01
+#define ISKNOW      	       02
+#define ISPOST		       04	/* object is in a trading post */
+#define	ISMETAL     	      010
+#define ISPROT		      020	/* object is protected */
+#define ISBLESSED     	      040
+#define ISMISL      	   020000
+#define ISMANY     	   040000
+/*
+ * Various flag bits
+ */
+#define ISDARK	    	       01
+#define ISGONE	    	       02
+#define	ISTREAS     	       04
+#define ISFOUND     	      010
+#define ISTHIEFSET	      020
+#define FORCEDARK	      040
+/*
+ * 1st set of creature flags (this might include player)
+ */
+#define ISBLIND		0x00000001
+#define	ISINWALL     	0x00000002
+#define ISRUN		0x00000004
+#define	ISFLEE		0x00000008
+#define ISINVIS		0x00000010
+#define ISMEAN		0x00000020
+#define ISGREED		0x00000040
+#define CANSHOOT	0x00000080
+#define ISHELD		0x00000100
+#define ISHUH		0x00000200
+#define ISREGEN		0x00000400
+#define CANHUH		0x00000800
+#define CANSEE		0x00001000
+#define HASFIRE		0x00002000
+#define ISSLOW		0x00004000
+#define ISHASTE		0x00008000
+#define ISCLEAR		0x00010000
+#define CANINWALL	0x00020000
+#define ISDISGUISE	0x00040000
+#define CANBLINK	0x00080000
+#define CANSNORE	0x00100000
+#define HALFDAMAGE	0x00200000
+#define	CANSUCK		0x00400000
+#define	CANRUST		0x00800000
+#define	CANPOISON	0x01000000
+#define	CANDRAIN	0x02000000
+#define ISUNIQUE	0x04000000
+#define	STEALGOLD	0x08000000
+/* 
+ * Second set of flags 
+ */
+#define	STEALMAGIC	0x10000001
+#define	CANDISEASE	0x10000002
+#define HASDISEASE	0x10000004
+#define CANSUFFOCATE	0x10000008
+#define DIDSUFFOCATE	0x10000010
+#define BOLTDIVIDE	0x10000020
+#define BLOWDIVIDE	0x10000040
+#define NOCOLD		0x10000080
+#define	TOUCHFEAR	0x10000100
+#define BMAGICHIT	0x10000200
+#define NOFIRE		0x10000400
+#define NOBOLT		0x10000800
+#define CARRYGOLD	0x10001000
+#define CANITCH		0x10002000
+#define HASITCH		0x10004000
+#define DIDDRAIN	0x10008000
+#define WASTURNED	0x10010000
+#define CANSELL		0x10020000
+#define CANBLIND	0x10040000
+#define NOACID		0x10080000
+#define NOSLOW		0x10100000
+#define NOFEAR		0x10200000
+#define NOSLEEP		0x10400000
+#define NOPARALYZE	0x10800000
+#define NOGAS		0x11000000
+#define CANMISSILE	0x12000000
+#define CMAGICHIT	0x14000000
+#define CANPAIN		0x18000000
+
+/* 
+ * Third set of flags 
+ */
+#define CANSLOW		0x20000001
+#define CANTUNNEL	0x20000002
+#define TAKEWISDOM	0x20000004
+#define NOMETAL		0x20000008
+#define MAGICHIT	0x20000010
+#define CANINFEST	0x20000020
+#define HASINFEST	0x20000040
+#define NOMOVE		0x20000080
+#define CANSHRIEK	0x20000100
+#define CANDRAW		0x20000200
+#define CANSMELL	0x20000400
+#define CANPARALYZE	0x20000800
+#define CANROT		0x20001000
+#define ISSCAVENGE	0x20002000
+#define DOROT		0x20004000
+#define CANSTINK	0x20008000
+#define HASSTINK	0x20010000
+#define ISSHADOW	0x20020000
+#define CANCHILL	0x20040000
+#define	CANHUG		0x20080000
+#define CANSURPRISE	0x20100000
+#define CANFRIGHTEN	0x20200000
+#define CANSUMMON	0x20400000
+#define TOUCHSTONE	0x20800000
+#define LOOKSTONE	0x21000000
+#define CANHOLD		0x22000000
+#define DIDHOLD		0x24000000
+#define DOUBLEDRAIN	0x28000000
+
+/* 
+ * Fourth set of flags 
+ */
+#define CANBRANDOM	0x30000001	/* Types of breath */
+#define CANBACID	0x30000002	/* acid */
+#define CANBFIRE	0x30000004	/* Fire */
+#define CANBCGAS	0x30000008	/* confusion gas */
+#define CANBBOLT	0x30000010	/* lightning bolt */
+#define CANBGAS		0x30000020	/* clorine gas */
+#define CANBICE		0x30000040	/* ice */
+#define CANBFGAS	0x30000080	/* Fear gas */
+#define CANBPGAS	0x30000100	/* Paralyze gas */
+#define CANBSGAS	0x30000200	/* Sleeping gas */
+#define CANBSLGAS	0x30000400	/* Slow gas */
+#define CANBREATHE	0x300007ff	/* Can it breathe at all? */
+/*
+ * Fifth set of flags
+ */
+#define ISUNDEAD	0x40000001
+#define CANSONIC	0x40000002
+#define TURNABLE	0x40000004
+#define TAKEINTEL	0x40000008
+#define NOSTAB		0x40000010
+#define CANDISSOLVE	0x40000020
+#define ISFLY		0x40000040	/* creature can fly */
+#define CANTELEPORT	0x40000080	/* creature can teleport */
+#define CANEXPLODE	0x40000100	/* creature explodes when hit */
+#define CANDANCE	0x40000200	/* creature can make hero "dance" */
+#define ISDANCE		0x40000400	/* creature (hero) is dancing */
+#define CARRYFOOD	0x40000800
+#define CARRYSCROLL	0x40001000
+#define CARRYPOTION	0x40002000
+#define CARRYRING	0x40004000
+#define CARRYSTICK	0x40008000
+#define CARRYMISC	0x40010000
+#define CARRYDAGGER	0x40020000	/* Dagger of Musty */
+#define CARRYCLOAK	0x40040000	/* Cloak of Emori */
+#define CARRYANKH	0x40080000	/* Ankh of Heil */
+#define CARRYSTAFF	0x40100000	/* Staff of Ming */
+#define CARRYWAND	0x40200000	/* Wand of Orcus */
+#define	CARRYROD	0x40400000	/* Rod of Asmodeus */
+#define	CARRYAMULET	0x40800000	/* Amulet of Yendor */
+#define	CARRYMANDOLIN	0x41000000	/* Mandolin of Brian */
+#define MISSEDDISP	0x42000000	/* Missed Cloak of Displacement */
+#define CANBSTAB	0x44000000	/* Can backstab */
+
+
+#define CARRYHORN	0x50000001	/* Horn of Geryon */
+#define CARRYMSTAR	0x50000002	/* Morning Star of Hruggek */
+#define CARRYFLAIL	0x50000004	/* Flail of Yeenoghu */
+#define CARRYWEAPON	0x50000008	/* A generic weapon */
+#define CANAGE		0x50000010	/* can age you */
+
+#define	ISREADY		0x60000001
+#define ISDEAD		0x60000002
+#define ISELSEWHERE	0x60000004
+
+/* Masks for choosing the right flag */
+#define FLAGMASK     0xf0000000
+#define FLAGINDEX    0x0000000f
+#define FLAGSHIFT    28
+#define MAXFLAGS     25			/* max initial flags per creature */
+
+/* 
+ * Mask for cancelling special abilities 
+ * The flags listed here will be the ones left on after the
+ * cancellation takes place
+ */
+#define CANC0MASK (	ISBLIND		| ISINWALL	| ISRUN		| \
+			ISFLEE		| ISMEAN	| ISGREED	| \
+			CANSHOOT	| ISHELD	| ISHUH		| \
+			ISSLOW		| ISHASTE	| ISCLEAR	| \
+			ISUNIQUE )
+#define CANC1MASK (	HASDISEASE	| DIDSUFFOCATE	| CARRYGOLD 	| \
+			HASITCH		| CANSELL 	| DIDDRAIN	| \
+			WASTURNED )
+#define CANC2MASK (	HASINFEST	| NOMOVE	| ISSCAVENGE	| \
+			DOROT		| HASSTINK	| DIDHOLD )
+#define CANC3MASK (	CANBREATHE )
+#define CANC4MASK (	ISUNDEAD	| CANSONIC	| NOSTAB	| \
+			ISFLY		| CARRYFOOD	| CANEXPLODE	| \
+			ISDANCE		| CARRYSCROLL	| CARRYPOTION	| \
+			CARRYRING	| CARRYSTICK	| CARRYMISC	| \
+			CARRYDAGGER	| CARRYCLOAK	| CARRYANKH	| \
+			CARRYSTAFF	| CARRYWAND	| CARRYROD	| \
+			CARRYAMULET	| CARRYMANDOLIN )
+#define CANC5MASK (	CARRYHORN	| CARRYMSTAR 	| CARRYFLAIL )
+
+/* types of things */
+#define TYP_POTION	0
+#define TYP_SCROLL	1
+#define TYP_FOOD	2
+#define TYP_WEAPON	3
+#define TYP_ARMOR	4
+#define TYP_RING	5
+#define TYP_STICK	6
+#define TYP_MM		7
+#define	TYP_RELIC	8
+#define	NUMTHINGS	9
+/*
+ * Potion types
+ */
+#define	P_CLEAR		0
+#define	P_ABIL		1
+#define	P_SEEINVIS	2
+#define	P_HEALING	3
+#define	P_MFIND		4
+#define	P_TFIND		5
+#define	P_RAISE		6
+#define	P_HASTE		7
+#define	P_RESTORE	8
+#define	P_PHASE		9
+#define P_INVIS		10
+#define P_FLY		11
+#define	MAXPOTIONS	12
+/*
+ * Scroll types
+ */
+#define	S_CONFUSE	0
+#define	S_MAP		1
+#define	S_LIGHT		2
+#define	S_HOLD		3
+#define	S_SLEEP		4
+#define	S_ALLENCH	5
+#define	S_IDENT		6
+#define	S_SCARE		7
+#define	S_GFIND		8
+#define	S_TELEP		9
+#define	S_CREATE	10
+#define	S_REMOVE	11
+#define	S_PETRIFY	12
+#define	S_GENOCIDE	13
+#define	S_CURING	14
+#define S_MAKEIT	15
+#define S_PROTECT	16
+#define	MAXSCROLLS	17
+
+/*
+ * Weapon types
+ */
+#define MACE		0		/* mace */
+#define SWORD		1		/* long sword */
+#define BOW		2		/* short bow */
+#define ARROW		3		/* arrow */
+#define DAGGER		4		/* dagger */
+#define ROCK		5		/* rocks */
+#define TWOSWORD	6		/* two-handed sword */
+#define SLING		7		/* sling */
+#define DART		8		/* darts */
+#define CROSSBOW	9		/* crossbow */
+#define BOLT		10		/* crossbow bolt */
+#define SPEAR		11		/* spear */
+#define TRIDENT		12		/* trident */
+#define SPETUM		13		/* spetum */
+#define BARDICHE	14 		/* bardiche */
+#define PIKE		15		/* pike */
+#define BASWORD		16		/* bastard sword */
+#define HALBERD		17		/* halberd */
+#define BATTLEAXE	18		/* battle axe */
+#define MAXWEAPONS	19		/* types of weapons */
+#define NONE		100		/* no weapon */
+
+/*
+ * Armor types
+ */
+#define	LEATHER		0
+#define	RING_MAIL	1
+#define	STUDDED_LEATHER	2
+#define	SCALE_MAIL	3
+#define	PADDED_ARMOR	4
+#define	CHAIN_MAIL	5
+#define	SPLINT_MAIL	6
+#define	BANDED_MAIL	7
+#define	PLATE_MAIL	8
+#define	PLATE_ARMOR	9
+#define	MAXARMORS	10
+
+/*
+ * Ring types
+ */
+#define	R_PROTECT	0
+#define	R_ADDSTR	1
+#define	R_SUSABILITY	2
+#define	R_SEARCH	3
+#define	R_SEEINVIS	4
+#define	R_ALERT		5
+#define	R_AGGR		6
+#define	R_ADDHIT	7
+#define	R_ADDDAM	8
+#define	R_REGEN		9
+#define	R_DIGEST	10
+#define	R_TELEPORT	11
+#define	R_STEALTH	12
+#define	R_ADDINTEL	13
+#define	R_ADDWISDOM	14
+#define	R_HEALTH	15
+#define R_HEAVY		16
+#define R_LIGHT		17
+#define R_DELUSION	18
+#define R_FEAR		19
+#define R_HEROISM	20
+#define R_FIRE		21
+#define R_WARMTH	22
+#define R_VAMPREGEN	23
+#define	MAXRINGS	24
+
+/*
+ * Rod/Wand/Staff types
+ */
+
+#define	WS_LIGHT	0
+#define	WS_HIT		1
+#define	WS_ELECT	2
+#define	WS_FIRE		3
+#define	WS_COLD		4
+#define	WS_POLYMORPH	5
+#define	WS_MISSILE	6
+#define	WS_SLOW_M	7
+#define	WS_DRAIN	8
+#define	WS_CHARGE	9
+#define	WS_TELMON	10
+#define	WS_CANCEL	11
+#define WS_CONFMON	12
+#define WS_DISINTEGRATE	13
+#define WS_PETRIFY	14
+#define WS_PARALYZE	15
+#define WS_MDEG		16
+#define WS_CURING	17
+#define WS_WONDER	18
+#define WS_FEAR		19
+#define	MAXSTICKS	20
+
+/*
+ * miscellaneous magic items
+ */
+#define	MM_JUG		0
+#define	MM_BEAKER	1
+#define	MM_BOOK		2
+#define	MM_ELF_BOOTS	3
+#define MM_BRACERS	4
+#define MM_OPEN		5
+#define MM_HUNGER	6
+#define MM_DISP		7
+#define MM_PROTECT	8
+#define MM_DRUMS	9
+#define MM_DISAPPEAR	10
+#define MM_CHOKE	11
+#define MM_G_DEXTERITY	12
+#define MM_G_OGRE	13
+#define MM_JEWEL	14
+#define MM_KEOGHTOM	15
+#define MM_R_POWERLESS	16
+#define MM_FUMBLE	17
+#define MM_ADAPTION	18
+#define MM_STRANGLE	19
+#define MM_DANCE	20
+#define MM_SKILLS	21
+#define MAXMM		22
+
+/*
+ * Relic types
+ */
+#define MUSTY_DAGGER	0
+#define EMORI_CLOAK	1
+#define HEIL_ANKH	2
+#define MING_STAFF	3
+#define ORCUS_WAND	4
+#define ASMO_ROD	5
+#define YENDOR_AMULET	6
+#define BRIAN_MANDOLIN	7
+#define GERYON_HORN	8
+#define HRUGGEK_MSTAR	9
+#define YEENOGHU_FLAIL	10
+#define MAXRELIC	11
+
+
+#define LEVEL  600
+#define vlevel max(level, turns/LEVEL + 1)
+/*
+ * Now we define the structures and types
+ */
+
+struct delayed_action {
+	int d_type;
+	int (*d_func)();
+	int d_arg;
+	int d_time;
+};
+
+/*
+ * level types
+ */
+typedef enum {
+	NORMLEV,	/* normal level */
+	POSTLEV,	/* trading post level */
+	MAZELEV,	/* maze level */
+	OUTSIDE		/* outside level */
+} LEVTYPE;
+
+/*
+ * Help list
+ */
+
+struct h_list {
+    char h_ch;
+    char *h_desc;
+};
+
+/*
+ * Coordinate data type
+ */
+typedef struct {
+    int x;
+    int y;
+} coord;
+
+/*
+ * structure for the ways to die
+ */
+struct death_type {
+    int reason;
+    char *name;
+};
+
+
+/*
+ * Linked list data type
+ */
+struct linked_list {
+    struct linked_list *l_next;
+    struct linked_list *l_prev;
+    char *l_data;			/* Various structure pointers */
+};
+
+/*
+ * Stuff about magic items
+ */
+
+struct magic_item {
+    char *mi_name;
+    int mi_prob;
+    int mi_worth;
+    int mi_curse;
+    int mi_bless;
+};
+
+/*
+ * Room structure
+ */
+struct room {
+    coord r_pos;			/* Upper left corner */
+    coord r_max;			/* Size of room */
+    long r_flags;			/* Info about the room */
+    struct linked_list *r_fires;	/* List of fire creatures in room */
+    struct linked_list *r_exit;		/* Linked list of exits */
+};
+
+/*
+ * Array of all traps on this level
+ */
+
+struct trap {
+    char tr_type;			/* What kind of trap */
+    char tr_show;			/* Where disguised trap looks like */
+    coord tr_pos;			/* Where trap is */
+    long tr_flags;			/* Info about trap (i.e. ISFOUND) */
+};
+
+/*
+ * Structure describing a fighting being
+ */
+struct stats {
+    short s_str;			/* Strength */
+    short s_intel;			/* Intelligence */
+    short s_wisdom;			/* Wisdom */
+    short s_dext;			/* Dexterity */
+    short s_const;			/* Constitution */
+    short s_charisma;			/* Charisma */
+    unsigned long s_exp;		/* Experience */
+    int s_lvl;				/* Level of mastery */
+    int s_arm;				/* Armor class */
+    int s_hpt;				/* Hit points */
+    int s_pack;				/* current weight of his pack */
+    int s_carry;			/* max weight he can carry */
+    char s_dmg[30];			/* String describing damage done */
+};
+
+/*
+ * Structure describing a fighting being (monster at initialization)
+ */
+struct mstats {
+    short s_str;			/* Strength */
+    unsigned long s_exp;		/* Experience */
+    int s_lvl;				/* Level of mastery */
+    int s_arm;				/* Armor class */
+    char *s_hpt;			/* Hit points */
+    char *s_dmg;			/* String describing damage done */
+};
+
+/*
+ * Structure for monsters and player
+ */
+struct thing {
+    bool t_turn;			/* If slowed, is it a turn to move */
+    bool t_wasshot;			/* Was character shot last round? */
+    char t_type;			/* What it is */
+    char t_disguise;			/* What mimic looks like */
+    char t_oldch;			/* Character that was where it was */
+    short t_ctype;			/* Character type */
+    short t_index;			/* Index into monster table */
+    short t_no_move;			/* How long the thing can't move */
+    short t_quiet;			/* used in healing */
+    coord *t_doorgoal;			/* What door are we heading to? */
+    coord t_pos;			/* Position */
+    coord t_oldpos;			/* Last position */
+    coord *t_dest;			/* Where it is running to */
+    unsigned long t_flags[16];		/* State word */
+    struct linked_list *t_pack;		/* What the thing is carrying */
+    struct stats t_stats;		/* Physical description */
+    struct stats maxstats;		/* maximum(or initial) stats */
+    int    t_reserved;
+	int    t_reserved2;
+	int    t_reserved3;
+};
+
+/*
+ * Array containing information on all the various types of monsters
+ */
+struct monster {
+    const char *m_name;			/* What to call the monster */
+    const short m_carry;			/* Probability of carrying something */
+    bool m_normal;			/* Does monster exist? */
+    bool m_wander;			/* Does monster wander? */
+    const char m_appear;			/* What does monster look like? */
+    const char *m_intel;			/* Intelligence range */
+    const long m_flags[MAXFLAGS];		/* Things about the monster */
+    const char *m_typesum;			/* type of creature can he summon */
+    short m_numsum;			/* how many creatures can he summon */
+    const short m_add_exp;			/* Added experience per hit point */
+    const struct mstats m_stats;		/* Initial stats */
+};
+
+/*
+ * Structure for a thing that the rogue can carry
+ */
+
+struct object {
+    int o_type;				/* What kind of object it is */
+    coord o_pos;			/* Where it lives on the screen */
+    char *o_text;			/* What it says if you read it */
+    char o_launch;			/* What you need to launch it */
+    char o_damage[8];			/* Damage if used like sword */
+    char o_hurldmg[8];			/* Damage if thrown */
+    struct linked_list *contents;	/* contents of this object */
+    int o_count;			/* Count for plural objects */
+    int o_which;			/* Which object of a type it is */
+    int o_hplus;			/* Plusses to hit */
+    int o_dplus;			/* Plusses to damage */
+    int o_ac;				/* Armor class */
+    long o_flags;			/* Information about objects */
+    int o_group;			/* Group number for this object */
+    int o_weight;			/* weight of this object */
+    char o_mark[MARKLEN];		/* Mark the specific object */
+};
+/*
+ * weapon structure
+ */
+struct init_weps {
+    char *w_name;		/* name of weapon */
+    char *w_dam;		/* hit damage */
+    char *w_hrl;		/* hurl damage */
+    char w_launch;		/* need to launch it */
+    int  w_flags;		/* flags */
+    int  w_wght;		/* weight of weapon */
+    int  w_worth;		/* worth of this weapon */
+};
+
+/*
+ * armor structure 
+ */
+struct init_armor {
+	char *a_name;		/* name of armor */
+	int  a_prob;		/* chance of getting armor */
+	int  a_class;		/* normal armor class */
+	int  a_worth;		/* worth of armor */
+	int  a_wght;		/* weight of armor */
+};
+
+struct matrix {
+    int base;			/* Base to-hit value (AC 10) */
+    int max_lvl;		/* Maximum level for changing value */
+    int factor;			/* Amount base changes each time */
+    int offset;			/* What to offset level */
+    int range;			/* Range of levels for each offset */
+};
+
+struct spells {
+    short s_which;		/* which scroll or potion */
+    short s_cost;		/* cost of casting spell */
+    short s_type;		/* scroll or potion */
+    int   s_flag;		/* is the spell blessed/cursed? */
+};
+
+struct linked_list	*find_mons(), *find_obj(), *get_item(), *new_item(),
+			*new_thing(), *wake_monster(), *get_hurl(), 
+			*spec_item(), *creat_item();
+struct object		*wield_weap();
+struct room		*roomin();
+struct trap		*trap_at();
+
+char	*getenv(), *tr_name(), *new(), 
+	*vowelstr(), *inv_name(), 
+	*ctime(), *num(), *ring_num(), *misc_num(), *blesscurse(), *typ_name(),
+	*weap_name(), *misc_name();
+coord	*rndmove(), *can_shoot(), *fallpos();
+short	randmonster(), id_monst();
+void    quit(int sig), tstp(int sig), auto_save(int sig), bugkill(int sig), endit(int sig);
+int	rnd(), wghtchk(), nohaste(), res_strength(),
+	doctor(), runners(), swander(), unconfuse(), unsee(), fumble(),
+	unclrhead(), unphase(), noslow(), rollwand(), stomach(), sight(),
+	unstink(), suffocate(), cure_disease(), un_itch(), shoot_bolt(),
+	appear(), dust_appear(), unchoke(), alchemy(), trap_look(), strangle(),
+	ring_teleport(), ring_search(), grab();
+bool	blue_light(), can_blink(), creat_mons(), add_pack(),
+	straight_shot(), maze_view(), lit_room(), getdelta(), save_file(),
+	save_game();
+long	check_level();
+void	byebye(int sig), genmonsters();
+int     land(), undance();
+#ifdef CHECKTIME
+int checkout();
+#endif
+extern char *md_getusername();
+extern char *md_gethomedir();
+extern void md_flushinp();
+extern char *md_getshell();
+extern char *md_gethostname();
+extern void md_dobinaryio();
+extern char *md_getpass();
+extern char *md_crypt();
+extern char *md_getroguedir();
+extern void md_init();
+
+/*
+ * Now all the global variables
+ */
+
+extern char outstring[];		/* string for use with msg */
+extern struct trap traps[];
+extern struct h_list helpstr[];
+extern struct h_list wiz_help[];
+extern struct room rooms[];		/* One for each room -- A level */
+extern struct room *oldrp;		/* Roomin(&oldpos) */
+extern struct linked_list *mlist;	/* List of monsters on the level */
+extern struct linked_list *tlist;	/* list of monsters fallen down traps */
+extern struct death_type deaths[];	/* all the ways to die */
+extern struct thing player;		/* The rogue */
+extern struct monster monsters[];	/* The initial monster states */
+extern struct linked_list *lvl_obj;	/* List of objects on this level */
+extern struct linked_list *monst_dead;	/* Indicates monster that got killed */
+extern struct object *cur_weapon;	/* Which weapon he is weilding */
+extern struct object *cur_armor;	/* What a well dresssed rogue wears */
+extern struct object *cur_ring[];	/* Which rings are being worn */
+extern struct object *cur_misc[];	/* which MM's are in use */
+extern struct magic_item things[];	/* Chances for each type of item */
+extern struct magic_item s_magic[];	/* Names and chances for scrolls */
+extern struct magic_item p_magic[];	/* Names and chances for potions */
+extern struct magic_item r_magic[];	/* Names and chances for rings */
+extern struct magic_item ws_magic[];	/* Names and chances for sticks */
+extern struct magic_item m_magic[];	/* Names and chances for MM */
+extern struct magic_item rel_magic[];	/* Names and chances for relics */
+extern struct spells magic_spells[];	/* spells for magic users */
+extern struct spells cleric_spells[];	/* spells for magic users */
+extern char *cnames[][11];		/* Character level names */
+extern char curpurch[];			/* name of item ready to buy */
+extern char PLAYER;			/* what the player looks like */
+extern char nfloors;			/* Number of floors in this dungeon */
+extern int char_type;			/* what type of character is player */
+extern int foodlev;			/* how fast he eats food */
+extern int level;			/* What level rogue is on */
+extern int trader;			/* number of purchases */
+extern int curprice;			/* price of an item */
+extern int purse;			/* How much gold the rogue has */
+extern int mpos;			/* Where cursor is on top line */
+extern int ntraps;			/* Number of traps on this level */
+extern int no_move;			/* Number of turns held in place */
+extern int no_command;			/* Number of turns asleep */
+extern int inpack;			/* Number of things in pack */
+extern int total;			/* Total dynamic memory bytes */
+extern int lastscore;			/* Score before this turn */
+extern int no_food;			/* Number of levels without food */
+extern int foods_this_level;		/* num of foods this level */
+extern int seed;			/* Random number seed */
+extern int count;			/* Number of times to repeat command */
+extern int dnum;			/* Dungeon number */
+extern int max_level;			/* Deepest player has gone */
+extern int cur_max;			/* Deepest player has gone currently */
+extern int food_left;			/* Amount of food in hero's stomach */
+extern int group;			/* Current group number */
+extern int hungry_state;		/* How hungry is he */
+extern int infest_dam;			/* Damage from parasites */
+extern int lost_str;			/* Amount of strength lost */
+extern int lost_dext;			/* amount of dexterity lost */
+extern int hold_count;			/* Number of monsters holding player */
+extern int trap_tries;			/* Number of attempts to set traps */
+extern int pray_time;			/* Number of prayer points/exp level */
+extern int spell_power;			/* Spell power left at this level */
+extern int turns;			/* Number of turns player has taken */
+extern int quest_item;			/* Item hero is looking for */
+extern int cur_relic[];			/* Current relics */
+extern char take;			/* Thing the rogue is taking */
+extern char prbuf[];			/* Buffer for sprintfs */
+extern char outbuf[];			/* Output buffer for stdout */
+extern char runch;			/* Direction player is running */
+extern char *s_names[];			/* Names of the scrolls */
+extern char *p_colors[];		/* Colors of the potions */
+extern char *r_stones[];		/* Stone settings of the rings */
+extern struct init_weps weaps[];	/* weapons and attributes */
+extern struct init_armor armors[];	/* armors and attributes */
+extern char *ws_made[];			/* What sticks are made of */
+extern char *release;			/* Release number of rogue */
+extern char whoami[];			/* Name of player */
+extern char fruit[];			/* Favorite fruit */
+extern char huh[LINELEN];		/* The last message printed */
+extern char *s_guess[];			/* Players guess at what scroll is */
+extern char *p_guess[];			/* Players guess at what potion is */
+extern char *r_guess[];			/* Players guess at what ring is */
+extern char *ws_guess[];		/* Players guess at what wand is */
+extern char *m_guess[];			/* Players guess at what MM is */
+extern char *ws_type[];			/* Is it a wand or a staff */
+extern char file_name[];		/* Save file name */
+extern char score_file[];		/* Score file name */
+extern char home[];			/* User's home directory */
+extern WINDOW *cw;			/* Window that the player sees */
+extern WINDOW *hw;			/* Used for the help command */
+extern WINDOW *mw;			/* Used to store mosnters */
+extern WINDOW *msgw;			/* Used to display messages */
+extern bool pool_teleport;		/* just teleported from a pool */
+extern bool inwhgt;			/* true if from wghtchk() */
+extern bool running;			/* True if player is running */
+extern bool playing;			/* True until he quits */
+extern bool wizard;			/* True if allows wizard commands */
+extern bool after;			/* True if we want after daemons */
+extern bool notify;			/* True if player wants to know */
+extern bool fight_flush;		/* True if toilet input */
+extern bool terse;			/* True if we should be short */
+extern bool auto_pickup;		/* pick up things automatically? */
+extern bool door_stop;			/* Stop running when we pass a door */
+extern bool jump;			/* Show running as series of jumps */
+extern bool slow_invent;		/* Inventory one line at a time */
+extern bool firstmove;			/* First move after setting door_stop */
+extern bool waswizard;			/* Was a wizard sometime */
+extern bool askme;			/* Ask about unidentified things */
+extern bool s_know[];			/* Does he know what a scroll does */
+extern bool p_know[];			/* Does he know what a potion does */
+extern bool r_know[];			/* Does he know what a ring does */
+extern bool ws_know[];			/* Does he know what a stick does */
+extern bool m_know[];			/* Does he know what a MM does */
+extern bool in_shell;			/* True if executing a shell */
+extern bool daytime;			/* Indicates whether it is daytime */
+extern coord oldpos;			/* Position before last look() call */
+extern coord delta;			/* Change indicated to get_dir() */
+extern coord grid[];			/* used for random pos generation */
+extern char *nothing;			/* "nothing happens" msg */
+extern char *spacemsg;
+extern char *morestr;
+extern char *retstr;
+extern LEVTYPE levtype;
+extern int demoncnt;
+extern int fusecnt;
+extern int between;
+extern struct delayed_action d_list[MAXDAEMONS];
+extern struct delayed_action f_list[MAXFUSES];
+extern char *rainbow[NCOLORS];
+extern char *sylls[NSYLLS];
+extern char *stones[NSTONES];
+extern char *metal[NMETAL];
+extern char *wood[NWOOD];
+extern coord ch_ret;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/rooms.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,239 @@
+/*
+ * Draw the nine rooms on the screen
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include "rogue.h"
+
+do_rooms()
+{
+    register int i;
+    register struct room *rp;
+    register struct linked_list *item;
+    register struct thing *tp;
+    register int left_out;
+    coord top;
+    coord bsze;
+    coord mp;
+
+    /*
+     * bsze is the maximum room size
+     */
+    bsze.x = COLS/3;
+    bsze.y = (LINES-2)/3;
+    /*
+     * Clear things for a new level
+     */
+    for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) {
+	rp->r_flags = 0;
+	rp->r_fires = NULL;
+    }
+    /*
+     * Put the gone rooms, if any, on the level
+     */
+    left_out = rnd(4);
+    for (i = 0; i < left_out; i++)
+	rooms[rnd_room()].r_flags |= ISGONE;
+    /*
+     * dig and populate all the rooms on the level
+     */
+    for (i = 0, rp = rooms; i < MAXROOMS; rp++, i++)
+    {
+	bool has_gold=FALSE;
+
+	/*
+	 * Find upper left corner of box that this room goes in
+	 */
+	top.x = (i%3)*bsze.x;
+	top.y = i/3*bsze.y + 1;
+	if (rp->r_flags & ISGONE)
+	{
+	    /*
+	     * Place a gone room.  Make certain that there is a blank line
+	     * for passage drawing.
+	     */
+	    do
+	    {
+		rp->r_pos.x = top.x + rnd(bsze.x-2) + 1;
+		rp->r_pos.y = top.y + rnd(bsze.y-2) + 1;
+		rp->r_max.x = -COLS;
+		rp->r_max.x = -LINES;
+	    } until(rp->r_pos.y > 0 && rp->r_pos.y < LINES-2);
+	    continue;
+	}
+	if (rnd(10) < level-1)
+	    rp->r_flags |= ISDARK;
+	/*
+	 * Find a place and size for a random room
+	 */
+	do
+	{
+	    rp->r_max.x = rnd(bsze.x - 4) + 4;
+	    rp->r_max.y = rnd(bsze.y - 4) + 4;
+	    rp->r_pos.x = top.x + rnd(bsze.x - rp->r_max.x);
+	    rp->r_pos.y = top.y + rnd(bsze.y - rp->r_max.y);
+	} until (rp->r_pos.y != 0);
+
+	/* Draw the room */
+	draw_room(rp);
+
+	/*
+	 * Put the gold in
+	 */
+	if (rnd(100) < 50 && level >= cur_max)
+	{
+	    register struct linked_list *item;
+	    register struct object *cur;
+	    coord tp;
+
+	    has_gold = TRUE;	/* This room has gold in it */
+
+	    item = spec_item(GOLD, NULL, NULL, NULL);
+	    cur = OBJPTR(item);
+
+	    /* Put the gold into the level list of items */
+	    attach(lvl_obj, item);
+
+	    /* Put it somewhere */
+	    rnd_pos(rp, &tp);
+	    mvaddch(tp.y, tp.x, GOLD);
+	    cur->o_pos = tp;
+	    if (roomin(&tp) != rp) {
+		endwin();
+		printf("\n");
+		abort();
+	    }
+	}
+
+	/*
+	 * Put the monster in
+	 */
+	if (rnd(100) < (has_gold ? 80 : 25) + vlevel/2)
+	{
+	    item = new_item(sizeof *tp);
+	    tp = THINGPTR(item);
+	    do
+	    {
+		rnd_pos(rp, &mp);
+	    } until(mvwinch(stdscr, mp.y, mp.x) == FLOOR);
+	    new_monster(item, randmonster(FALSE, FALSE), &mp, FALSE);
+	    /*
+	     * See if we want to give it a treasure to carry around.
+	     */
+	    carry_obj(tp, monsters[tp->t_index].m_carry);
+
+	    /*
+	     * If it has a fire, mark it
+	     */
+	    if (on(*tp, HASFIRE)) {
+		register struct linked_list *fire_item;
+
+		fire_item = creat_item();
+		ldata(fire_item) = (char *) tp;
+		attach(rp->r_fires, fire_item);
+		rp->r_flags |= HASFIRE;
+	    }
+	}
+    }
+}
+
+
+/*
+ * Draw a box around a room
+ */
+
+draw_room(rp)
+register struct room *rp;
+{
+    register int j, k;
+
+    move(rp->r_pos.y, rp->r_pos.x+1);
+    vert(rp->r_max.y-2);				/* Draw left side */
+    move(rp->r_pos.y+rp->r_max.y-1, rp->r_pos.x);
+    horiz(rp->r_max.x);					/* Draw bottom */
+    move(rp->r_pos.y, rp->r_pos.x);
+    horiz(rp->r_max.x);					/* Draw top */
+    vert(rp->r_max.y-2);				/* Draw right side */
+    /*
+     * Put the floor down
+     */
+    for (j = 1; j < rp->r_max.y-1; j++)
+    {
+	move(rp->r_pos.y + j, rp->r_pos.x+1);
+	for (k = 1; k < rp->r_max.x-1; k++)
+	    addch(FLOOR);
+    }
+}
+
+/*
+ * horiz:
+ *	draw a horizontal line
+ */
+
+horiz(cnt)
+register int cnt;
+{
+    while (cnt--)
+	addch('-');
+}
+
+/*
+ * rnd_pos:
+ *	pick a random spot in a room
+ */
+
+rnd_pos(rp, cp)
+register struct room *rp;
+register coord *cp;
+{
+    cp->x = rp->r_pos.x + rnd(rp->r_max.x-2) + 1;
+    cp->y = rp->r_pos.y + rnd(rp->r_max.y-2) + 1;
+}
+
+
+
+/*
+ * roomin:
+ *	Find what room some coordinates are in. NULL means they aren't
+ *	in any room.
+ */
+
+struct room *
+roomin(cp)
+register coord *cp;
+{
+    register struct room *rp;
+
+    for (rp = rooms; rp < &rooms[MAXROOMS]; rp++)
+	if (inroom(rp, cp))
+	    return rp;
+    return NULL;
+}
+
+/*
+ * vert:
+ *	draw a vertical line
+ */
+
+vert(cnt)
+register int cnt;
+{
+    register int x, y;
+
+    getyx(stdscr, y, x);
+    x--;
+    while (cnt--) {
+	move(++y, x);
+	addch('|');
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/save.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,289 @@
+/*
+ * save and restore routines
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include <fcntl.h>
+#include <errno.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <signal.h>
+#include "rogue.h"
+
+typedef struct stat STAT;
+
+extern char version[], encstr[];
+/* extern bool _endwin; */
+
+STAT sbuf;
+
+bool
+save_game()
+{
+    register FILE *savef;
+    register int c;
+    char buf[LINELEN];
+
+    /*
+     * get file name
+     */
+    mpos = 0;
+    if (file_name[0] != '\0')
+    {
+	msg("Save file (%s)? ", file_name);
+	do
+	{
+	    c = readchar();
+	    if (c == ESCAPE) return(0);
+	} while (c != 'n' && c != 'N' && c != 'y' && c != 'Y');
+	mpos = 0;
+	if (c == 'y' || c == 'Y')
+	{
+	    msg("File name: %s", file_name);
+	    goto gotfile;
+	}
+    }
+
+    do
+    {
+	msg("File name: ");
+	mpos = 0;
+	buf[0] = '\0';
+	if (get_str(buf, cw) == QUIT)
+	{
+	    msg("");
+	    return FALSE;
+	}
+        msg("");
+	strcpy(file_name, buf);
+gotfile:
+	if ((savef = fopen(file_name, "w")) == NULL)
+	    msg(strerror(errno));	/* fake perror() */
+    } while (savef == NULL);
+
+    /*
+     * write out encrpyted file (after a stat)
+     * The fwrite is to force allocation of the buffer before the write
+     */
+    if (save_file(savef) != 0) {
+	msg("Cannot create save file.");
+	unlink(file_name);
+	return(FALSE);
+    }
+    else return(TRUE);
+}
+
+/*
+ * automatically save a file.  This is used if a HUP signal is
+ * recieved
+ */
+void
+auto_save(int sig)
+{
+    register FILE *savef;
+    register int i;
+
+    NOOP(sig);
+
+    for (i = 0; i < NSIG; i++)
+	signal(i, SIG_IGN);
+    if (file_name[0] != '\0'	&& 
+	pstats.s_hpt > 0	&&
+	(savef = fopen(file_name, "w")) != NULL)
+	save_file(savef);
+    exit(1);
+}
+
+/*
+ * write the saved game on the file
+ */
+bool
+save_file(savef)
+register FILE *savef;
+{
+    int ret;
+    int slines = LINES;
+    int scols  = COLS;
+
+    wmove(cw, LINES-1, 0);
+    draw(cw);
+    fwrite("junk", 1, 5, savef);
+    fseek(savef, 0L, 0);
+    /* _endwin = TRUE; */
+    fstat(fileno(savef), &sbuf);
+
+    encwrite(version,strlen(version)+1,savef);
+    sprintf(prbuf,"%d x %d\n", LINES, COLS);
+    encwrite(prbuf,80,savef);
+
+    msg("");
+    ret = rs_save_file(savef);
+
+    fclose(savef);
+ 
+    return(ret);
+}
+
+restore(file, envp)
+register char *file;
+char **envp;
+{
+    register int inf;
+#ifndef _AIX
+    extern char **environ;
+#endif
+    char buf[LINELEN];
+    STAT sbuf2;
+    int oldcol, oldline;	/* Old number of columns and lines */
+
+    if (strcmp(file, "-r") == 0)
+	file = file_name;
+
+    if ((inf = open(file, O_RDONLY)) < 0)
+    {
+	perror(file);
+	return FALSE;
+    }
+
+    fflush(stdout);
+
+    encread(buf, strlen(version) + 1, inf);
+
+    if (strcmp(buf, version) != 0)
+    {
+	printf("Sorry, saved game is out of date.\n");
+	return FALSE;
+    }
+
+    /*
+     * Get the lines and columns from the previous game
+     */
+
+    encread(buf, 80, inf);
+    sscanf(buf, "%d x %d\n", &oldline, &oldcol);
+    fstat(inf, &sbuf2);
+    fflush(stdout);
+
+    /*
+     * Set the new terminal and make sure we aren't going to a smaller screen.
+     */
+
+    initscr();
+   
+    if (COLS < oldcol || LINES < oldline) {
+        endwin();
+	printf("\nCannot restart the game on a smaller screen.\n");
+	return FALSE;
+    }
+
+    cw = newwin(LINES, COLS, 0, 0);
+    mw = newwin(LINES, COLS, 0, 0);
+    hw = newwin(LINES, COLS, 0, 0);
+    msgw = newwin(4, COLS, 0, 0);
+    keypad(cw,1);
+    keypad(msgw,1);
+
+    mpos = 0;
+    mvwprintw(cw, 0, 0, "%s: %s", file, ctime(&sbuf2.st_mtime));
+
+    /*
+     * defeat multiple restarting from the same place
+     */
+    if (!wizard) {
+	if (sbuf2.st_nlink != 1) {
+            endwin();
+	    printf("\nCannot restore from a linked file\n");
+	    return FALSE;
+	}
+    }
+
+    if (rs_restore_file(inf) != 0)
+    {
+        endwin();
+        printf("\nCannot restore file\n");
+        return(FALSE);
+    }
+
+    if (!wizard)
+    {
+	if (unlink(file) < 0) {
+            close(inf); /* only close if system insists */
+            if (unlink(file) < 0) {
+                endwin();
+	        printf("\nCannot unlink file\n");
+	        return FALSE;
+            }
+	}
+    }
+
+    environ = envp;
+    strcpy(file_name, file);
+    setup();
+    clearok(curscr, TRUE);
+    touchwin(cw);
+    srand(getpid());
+    playit();
+    /*NOTREACHED*/ 
+    return(FALSE);
+}
+
+/*
+ * perform an encrypted write
+ */
+encwrite(start, size, outf)
+register char *start;
+register unsigned size;
+register FILE *outf;
+{
+    register char *ep;
+    register num_written = 0;
+
+    ep = encstr;
+
+    while (size--)
+    {
+	if (putc(*start++ ^ *ep++, outf) == EOF && ferror(outf))
+	    return(num_written);
+	num_written++;
+	if (*ep == '\0')
+	    ep = encstr;
+    }
+    return(num_written);
+}
+
+/*
+ * perform an encrypted read
+ */
+encread(start, size, inf)
+register char *start;
+register unsigned size;
+register int inf;
+{
+    register char *ep;
+    register int read_size;
+
+    if ((read_size = read(inf, start, size)) == -1 || read_size == 0)
+	return read_size;
+
+    ep = encstr;
+
+    size = read_size;
+    while (size--)
+    {
+	*start++ ^= *ep++;
+	if (*ep == '\0')
+	    ep = encstr;
+    }
+    return read_size;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/scrolls.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,709 @@
+/*
+ * Read a scroll and let it happen
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include <ctype.h>
+#include "rogue.h"
+
+
+
+/*
+ * let the hero get rid of some type of monster (but not a UNIQUE!)
+ */
+genocide()
+{
+    register struct linked_list *ip;
+    register struct thing *mp;
+    register int i;
+    register struct linked_list *nip;
+    register int num_monst = NUMMONST-NUMUNIQUE-1, /* cannot genocide uniques */
+		 pres_monst=1, 
+		 num_lines=2*(LINES-3);
+    register int which_monst;
+    char monst_name[40];
+
+    /* Print out the monsters */
+    while (num_monst > 0) {
+	register left_limit;
+
+	if (num_monst < num_lines) left_limit = (num_monst+1)/2;
+	else left_limit = num_lines/2;
+
+	wclear(hw);
+	touchwin(hw);
+
+	/* Print left column */
+	wmove(hw, 2, 0);
+	for (i=0; i<left_limit; i++) {
+	    sprintf(monst_name, 
+		    "[%d] %c%s\n",
+		    pres_monst, 
+		    monsters[pres_monst].m_normal ? ' ' : '*',
+		    monsters[pres_monst].m_name);
+	    waddstr(hw, monst_name);
+	    pres_monst++;
+	}
+
+	/* Print right column */
+	for (i=0; i<left_limit && pres_monst<=NUMMONST-NUMUNIQUE-1; i++) {
+	    sprintf(monst_name, 
+		    "[%d] %c%s\n",
+		    pres_monst, 
+		    monsters[pres_monst].m_normal ? ' ' : '*',
+		    monsters[pres_monst].m_name);
+	    wmove(hw, i+2, COLS/2);
+	    waddstr(hw, monst_name);
+	    pres_monst++;
+	}
+
+	if ((num_monst -= num_lines) > 0) {
+	    mvwaddstr(hw, LINES-1, 0, morestr);
+	    draw(hw);
+	    wait_for(hw,' ');
+	}
+
+	else {
+	    mvwaddstr(hw, 0, 0, "Which monster");
+	    if (!terse) waddstr(hw, " do you wish to wipe out");
+	    waddstr(hw, "? ");
+	    draw(hw);
+	}
+    }
+
+get_monst:
+    get_str(monst_name, hw);
+    which_monst = atoi(monst_name);
+    if ((which_monst < 1 || which_monst > NUMMONST-NUMUNIQUE-1)) {
+	mvwaddstr(hw, 0, 0, "Please enter a number in the displayed range -- ");
+	draw(hw);
+	goto get_monst;
+    }
+
+    /* Set up for redraw */
+    clearok(cw, TRUE);
+    touchwin(cw);
+
+    /* Remove this monster from the present level */
+    for (ip = mlist; ip; ip = nip) {
+	mp = THINGPTR(ip);
+	nip = next(ip);
+	if (mp->t_index == which_monst) {
+	    killed(ip, FALSE, FALSE);
+	}
+    }
+
+    /* Remove from available monsters */
+    monsters[which_monst].m_normal = FALSE;
+    monsters[which_monst].m_wander = FALSE;
+    mpos = 0;
+    msg("You have wiped out the %s.", monsters[which_monst].m_name);
+}
+
+read_scroll(which, flag, is_scroll)
+register int which;
+int flag;
+bool is_scroll;
+{
+    register struct object *obj = NULL, *nobj;
+    register struct linked_list *item, *nitem;
+    register int i,j;
+    register char ch, nch;
+    bool cursed, blessed;
+    char buf[LINELEN];
+
+    blessed = FALSE;
+    cursed = FALSE;
+    item = NULL;
+
+    if (which < 0) {
+	if (on(player, ISBLIND)) {
+	    msg("You can't see to read anything");
+	    return;
+	}
+	item = get_item(pack, "read", SCROLL);
+	if (item == NULL)
+	    return;
+
+	obj = OBJPTR(item);
+	/* remove it from the pack */
+	inpack--;
+	detach(pack, item);
+
+	msg("As you read the scroll, it vanishes.");
+	cursed = (obj->o_flags & ISCURSED) != 0;
+	blessed = (obj->o_flags & ISBLESSED) != 0;
+
+	which = obj->o_which;
+    }
+    else {
+	cursed = flag & ISCURSED;
+	blessed = flag & ISBLESSED;
+    }
+
+
+    switch (which) {
+	case S_CONFUSE:
+	    /*
+	     * Scroll of monster confusion.  Give him that power.
+	     */
+	    msg("Your hands begin to glow red");
+	    turn_on(player, CANHUH);
+	when S_CURING:
+	    /*
+	     * A cure disease spell
+	     */
+	    if (on(player, HASINFEST) || 
+		on(player, HASDISEASE)|| 
+		on(player, DOROT)) {
+		if (on(player, HASDISEASE)) {
+		    extinguish(cure_disease);
+		    cure_disease();
+		}
+		if (on(player, HASINFEST)) {
+		    msg(terse ? "You feel yourself improving."
+			      : "You begin to feel yourself improving again.");
+		    turn_off(player, HASINFEST);
+		    infest_dam = 0;
+		}
+		if (on(player, DOROT)) {
+		    msg("You feel your skin returning to normal.");
+		    turn_off(player, DOROT);
+		}
+	    }
+	    else {
+		msg(nothing);
+		break;
+	    }
+	    if (is_scroll) s_know[S_CURING] = TRUE;
+	when S_LIGHT:
+	    if (blue_light(blessed, cursed) && is_scroll)
+		s_know[S_LIGHT] = TRUE;
+	when S_HOLD:
+	    if (cursed) {
+		/*
+		 * This scroll aggravates all the monsters on the current
+		 * level and sets them running towards the hero
+		 */
+		aggravate();
+		msg("You hear a high pitched humming noise.");
+	    }
+	    else if (blessed) { /* Hold all monsters on level */
+		if (mlist == NULL) msg(nothing);
+		else {
+		    register struct linked_list *mon;
+		    register struct thing *th;
+
+		    for (mon = mlist; mon != NULL; mon = next(mon)) {
+			th = THINGPTR(mon);
+			turn_off(*th, ISRUN);
+			turn_on(*th, ISHELD);
+		    }
+		    msg("A sudden peace comes over the dungeon.");
+		}
+	    }
+	    else {
+		/*
+		 * Hold monster scroll.  Stop all monsters within two spaces
+		 * from chasing after the hero.
+		 */
+		    register int x,y;
+		    register struct linked_list *mon;
+		    bool gotone=FALSE;
+
+		    for (x = hero.x-2; x <= hero.x+2; x++) {
+			for (y = hero.y-2; y <= hero.y+2; y++) {
+			    if (y < 1 || x < 0 || y > LINES - 3 || x > COLS - 1)
+				continue;
+			    if (isalpha(mvwinch(mw, y, x))) {
+				if ((mon = find_mons(y, x)) != NULL) {
+				    register struct thing *th;
+
+				    gotone = TRUE;
+				    th = THINGPTR(mon);
+				    turn_off(*th, ISRUN);
+				    turn_on(*th, ISHELD);
+				}
+			    }
+			}
+		    }
+		    if (gotone) msg("A sudden peace surrounds you.");
+		    else msg(nothing);
+	    }
+	when S_SLEEP:
+	    /*
+	     * if cursed, you fall asleep
+	     */
+	    if (is_scroll) s_know[S_SLEEP] = TRUE;
+	    if (cursed) {
+		if (ISWEARING(R_ALERT))
+		    msg("You feel drowsy for a moment.");
+		else {
+		    msg("You fall asleep.");
+		    no_command += 4 + rnd(SLEEPTIME);
+		}
+	    }
+	    else {
+		/*
+		 * sleep monster scroll.  
+		 * puts all monsters within 2 spaces asleep
+		 */
+		    register int x,y;
+		    register struct linked_list *mon;
+		    bool gotone=FALSE;
+
+		    for (x = hero.x-2; x <= hero.x+2; x++) {
+			for (y = hero.y-2; y <= hero.y+2; y++) {
+			    if (y < 1 || x < 0 || y > LINES - 3 || x > COLS - 1)
+				continue;
+			    if (isalpha(mvwinch(mw, y, x))) {
+				if ((mon = find_mons(y, x)) != NULL) {
+				    register struct thing *th;
+
+				    th = THINGPTR(mon);
+				    if (on(*th, ISUNDEAD))
+					continue;
+				    th->t_no_move += SLEEPTIME;
+				    gotone = TRUE;
+				}
+			    }
+			}
+		    }
+		    if (gotone) 
+			msg("The monster(s) around you seem to have fallen asleep");
+		    else 
+			msg(nothing);
+	    }
+	when S_CREATE:
+	    /*
+	     * Create a monster
+	     * First look in a circle around him, next try his room
+	     * otherwise give up
+	     */
+	    creat_mons(&player, (short) 0, TRUE);
+	    light(&hero);
+	when S_IDENT:
+	    /* 
+	     * if its blessed then identify everything in the pack
+	     */
+	    if (blessed) {
+		msg("You feel more Knowledgeable!");
+		idenpack();
+	    }
+	    else {
+		/*
+		 * Identify, let the rogue figure something out
+		 */
+		if (is_scroll && s_know[S_IDENT] != TRUE) {
+		    msg("This scroll is an identify scroll");
+		}
+		whatis(NULL);
+	    }
+	    if (is_scroll) s_know[S_IDENT] = TRUE;
+	when S_MAP:
+	    /*
+	     * Scroll of magic mapping.
+	     */
+	    if (is_scroll && s_know[S_MAP] != TRUE) {
+		msg("Oh, now this scroll has a map on it.");
+		s_know[S_MAP] = TRUE;
+	    }
+	    overwrite(stdscr, hw);
+	    /*
+	     * Take all the things we want to keep hidden out of the window
+	     */
+	    for (i = 1; i < LINES-2; i++)
+		for (j = 0; j < COLS; j++)
+		{
+		    switch (nch = ch = CCHAR( mvwinch(hw, i, j) ))
+		    {
+			case SECRETDOOR:
+			    nch = secretdoor (i, j);
+			    break;
+			case '-':
+			case '|':
+			case DOOR:
+			case PASSAGE:
+			case ' ':
+			case STAIRS:
+			    if (mvwinch(mw, i, j) != ' ')
+			    {
+				register struct thing *it;
+
+				it = THINGPTR(find_mons(i, j));
+				if (it && it->t_oldch == ' ')
+				    it->t_oldch = nch;
+			    }
+			    break;
+			default:
+			    nch = ' ';
+		    }
+		    if (nch != ch)
+			waddch(hw, nch);
+		}
+	    /*
+	     * Copy in what he has discovered
+	     */
+	    overlay(cw, hw);
+	    /*
+	     * And set up for display
+	     */
+	    overwrite(hw, cw);
+	when S_GFIND:
+	    /*
+	     * Scroll of gold detection
+	     */
+	    if (lvl_obj != NULL) {
+		register struct linked_list *gitem;
+		struct object *cur;
+		int gtotal = 0;
+
+		wclear(hw);
+		for (gitem = lvl_obj; gitem != NULL; gitem = next(gitem)) {
+		    cur = OBJPTR(gitem);
+		    if (cur->o_type == GOLD) {
+			gtotal += cur->o_count;
+			mvwaddch(hw, cur->o_pos.y, cur->o_pos.x, GOLD);
+		    }
+		}
+		if (gtotal) {
+		    if (is_scroll) s_know[S_GFIND] = TRUE;
+		    msg("You begin to feel greedy and you sense gold.");
+		    overlay(hw,cw);
+		    break;
+		}
+	    }
+	    msg("You begin to feel a pull downward");
+	when S_TELEP:
+	    /*
+	     * Scroll of teleportation:
+	     * Make him disappear and reappear
+	     */
+	    if (cursed) {
+		int old_max = cur_max;
+
+		turns = (vlevel * 3) * LEVEL;
+		level = nfloors;
+		new_level(NORMLEV);
+		status(TRUE);
+		mpos = 0;
+		msg("You are banished to the lower regions.");
+		if (old_max == cur_max) /* if he's been here, make it harder */
+		    aggravate();
+	    }
+	    else if (blessed) {
+		int	old_level, 
+			much = rnd(4) - 4;
+
+		old_level = level;
+		if (much != 0) {
+		    level += much;
+		    if (level < 1)
+			level = 1;
+		    mpos = 0;
+		    cur_max = level;
+		    turns += much*LEVEL;
+		    if (turns < 0)
+			turns = 0;
+		    new_level(NORMLEV);		/* change levels */
+		    if (level == old_level)
+			status(TRUE);
+		    msg("You are whisked away to another region.");
+		}
+	    }
+	    else {
+		teleport();
+	    }
+	    if (is_scroll) s_know[S_TELEP] = TRUE;
+	when S_SCARE:
+	    /*
+	     * A monster will refuse to step on a scare monster scroll
+	     * if it is dropped.  Thus reading it is a mistake and produces
+	     * laughter at the poor rogue's boo boo.
+	     */
+	    msg("You hear maniacal laughter in the distance.");
+	when S_REMOVE:
+	    if (cursed) { /* curse all player's possessions */
+		for (nitem = pack; nitem != NULL; nitem = next(nitem)) {
+		    nobj = OBJPTR(nitem);
+		    if (nobj->o_flags & ISBLESSED) 
+			nobj->o_flags &= ~ISBLESSED;
+		    else 
+			nobj->o_flags |= ISCURSED;
+		}
+		msg("The smell of fire and brimstone fills the air.");
+	    }
+	    else if (blessed) {
+		for (nitem = pack; nitem != NULL; nitem = next(nitem)) {
+		    nobj = OBJPTR(nitem);
+		    nobj->o_flags &= ~ISCURSED;
+		}
+		msg("Your pack glistens brightly");
+	    }
+	    else {
+		if ((nitem = get_item(pack, "remove the curse on",ALL))!=NULL){
+		    nobj = OBJPTR(nitem);
+		    nobj->o_flags &= ~ISCURSED;
+		    msg("Removed the curse from %s",inv_name(nobj,TRUE));
+		}
+	    }
+	    if (is_scroll) s_know[S_REMOVE] = TRUE;
+	when S_PETRIFY:
+	    switch (mvinch(hero.y, hero.x)) {
+		case TRAPDOOR:
+		case DARTTRAP:
+		case TELTRAP:
+		case ARROWTRAP:
+		case SLEEPTRAP:
+		case BEARTRAP:
+		    {
+			register int i;
+
+			/* Find the right trap */
+			for (i=0; i<ntraps && !ce(traps[i].tr_pos, hero); i++);
+			ntraps--;
+
+			if (!ce(traps[i].tr_pos, hero))
+			    msg("What a strange trap!");
+			else {
+			    while (i < ntraps) {
+				traps[i] = traps[i + 1];
+				i++;
+			    }
+			}
+		    }
+		    goto pet_message;
+		case DOOR:
+		case SECRETDOOR:
+		case FLOOR:
+		case PASSAGE:
+pet_message:	    msg("The dungeon begins to rumble and shake!");
+		    addch(WALL);
+
+		    /* If the player is phased, unphase him */
+		    if (on(player, CANINWALL)) {
+			extinguish(unphase);
+			turn_off(player, CANINWALL);
+			msg("Your dizzy feeling leaves you.");
+		    }
+
+		    /* Mark the player as in a wall */
+		    turn_on(player, ISINWALL);
+		    break;
+		default:
+		    msg(nothing);
+	    }
+	when S_GENOCIDE:
+	    msg("You have been granted the boon of genocide!--More--");
+	    wait_for(cw,' ');
+	    msg("");
+	    genocide();
+	    if (is_scroll) s_know[S_GENOCIDE] = TRUE;
+	when S_PROTECT: {
+	    struct linked_list *ll;
+	    struct object *lb;
+	    bool did_it = FALSE;
+	    msg("You are granted the power of protection.");
+	    if ((ll = get_item(pack, "protect", PROTECTABLE)) != NULL) {
+		lb = OBJPTR(ll);
+		mpos = 0;
+		if (cursed) {
+		    switch(lb->o_type) {	/* ruin it completely */
+			case RING: if (lb->o_ac > 0) {
+				    if (is_current(lb)) {
+					switch (lb->o_which) {
+					    case R_ADDWISDOM: 
+						pstats.s_wisdom -= lb->o_ac;
+					    when R_ADDINTEL:  
+						pstats.s_intel -= lb->o_ac;
+					    when R_ADDSTR:
+						pstats.s_str -= lb->o_ac;
+					    when R_ADDHIT:
+						pstats.s_dext -= lb->o_ac;
+					}
+				    }
+				    did_it = TRUE;
+					lb->o_ac = 0;
+				}
+			when ARMOR: if (lb->o_ac > 10) {
+					did_it = TRUE;
+					lb->o_ac = 10;
+				    }
+			when STICK: if (lb->o_charges > 0) {
+					did_it = TRUE;
+					lb->o_charges = 0;
+				    }
+			when WEAPON:if (lb->o_hplus > 0) {
+					did_it = TRUE;
+					lb->o_hplus = 0;
+				    }
+				    if (lb->o_dplus > 0) {
+					did_it = TRUE;
+					lb->o_dplus = 0;
+				    }
+		    }
+		    if (lb->o_flags & ISPROT) {
+			did_it = TRUE;
+			lb->o_flags &= ~ISPROT;
+		    }
+		    if (lb->o_flags & ISBLESSED) {
+			did_it = TRUE;
+			lb->o_flags &= ~ISBLESSED;
+		    }
+		    if (did_it)
+			msg("Your %s glows red for a moment",inv_name(lb,TRUE));
+		    else {
+			msg(nothing);
+			break;
+		    }
+		}
+		else  {
+		    lb->o_flags |= ISPROT;
+		    msg("Protected %s.",inv_name(lb,TRUE));
+		}
+	    }
+	    if (is_scroll) s_know[S_PROTECT] = TRUE;
+	}
+	when S_MAKEIT:
+	    msg("You have been endowed with the power of creation.");
+	    if (is_scroll) s_know[S_MAKEIT] = TRUE;
+	    create_obj(TRUE, 0, 0);
+	when S_ALLENCH: {
+	    struct linked_list *ll;
+	    struct object *lb;
+	    int howmuch, flags;
+	    if (is_scroll && s_know[S_ALLENCH] == FALSE) {
+		msg("You are granted the power of enchantment.");
+		msg("You may enchant anything(weapon,ring,armor,scroll,potion)");
+	    }
+	    if ((ll = get_item(pack, "enchant",ALL)) != NULL) {
+		lb = OBJPTR(ll);
+		lb->o_flags &= ~ISCURSED;
+		if (blessed) {
+		    howmuch = 2;
+		    flags = ISBLESSED;
+		}
+		else if (cursed) {
+		    howmuch = -1;
+		    flags = ISCURSED;
+		}
+		else {
+		    howmuch = 1;
+		    flags = ISBLESSED;
+		}
+		switch(lb->o_type) {
+		    case RING:
+			if (lb->o_ac + howmuch > MAXENCHANT) {
+			    msg("The enchantment doesn't seem to work!");
+			    break;
+			}
+			lb->o_ac += howmuch;
+			if (lb==cur_ring[LEFT_1]  || lb==cur_ring[LEFT_2]  ||
+			    lb==cur_ring[LEFT_3]  || lb==cur_ring[LEFT_4]  ||
+			    lb==cur_ring[RIGHT_1] || lb==cur_ring[RIGHT_2] ||
+			    lb==cur_ring[RIGHT_3] || lb==cur_ring[RIGHT_4]) {
+			    switch (lb->o_which) {
+				case R_ADDWISDOM: pstats.s_wisdom += howmuch;
+				when R_ADDINTEL:  pstats.s_intel += howmuch;
+				when R_ADDSTR:    pstats.s_str += howmuch;
+				when R_ADDHIT:    pstats.s_dext += howmuch;
+			    }
+			}
+			msg("Enchanted %s.",inv_name(lb,TRUE));
+		    when ARMOR:
+			if ((armors[lb->o_which].a_class - lb->o_ac) +
+			    howmuch > MAXENCHANT) {
+			    msg("The enchantment doesn't seem to work!");
+			    break;
+			}
+			else
+			    lb->o_ac -= howmuch;
+			msg("Enchanted %s.",inv_name(lb,TRUE));
+		    when STICK:
+			lb->o_charges += (howmuch * 10) + rnd(5);
+			if (lb->o_charges < 0)
+			    lb->o_charges = 0;
+			if (EQUAL(ws_type[lb->o_which], "staff")) {
+			    if (lb->o_charges > 100) 
+				lb->o_charges = 100;
+			}
+			else {
+			    if (lb->o_charges > 50)
+				lb->o_charges = 50;
+			}
+			msg("Enchanted %s.",inv_name(lb,TRUE));
+		    when WEAPON:
+			if(lb->o_hplus+lb->o_dplus+howmuch > MAXENCHANT * 2){
+			    msg("The enchantment doesn't seem to work!");
+			    break;
+			}
+			if (rnd(100) < 50)
+			    lb->o_hplus += howmuch;
+			else
+			    lb->o_dplus += howmuch;
+			msg("Enchanted %s.",inv_name(lb,TRUE));
+		    when MM:
+			switch (lb->o_which) {
+			    case MM_BRACERS:
+			    case MM_PROTECT:
+				if (lb->o_ac + howmuch > MAXENCHANT) {
+				   msg("The enchantment doesn't seem to work!");
+				   break;
+				}
+				else lb->o_ac += howmuch;
+				msg("Enchanted %s.",inv_name(lb,TRUE));
+			}
+			lb->o_flags |= flags;
+		    when POTION:
+		    case SCROLL:
+		    default:
+			lb->o_flags |= flags;
+		    msg("Enchanted %s.",inv_name(lb,TRUE));
+		}
+	    }
+	    if (is_scroll) s_know[S_ALLENCH] = TRUE;
+	    if (!is_scroll) {
+		pstats.s_const--;
+		max_stats.s_const--;
+		if (pstats.s_const <= 0)
+		    death(D_CONSTITUTION);
+		msg("You feel less healthy now");
+	    }
+	}
+	otherwise:
+	    msg("What a puzzling scroll!");
+	    return;
+    }
+    look(TRUE, FALSE);	/* put the result of the scroll on the screen */
+    status(FALSE);
+    if (is_scroll && s_know[which] && s_guess[which])
+    {
+	free(s_guess[which]);
+	s_guess[which] = NULL;
+    }
+    else if (is_scroll && 
+	     !s_know[which] && 
+	     askme &&
+	     (obj->o_flags & ISKNOW) == 0 &&
+	     (obj->o_flags & ISPOST) == 0 &&
+	     s_guess[which] == NULL) {
+	msg(terse ? "Call it: " : "What do you want to call it? ");
+	if (get_str(buf, cw) == NORM)
+	{
+	    s_guess[which] = new(strlen(buf) + 1);
+	    strcpy(s_guess[which], buf);
+	}
+    }
+    if (item != NULL) o_discard(item);
+    updpack(TRUE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/state.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,2477 @@
+/*
+    state.c - Portable Rogue Save State Code
+
+    Copyright (C) 1999, 2000, 2005 Nicholas J. Kisseberth
+    All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer.
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    3. Neither the name(s) of the author(s) nor the names of other contributors
+       may be used to endorse or promote products derived from this software
+       without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
+    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+    OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+*/
+
+/************************************************************************/
+/* Save State Code                                                      */
+/************************************************************************/
+
+#define RSID_STATS        0xABCD0001
+#define RSID_MSTATS       0xABCD0002
+#define RSID_THING        0xABCD0003
+#define RSID_OBJECT       0xABCD0004
+#define RSID_MAGICITEMS   0xABCD0005
+#define RSID_KNOWS        0xABCD0006
+#define RSID_GUESSES      0xABCD0007
+#define RSID_OBJECTLIST   0xABCD0008
+#define RSID_BAGOBJECT    0xABCD0009
+#define RSID_MONSTERLIST  0xABCD000A
+#define RSID_MONSTERSTATS 0xABCD000B
+#define RSID_MONSTERS     0xABCD000C
+#define RSID_TRAP         0xABCD000D
+#define RSID_WINDOW       0xABCD000E
+#define RSID_DAEMONS      0xABCD000F
+#define RSID_STICKS       0xABCD0010
+#define RSID_IARMOR       0xABCD0011
+#define RSID_SPELLS       0xABCD0012
+#define RSID_ILIST        0xABCD0013
+#define RSID_HLIST        0xABCD0014
+#define RSID_DEATHTYPE    0xABCD0015
+#define RSID_CTYPES       0XABCD0016
+#define RSID_COORDLIST    0XABCD0017
+#define RSID_ROOMS        0XABCD0018
+
+#include <curses.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "rogue.h"
+
+#define READSTAT (format_error || read_error )
+#define WRITESTAT (write_error)
+
+static int read_error   = FALSE;
+static int write_error  = FALSE;
+static int format_error = FALSE;
+static int endian = 0x01020304;
+#define  big_endian ( *((char *)&endian) == 0x01 )
+
+int
+rs_write(FILE *savef, void *ptr, size_t size)
+{
+    if (write_error)
+        return(WRITESTAT);
+
+    if (encwrite(ptr, size, savef) != size)
+        write_error = 1;
+
+    return(WRITESTAT);
+}
+
+int
+rs_read(int inf, void *ptr, size_t size)
+{
+    if (read_error || format_error)
+        return(READSTAT);
+
+    if (encread(ptr, size, inf) != size)
+        read_error = 1;
+       
+    return(READSTAT);
+}
+
+int
+rs_write_uchar(FILE *savef, unsigned char c)
+{
+    if (write_error)
+        return(WRITESTAT);
+
+    rs_write(savef, &c, 1);
+
+    return(WRITESTAT);
+}
+
+int
+rs_read_uchar(int inf, unsigned char *c)
+{
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read(inf, c, 1);
+
+    return(READSTAT);
+}
+
+int
+rs_write_char(FILE *savef, char c)
+{
+    if (write_error)
+        return(WRITESTAT);
+
+    rs_write(savef, &c, 1);
+
+    return(WRITESTAT);
+}
+
+int
+rs_read_char(int inf, char *c)
+{
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read(inf, c, 1);
+
+    return(READSTAT);
+}
+
+int
+rs_write_chars(FILE *savef, char *c, int count)
+{
+    if (write_error)
+        return(WRITESTAT);
+
+    rs_write_int(savef, count);
+    rs_write(savef, c, count);
+
+    return(WRITESTAT);
+}
+
+int
+rs_read_chars(int inf, char *i, int count)
+{
+    int value = 0;
+    
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read_int(inf, &value);
+    
+    if (value != count)
+        format_error = TRUE;
+
+    rs_read(inf, i, count);
+    
+    return(READSTAT);
+}
+
+int
+rs_write_int(FILE *savef, int c)
+{
+    unsigned char bytes[4];
+    unsigned char *buf = (unsigned char *) &c;
+
+    if (write_error)
+        return(WRITESTAT);
+
+    if (big_endian)
+    {
+        bytes[3] = buf[0];
+        bytes[2] = buf[1];
+        bytes[1] = buf[2];
+        bytes[0] = buf[3];
+        buf = bytes;
+    }
+    
+    rs_write(savef, buf, 4);
+
+    return(WRITESTAT);
+}
+
+int
+rs_read_int(int inf, int *i)
+{
+    unsigned char bytes[4];
+    int input = 0;
+    unsigned char *buf = (unsigned char *)&input;
+    
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read(inf, &input, 4);
+
+    if (big_endian)
+    {
+        bytes[3] = buf[0];
+        bytes[2] = buf[1];
+        bytes[1] = buf[2];
+        bytes[0] = buf[3];
+        buf = bytes;
+    }
+    
+    *i = *((int *) buf);
+
+    return(READSTAT);
+}
+
+int
+rs_write_ints(FILE *savef, int *c, int count)
+{
+    int n = 0;
+
+    if (write_error)
+        return(WRITESTAT);
+
+    rs_write_int(savef, count);
+
+    for(n = 0; n < count; n++)
+        if( rs_write_int(savef,c[n]) != 0)
+            break;
+
+    return(WRITESTAT);
+}
+
+int
+rs_read_ints(int inf, int *i, int count)
+{
+    int n, value;
+    
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read_int(inf,&value);
+
+    if (value != count)
+        format_error = TRUE;
+
+    for(n = 0; n < count; n++)
+        if (rs_read_int(inf, &i[n]) != 0)
+            break;
+    
+    return(READSTAT);
+}
+
+int
+rs_write_boolean(FILE *savef, bool c)
+{
+    unsigned char buf = (c == 0) ? 0 : 1;
+    
+    if (write_error)
+        return(WRITESTAT);
+
+    rs_write(savef, &buf, 1);
+
+    return(WRITESTAT);
+}
+
+int
+rs_read_boolean(int inf, bool *i)
+{
+    unsigned char buf = 0;
+    
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read(inf, &buf, 1);
+
+    *i = (buf != 0);
+    
+    return(READSTAT);
+}
+
+int
+rs_write_booleans(FILE *savef, bool *c, int count)
+{
+    int n = 0;
+
+    if (write_error)
+        return(WRITESTAT);
+
+    rs_write_int(savef, count);
+
+    for(n = 0; n < count; n++)
+        if (rs_write_boolean(savef, c[n]) != 0)
+            break;
+
+    return(WRITESTAT);
+}
+
+int
+rs_read_booleans(int inf, bool *i, int count)
+{
+    int n = 0, value = 0;
+    
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read_int(inf,&value);
+
+    if (value != count)
+        format_error = TRUE;
+
+    for(n = 0; n < count; n++)
+        if (rs_read_boolean(inf, &i[n]) != 0)
+            break;
+    
+    return(READSTAT);
+}
+
+int
+rs_write_short(FILE *savef, short c)
+{
+    unsigned char bytes[2];
+    unsigned char *buf = (unsigned char *) &c;
+
+    if (write_error)
+        return(WRITESTAT);
+
+    if (big_endian)
+    {
+        bytes[1] = buf[0];
+        bytes[0] = buf[1];
+        buf = bytes;
+    }
+
+    rs_write(savef, buf, 2);
+
+    return(WRITESTAT);
+}
+
+int
+rs_read_short(int inf, short *i)
+{
+    unsigned char bytes[2];
+    short  input;
+    unsigned char *buf = (unsigned char *)&input;
+    
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read(inf, &input, 2);
+
+    if (big_endian)
+    {
+        bytes[1] = buf[0];
+        bytes[0] = buf[1];
+        buf = bytes;
+    }
+    
+    *i = *((short *) buf);
+
+    return(READSTAT);
+} 
+
+int
+rs_write_shorts(FILE *savef, short *c, int count)
+{
+    int n = 0;
+
+    if (write_error)
+        return(WRITESTAT);
+
+    rs_write_int(savef, count);
+
+    for(n = 0; n < count; n++)
+        if (rs_write_short(savef, c[n]) != 0)
+            break; 
+
+    return(WRITESTAT);
+}
+
+int
+rs_read_shorts(int inf, short *i, int count)
+{
+    int n = 0, value = 0;
+
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read_int(inf,&value);
+
+    if (value != count)
+        format_error = TRUE;
+
+    for(n = 0; n < value; n++)
+        if (rs_read_short(inf, &i[n]) != 0)
+            break;
+    
+    return(READSTAT);
+}
+
+int
+rs_write_ushort(FILE *savef, unsigned short c)
+{
+    unsigned char bytes[2];
+    unsigned char *buf = (unsigned char *) &c;
+
+    if (write_error)
+        return(WRITESTAT);
+
+    if (big_endian)
+    {
+        bytes[1] = buf[0];
+        bytes[0] = buf[1];
+        buf = bytes;
+    }
+
+    rs_write(savef, buf, 2);
+
+    return(WRITESTAT);
+}
+
+int
+rs_read_ushort(int inf, unsigned short *i)
+{
+    unsigned char bytes[2];
+    unsigned short  input;
+    unsigned char *buf = (unsigned char *)&input;
+    
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read(inf, &input, 2);
+
+    if (big_endian)
+    {
+        bytes[1] = buf[0];
+        bytes[0] = buf[1];
+        buf = bytes;
+    }
+    
+    *i = *((unsigned short *) buf);
+
+    return(READSTAT);
+} 
+
+int
+rs_write_uint(FILE *savef, unsigned int c)
+{
+    unsigned char bytes[4];
+    unsigned char *buf = (unsigned char *) &c;
+
+    if (write_error)
+        return(WRITESTAT);
+
+    if (big_endian)
+    {
+        bytes[3] = buf[0];
+        bytes[2] = buf[1];
+        bytes[1] = buf[2];
+        bytes[0] = buf[3];
+        buf = bytes;
+    }
+    
+    rs_write(savef, buf, 4);
+
+    return(WRITESTAT);
+}
+
+int
+rs_read_uint(int inf, unsigned int *i)
+{
+    unsigned char bytes[4];
+    int  input;
+    unsigned char *buf = (unsigned char *)&input;
+    
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read(inf, &input, 4);
+
+    if (big_endian)
+    {
+        bytes[3] = buf[0];
+        bytes[2] = buf[1];
+        bytes[1] = buf[2];
+        bytes[0] = buf[3];
+        buf = bytes;
+    }
+    
+    *i = *((unsigned int *) buf);
+
+    return(READSTAT);
+}
+
+int
+rs_write_long(FILE *savef, long c)
+{
+    int c2;
+    unsigned char bytes[4];
+    unsigned char *buf = (unsigned char *)&c;
+
+    if (write_error)
+        return(WRITESTAT);
+
+    if (sizeof(long) == 8)
+    {
+        c2 = c;
+        buf = (unsigned char *) &c2;
+    }
+
+    if (big_endian)
+    {
+        bytes[3] = buf[0];
+        bytes[2] = buf[1];
+        bytes[1] = buf[2];
+        bytes[0] = buf[3];
+        buf = bytes;
+    }
+    
+    rs_write(savef, buf, 4);
+
+    return(WRITESTAT);
+}
+
+int
+rs_read_long(int inf, long *i)
+{
+    unsigned char bytes[4];
+    long input;
+    unsigned char *buf = (unsigned char *) &input;
+    
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read(inf, &input, 4);
+
+    if (big_endian)
+    {
+        bytes[3] = buf[0];
+        bytes[2] = buf[1];
+        bytes[1] = buf[2];
+        bytes[0] = buf[3];
+        buf = bytes;
+    }
+    
+    *i = *((long *) buf);
+
+    return(READSTAT);
+}
+
+int
+rs_write_longs(FILE *savef, long *c, int count)
+{
+    int n = 0;
+
+    if (write_error)
+        return(WRITESTAT);
+
+    rs_write_int(savef,count);
+    
+    for(n = 0; n < count; n++)
+        rs_write_long(savef, c[n]);
+
+    return(WRITESTAT);
+}
+
+int
+rs_read_longs(int inf, long *i, int count)
+{
+    int n = 0, value = 0;
+    
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read_int(inf,&value);
+
+    if (value != count)
+        format_error = TRUE;
+
+    for(n = 0; n < value; n++)
+        if (rs_read_long(inf, &i[n]) != 0)
+            break;
+    
+    return(READSTAT);
+}
+
+int
+rs_write_ulong(FILE *savef, unsigned long c)
+{
+    unsigned int c2;
+    unsigned char bytes[4];
+    unsigned char *buf = (unsigned char *)&c;
+
+    if (write_error)
+        return(WRITESTAT);
+
+    if ( (sizeof(long) == 8) && (sizeof(int) == 4) )
+    {
+        c2 = c;
+        buf = (unsigned char *) &c2;
+    }
+
+    if (big_endian)
+    {
+        bytes[3] = buf[0];
+        bytes[2] = buf[1];
+        bytes[1] = buf[2];
+        bytes[0] = buf[3];
+        buf = bytes;
+    }
+    
+    rs_write(savef, buf, 4);
+
+    return(WRITESTAT);
+}
+
+int
+rs_read_ulong(int inf, unsigned long *i)
+{
+    unsigned char bytes[4];
+    unsigned long input;
+    unsigned char *buf = (unsigned char *) &input;
+    
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read(inf, &input, 4);
+
+    if (big_endian)
+    {
+        bytes[3] = buf[0];
+        bytes[2] = buf[1];
+        bytes[1] = buf[2];
+        bytes[0] = buf[3];
+        buf = bytes;
+    }
+    
+    *i = *((unsigned long *) buf);
+
+    return(READSTAT);
+}
+
+int
+rs_write_ulongs(FILE *savef, unsigned long *c, int count)
+{
+    int n = 0;
+
+    if (write_error)
+        return(WRITESTAT);
+
+    rs_write_int(savef,count);
+
+    for(n = 0; n < count; n++)
+        if (rs_write_ulong(savef,c[n]) != 0)
+            break;
+
+    return(WRITESTAT);
+}
+
+int
+rs_read_ulongs(int inf, unsigned long *i, int count)
+{
+    int n = 0, value = 0;
+    
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read_int(inf,&value);
+
+    if (value != count)
+        format_error = TRUE;
+
+    for(n = 0; n < count; n++)
+        if (rs_read_ulong(inf, &i[n]) != 0)
+            break;
+    
+    return(READSTAT);
+}
+
+int
+rs_write_marker(FILE *savef, int id)
+{
+    if (write_error)
+        return(WRITESTAT);
+
+    rs_write_int(savef, id);
+
+    return(WRITESTAT);
+}
+
+int 
+rs_read_marker(int inf, int id)
+{
+    int nid;
+
+    if (read_error || format_error)
+        return(READSTAT);
+
+    if (rs_read_int(inf, &nid) == 0)
+        if (id != nid)
+            format_error = 1;
+    
+    return(READSTAT);
+}
+
+
+
+/******************************************************************************/
+
+int
+rs_write_string(FILE *savef, char *s)
+{
+    int len = 0;
+
+    if (write_error)
+        return(WRITESTAT);
+
+    len = (s == NULL) ? 0 : (int) strlen(s) + 1;
+
+    rs_write_int(savef, len);
+    rs_write_chars(savef, s, len);
+            
+    return(WRITESTAT);
+}
+
+int
+rs_read_string(int inf, char *s, int max)
+{
+    int len = 0;
+
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read_int(inf, &len);
+
+    if (len > max)
+        format_error = TRUE;
+
+    rs_read_chars(inf, s, len);
+    
+    return(READSTAT);
+}
+
+int
+rs_read_new_string(int inf, char **s)
+{
+    int len=0;
+    char *buf=0;
+
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read_int(inf, &len);
+
+    if (len == 0)
+        buf = NULL;
+    else
+    { 
+        buf = malloc(len);
+
+        if (buf == NULL)            
+            read_error = TRUE;
+    }
+
+    rs_read_chars(inf, buf, len);
+
+    *s = buf;
+
+    return(READSTAT);
+}
+
+int
+rs_write_strings(FILE *savef, char *s[], int count)
+{
+    int n = 0;
+
+    if (write_error)
+        return(WRITESTAT);
+
+    rs_write_int(savef, count);
+
+    for(n = 0; n < count; n++)
+        if (rs_write_string(savef, s[n]) != 0)
+            break;
+    
+    return(WRITESTAT);
+}
+
+int
+rs_read_strings(int inf, char **s, int count, int max)
+{
+    int n     = 0;
+    int value = 0;
+    
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read_int(inf, &value);
+
+    if (value != count)
+        format_error = TRUE;
+
+    for(n = 0; n < count; n++)
+        if (rs_read_string(inf, s[n], max) != 0)
+            break;
+    
+    return(READSTAT);
+}
+
+int
+rs_read_new_strings(int inf, char **s, int count)
+{
+    int n     = 0;
+    int value = 0;
+    
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read_int(inf, &value);
+
+    if (value != count)
+        format_error = TRUE;
+
+    for(n = 0; n < count; n++)
+        if (rs_read_new_string(inf, &s[n]) != 0)
+            break;
+    
+    return(READSTAT);
+}
+
+int
+rs_write_string_index(FILE *savef, char *master[], int max, const char *str)
+{
+    int i;
+
+    if (write_error)
+        return(WRITESTAT);
+
+    for(i = 0; i < max; i++)
+        if (str == master[i])
+            return( rs_write_int(savef, i) );
+
+    return( rs_write_int(savef,-1) );
+}
+
+int
+rs_read_string_index(int inf, char *master[], int maxindex, char **str)
+{
+    int i;
+
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read_int(inf, &i);
+
+    if (i > maxindex)
+        format_error = TRUE;
+    else if (i >= 0)
+        *str = master[i];
+    else
+        *str = NULL;
+
+    return(READSTAT);
+}
+
+int
+rs_write_coord(FILE *savef, coord c)
+{
+    if (write_error)
+        return(WRITESTAT);
+
+    rs_write_int(savef, c.x);
+    rs_write_int(savef, c.y);
+    
+    return(WRITESTAT);
+}
+
+int
+rs_read_coord(int inf, coord *c)
+{
+    coord in;
+
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read_int(inf,&in.x);
+    rs_read_int(inf,&in.y);
+
+    if (READSTAT == 0) 
+    {
+        c->x = in.x;
+        c->y = in.y;
+    }
+
+    return(READSTAT);
+}
+
+int
+rs_write_coord_list(FILE *savef, struct linked_list *l)
+{
+    rs_write_marker(savef, RSID_COORDLIST);
+    rs_write_int(savef, list_size(l));
+
+    while (l != NULL) 
+    {
+        rs_write_coord(savef, *(coord *) l->l_data);
+        l = l->l_next;
+    }
+    
+    return(WRITESTAT);
+}
+
+int
+rs_read_coord_list(int inf, struct linked_list **list)
+{
+    int i, cnt;
+    struct linked_list *l = NULL, *previous = NULL, *head = NULL;
+
+    rs_read_marker(inf, RSID_COORDLIST);
+
+    if (rs_read_int(inf,&cnt) != 0)
+	return(READSTAT);
+
+    for (i = 0; i < cnt; i++)
+    {
+	l = new_item(sizeof(coord));
+        l->l_prev = previous;
+
+        if (previous != NULL)
+	    previous->l_next = l;
+
+        rs_read_coord(inf,(coord *) l->l_data);
+
+	if (previous == NULL)
+	    head = l;
+                
+	previous = l;
+    }
+            
+    if (l != NULL)
+	l->l_next = NULL;
+    
+    *list = head;
+
+    return(READSTAT);
+}
+
+int
+rs_write_window(FILE *savef, WINDOW *win)
+{
+    int row,col,height,width;
+
+    if (write_error)
+        return(WRITESTAT);
+
+    width  = getmaxx(win);
+    height = getmaxy(win);
+
+    rs_write_marker(savef,RSID_WINDOW);
+    rs_write_int(savef,height);
+    rs_write_int(savef,width);
+
+    for(row=0;row<height;row++)
+        for(col=0;col<width;col++)
+            if (rs_write_int(savef, mvwinch(win,row,col)) != 0)
+                return(WRITESTAT);
+
+    return(WRITESTAT);
+}
+
+int
+rs_read_window(int inf, WINDOW *win)
+{
+    int row,col,maxlines,maxcols,value,width,height;
+    
+    if (read_error || format_error)
+        return(READSTAT);
+
+    width  = getmaxx(win);
+    height = getmaxy(win);
+
+    rs_read_marker(inf, RSID_WINDOW);
+
+    rs_read_int(inf, &maxlines);
+    rs_read_int(inf, &maxcols);
+
+    for(row = 0; row < maxlines; row++)
+        for(col = 0; col < maxcols; col++)
+        {
+            if (rs_read_int(inf, &value) != 0)
+                return(READSTAT);
+
+            if ((row < height) && (col < width))
+                mvwaddch(win,row,col,value);
+        }
+        
+    return(READSTAT);
+}
+
+/******************************************************************************/
+
+void *
+get_list_item(struct linked_list *l, int i)
+{
+    int count;
+
+    for(count = 0; l != NULL; count++, l = l->l_next)
+        if (count == i)
+	    return(l->l_data);
+    
+    return(NULL);
+}
+
+int
+find_list_ptr(struct linked_list *l, void *ptr)
+{
+    int count;
+
+    for(count = 0; l != NULL; count++, l = l->l_next)
+        if (l->l_data == ptr)
+            return(count);
+    
+    return(-1);
+}
+
+int
+list_size(struct linked_list *l)
+{
+    int count;
+    
+    for(count = 0; l != NULL; count++, l = l->l_next)
+        ;
+    
+    return(count);
+}
+
+/******************************************************************************/
+
+int
+rs_write_levtype(FILE *savef, LEVTYPE c)
+{
+    int lt;
+    
+    switch(c)
+    {
+        case NORMLEV: lt = 1; break;
+        case POSTLEV: lt = 2; break;
+        case MAZELEV: lt = 3; break;
+        case OUTSIDE: lt = 4; break;
+        default: lt = -1; break;
+    }
+    
+    rs_write_int(savef,lt);
+        
+    return(WRITESTAT);
+}
+
+int
+rs_read_levtype(int inf, LEVTYPE *l)
+{
+    int lt;
+    
+    rs_read_int(inf, &lt);
+    
+    switch(lt)
+    {
+        case 1: *l = NORMLEV; break;
+        case 2: *l = POSTLEV; break;
+        case 3: *l = MAZELEV; break;
+        case 4: *l = OUTSIDE; break;
+        default: *l = NORMLEV; break;
+    }
+    
+    return(READSTAT);
+}
+
+int
+rs_write_stats(FILE *savef, struct stats *s)
+{
+    if (write_error)
+        return(WRITESTAT);
+
+    rs_write_marker(savef, RSID_STATS);
+    rs_write_short(savef, s->s_str);
+    rs_write_short(savef, s->s_intel);
+    rs_write_short(savef, s->s_wisdom);
+    rs_write_short(savef, s->s_dext);
+    rs_write_short(savef, s->s_const);
+    rs_write_short(savef, s->s_charisma);
+    rs_write_ulong(savef, s->s_exp);
+    rs_write_int(savef, s->s_lvl);
+    rs_write_int(savef, s->s_arm);
+    rs_write_int(savef, s->s_hpt);
+    rs_write_int(savef, s->s_pack);
+    rs_write_int(savef, s->s_carry);
+    rs_write(savef, s->s_dmg, sizeof(s->s_dmg));
+
+    return(WRITESTAT);
+}
+
+int
+rs_read_stats(int inf, struct stats *s)
+{
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read_marker(inf, RSID_STATS);
+    rs_read_short(inf,&s->s_str);
+    rs_read_short(inf,&s->s_intel);
+    rs_read_short(inf,&s->s_wisdom);
+    rs_read_short(inf,&s->s_dext);
+    rs_read_short(inf,&s->s_const);
+    rs_read_short(inf,&s->s_charisma);
+    rs_read_ulong(inf,&s->s_exp);
+    rs_read_int(inf,&s->s_lvl);
+    rs_read_int(inf,&s->s_arm);
+    rs_read_int(inf,&s->s_hpt);
+    rs_read_int(inf,&s->s_pack);
+    rs_read_int(inf,&s->s_carry);
+
+    rs_read(inf,s->s_dmg,sizeof(s->s_dmg));
+    
+    return(READSTAT);
+}
+
+int
+rs_write_magic_items(FILE *savef, struct magic_item *i, int count)
+{
+    int n;
+    
+    rs_write_marker(savef, RSID_MAGICITEMS);
+    rs_write_int(savef, count);
+
+    for(n = 0; n < count; n++)
+    {
+        rs_write_int(savef,i[n].mi_prob);
+    }
+    
+    return(WRITESTAT);
+}
+
+int
+rs_read_magic_items(int inf, struct magic_item *mi, int count)
+{
+    int n;
+    int value;
+
+    rs_read_marker(inf, RSID_MAGICITEMS);
+
+    rs_read_int(inf, &value);
+
+    if (value != count)
+	format_error = 1;
+    else
+    {
+	for(n = 0; n < value; n++)
+        {
+	    rs_read_int(inf,&mi[n].mi_prob);
+        }
+    }
+    
+    return(READSTAT);
+}
+
+int
+rs_write_scrolls(FILE *savef)
+{
+    int i;
+
+    if (write_error)
+        return(WRITESTAT);
+
+    for(i = 0; i < MAXSCROLLS; i++)
+    {
+        rs_write_string(savef, s_names[i]);
+	rs_write_boolean(savef,s_know[i]);
+        rs_write_string(savef,s_guess[i]);
+    }
+
+    return(WRITESTAT);
+}
+
+int
+rs_read_scrolls(int inf)
+{
+    int i;
+
+    if (read_error || format_error)
+        return(READSTAT);
+
+    for(i = 0; i < MAXSCROLLS; i++)
+    {
+        rs_read_new_string(inf,&s_names[i]);
+        rs_read_boolean(inf,&s_know[i]);
+        rs_read_new_string(inf,&s_guess[i]);
+    }
+
+    return(READSTAT);
+}
+
+int
+rs_write_potions(FILE *savef)
+{
+    int i;
+
+    if (write_error)
+        return(WRITESTAT);
+
+    for(i = 0; i < MAXPOTIONS; i++)
+    {
+	rs_write_string_index(savef,rainbow,NCOLORS,p_colors[i]);
+        rs_write_boolean(savef,p_know[i]);
+        rs_write_string(savef,p_guess[i]);
+    }
+
+    return(WRITESTAT);
+}
+
+int
+rs_read_potions(int inf)
+{
+    int i;
+
+    if (read_error || format_error)
+        return(READSTAT);
+
+    for(i = 0; i < MAXPOTIONS; i++)
+    {
+        rs_read_string_index(inf,rainbow,NCOLORS,&p_colors[i]);
+	rs_read_boolean(inf,&p_know[i]);
+        rs_read_new_string(inf,&p_guess[i]);
+    }
+
+    return(READSTAT);
+}
+
+int
+rs_write_rings(FILE *savef)
+{
+    int i;
+
+    if (write_error)
+        return(WRITESTAT);
+
+    for(i = 0; i < MAXRINGS; i++)
+    {
+	rs_write_string_index(savef,stones,NSTONES,r_stones[i]);
+        rs_write_boolean(savef,r_know[i]);
+        rs_write_string(savef,r_guess[i]);
+    }
+
+    return(WRITESTAT);
+}
+
+int
+rs_read_rings(int inf)
+{
+    int i;
+
+    if (read_error || format_error)
+        return(READSTAT);
+
+    for(i = 0; i < MAXRINGS; i++)
+    {
+        rs_read_string_index(inf,stones,NSTONES,&r_stones[i]);
+	rs_read_boolean(inf,&r_know[i]);
+        rs_read_new_string(inf,&r_guess[i]);
+    }
+
+    return(READSTAT);
+}
+
+int
+rs_write_sticks(FILE *savef)
+{
+    int i;
+
+    if (write_error)
+        return(WRITESTAT);
+
+    rs_write_marker(savef, RSID_STICKS);
+
+    for (i = 0; i < MAXSTICKS; i++)
+    {
+        if (strcmp(ws_type[i],"staff") == 0)
+        {
+            rs_write_int(savef,0);
+	    rs_write_string_index(savef,wood,NWOOD,ws_made[i]);
+        }
+        else
+        {
+            rs_write_int(savef,1);
+	    rs_write_string_index(savef,metal,NMETAL,ws_made[i]);
+        }
+
+	rs_write_boolean(savef, ws_know[i]);
+        rs_write_string(savef, ws_guess[i]);
+    }
+ 
+    return(WRITESTAT);
+}
+        
+int
+rs_read_sticks(int inf)
+{
+    int i = 0, j = 0, list = 0;
+
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read_marker(inf, RSID_STICKS);
+
+    for(i = 0; i < MAXSTICKS; i++)
+    { 
+        rs_read_int(inf,&list);
+        ws_made[i] = NULL;
+
+        if (list == 0)
+        {
+	    rs_read_string_index(inf,wood,NWOOD,&ws_made[i]);
+            ws_type[i] = "staff";
+        }
+        else 
+        {
+	    rs_read_string_index(inf,metal,NMETAL,&ws_made[i]);
+	    ws_type[i] = "wand";
+        }
+	rs_read_boolean(inf, &ws_know[i]);
+        rs_read_new_string(inf, &ws_guess[i]);
+    }
+
+    return(READSTAT);
+}
+
+int
+rs_write_daemons(FILE *savef, struct delayed_action *d_list, int count)
+{
+    int i = 0;
+    int func = 0;
+        
+    if (write_error)
+        return(WRITESTAT);
+
+    rs_write_marker(savef, RSID_DAEMONS);
+    rs_write_int(savef, count);
+        
+    for(i = 0; i < count; i++)
+    {
+        if ( d_list[i].d_func == rollwand)
+            func = 1;
+        else if ( d_list[i].d_func == doctor)
+            func = 2;
+        else if ( d_list[i].d_func == stomach)
+            func = 3;
+        else if ( d_list[i].d_func == runners)
+            func = 4;
+        else if ( d_list[i].d_func == swander)
+            func = 5;
+        else if ( d_list[i].d_func == trap_look)
+            func = 6;
+        else if ( d_list[i].d_func == ring_search)
+            func = 7;
+        else if ( d_list[i].d_func == ring_teleport)
+            func = 8;
+        else if ( d_list[i].d_func == strangle)
+            func = 9;
+        else if ( d_list[i].d_func == fumble)
+            func = 10;
+        else if ( d_list[i].d_func == wghtchk)
+            func = 11;
+        else if ( d_list[i].d_func == unstink)
+            func = 12;
+        else if ( d_list[i].d_func == res_strength)
+            func = 13;
+        else if ( d_list[i].d_func == un_itch)
+            func = 14;
+        else if ( d_list[i].d_func == cure_disease)
+            func = 15;
+        else if ( d_list[i].d_func == unconfuse)
+            func = 16;
+        else if ( d_list[i].d_func == suffocate)
+            func = 17;
+        else if ( d_list[i].d_func == undance)
+            func = 18;
+        else if ( d_list[i].d_func == alchemy)
+            func = 19;
+        else if ( d_list[i].d_func == dust_appear)
+            func = 20;
+        else if ( d_list[i].d_func == unchoke)
+            func = 21;
+        else if ( d_list[i].d_func == sight)
+            func = 22;
+        else if ( d_list[i].d_func == noslow)
+            func = 23;
+        else if ( d_list[i].d_func == nohaste)
+            func = 24;
+        else if ( d_list[i].d_func == unclrhead)
+            func = 25;
+        else if ( d_list[i].d_func == unsee)
+            func = 26;
+        else if ( d_list[i].d_func == unphase)
+            func = 27;
+        else if ( d_list[i].d_func == land)
+            func = 28;
+        else if ( d_list[i].d_func == appear)
+            func = 29;
+        else if (d_list[i].d_func == NULL)
+            func = 0;
+        else
+            func = -1;
+
+        rs_write_int(savef, d_list[i].d_type);
+        rs_write_int(savef, func);
+        rs_write_int(savef, d_list[i].d_arg);
+        rs_write_int(savef, d_list[i].d_time);
+    }
+    
+    return(WRITESTAT);
+}       
+
+int
+rs_read_daemons(int inf, struct delayed_action *d_list, int count)
+{
+    int i = 0;
+    int func = 0;
+    int value = 0;
+    int dummy = 0;
+    
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read_marker(inf, RSID_DAEMONS);
+    rs_read_int(inf, &value);
+
+    if (value > count)
+        format_error = TRUE;
+
+    
+    for(i=0; i < count; i++)
+    {
+	func = 0;
+        rs_read_int(inf, &d_list[i].d_type);
+        rs_read_int(inf, &func);
+                    
+        switch(func)
+        {
+	    case  1: d_list[i].d_func = rollwand;
+		     break;
+            case  2: d_list[i].d_func = doctor;
+		     break;
+            case 3: d_list[i].d_func = stomach;
+		     break;
+            case  4: d_list[i].d_func = runners;
+                     break;
+            case  5: d_list[i].d_func = swander;
+                     break;
+            case  6: d_list[i].d_func = trap_look;
+                     break;
+            case  7: d_list[i].d_func = ring_search;
+                     break;
+            case  8: d_list[i].d_func = ring_teleport;
+                     break;
+            case  9: d_list[i].d_func = strangle;
+                     break;
+            case 10: d_list[i].d_func = fumble;
+                     break;
+            case 11: d_list[i].d_func = wghtchk;
+                     break;
+            case 12: d_list[i].d_func = unstink;
+                     break;
+            case 13: d_list[i].d_func = res_strength;
+                     break;
+            case 14: d_list[i].d_func = un_itch;
+                     break;
+            case 15: d_list[i].d_func = cure_disease;
+                     break;
+            case 16: d_list[i].d_func = unconfuse;
+                     break;
+            case 17: d_list[i].d_func = suffocate;
+                     break;
+            case 18: d_list[i].d_func = undance;
+                     break;
+            case 19: d_list[i].d_func = alchemy;
+                     break;
+            case 20: d_list[i].d_func = dust_appear;
+                     break;
+            case 21: d_list[i].d_func = unchoke;
+                     break;
+            case 22: d_list[i].d_func = sight;
+                     break;
+            case 23: d_list[i].d_func = noslow;
+                     break;
+            case 24: d_list[i].d_func = nohaste;
+                     break;
+            case 25: d_list[i].d_func = unclrhead;
+                     break;
+            case 26: d_list[i].d_func = unsee;
+                     break;
+            case 27: d_list[i].d_func = unphase;
+                     break;
+            case 28: d_list[i].d_func = land;
+                     break;
+            case 29: d_list[i].d_func = appear;
+                     break;
+	    case  0:
+            case -1:
+            default: d_list[i].d_func = NULL;
+                     break;
+        }   
+
+        rs_read_int(inf, &d_list[i].d_arg);
+        rs_read_int(inf, &d_list[i].d_time);
+
+	if (d_list[i].d_func == NULL) 
+	{
+	    d_list[i].d_time = 0;
+	    d_list[i].d_arg = 0;
+	    d_list[i].d_type = 0;
+	}
+    }
+    
+    return(READSTAT);
+}        
+
+int
+rs_write_room(FILE *savef, struct room *r)
+{
+    struct linked_list *l;
+    int i;
+
+    if (write_error)
+        return(WRITESTAT);
+
+    rs_write_coord(savef, r->r_pos);
+    rs_write_coord(savef, r->r_max);
+    rs_write_long(savef, r->r_flags);
+
+    l = r->r_fires;
+    i = list_size(l);
+        
+    rs_write_int(savef, i);
+
+    if (i >0)
+	while (l != NULL)
+        {
+	    i = find_list_ptr(mlist, l->l_data);
+            rs_write_int(savef,i);
+            l = l->l_next;
+        }
+    
+    rs_write_coord_list(savef, r->r_exit);
+
+    return(WRITESTAT);
+}
+
+int
+rs_read_room(int inf, struct room *r)
+{
+    int value = 0, n = 0, i = 0, index = 0, id = 0;
+    struct linked_list *fires=NULL, *item = NULL;
+    
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read_coord(inf,&r->r_pos);
+    rs_read_coord(inf,&r->r_max);
+    rs_read_long(inf,&r->r_flags);
+
+    rs_read_int(inf, &i);
+    fires = NULL;
+
+    while (i>0)
+    {
+	rs_read_int(inf,&index);
+                        
+        if (index >= 0)
+        {
+	    void *data;
+            data = get_list_item(mlist,index);
+            item = creat_item();
+            item->l_data = data;
+            if (fires == NULL)
+		fires = item;
+            else
+		attach(fires,item);
+        }
+        i--;
+    }
+
+    r->r_fires=fires; 
+
+    rs_read_coord_list(inf, &r->r_exit);
+
+    return(READSTAT);
+}
+
+int
+rs_write_rooms(FILE *savef, struct room r[], int count)
+{
+    int n = 0;
+
+    if (write_error)
+        return(WRITESTAT);
+
+    rs_write_int(savef, count);
+    
+    for(n = 0; n < count; n++)
+        rs_write_room(savef, &r[n]);
+    
+    return(WRITESTAT);
+}
+
+int
+rs_read_rooms(int inf, struct room *r, int count)
+{
+    int value = 0, n = 0;
+
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read_int(inf,&value);
+
+    if (value > count)
+        format_error = TRUE;
+
+    for(n = 0; n < value; n++)
+        rs_read_room(inf,&r[n]);
+
+    return(READSTAT);
+}
+
+rs_write_room_reference(FILE *savef, struct room *rp)
+{
+    int i, room = -1;
+    
+    if (write_error)
+        return(WRITESTAT);
+
+    for (i = 0; i < MAXROOMS; i++)
+        if (&rooms[i] == rp)
+            room = i;
+
+    rs_write_int(savef, room);
+
+    return(WRITESTAT);
+}
+
+int
+rs_read_room_reference(int inf, struct room **rp)
+{
+    int i;
+    
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read_int(inf, &i);
+
+    *rp = &rooms[i];
+            
+    return(READSTAT);
+}
+
+int
+rs_write_door_reference(FILE *savef, coord *exit)
+{
+    int i, idx;
+
+    for (i = 0; i < MAXROOMS; i++)
+    {
+	idx = find_list_ptr(rooms[i].r_exit, exit);
+
+	if (idx != -1)
+	    break;
+    }
+
+    if (i >= MAXROOMS) 
+    {
+        rs_write_int(savef,-1);
+	rs_write_int(savef,-1);
+	if (exit != NULL)
+	    abort();
+    }
+    else
+    {
+	rs_write_int(savef,i);
+	rs_write_int(savef,idx);
+    }
+
+    return(WRITESTAT);
+}
+
+int
+rs_read_door_reference(int inf, coord **exit)
+{
+    int i, idx;
+
+    rs_read_int(inf, &i);
+    rs_read_int(inf, &idx);
+
+    if ( (i == -1) || (idx == -1) )
+	*exit = NULL;
+    else
+	*exit = get_list_item(rooms[i].r_exit, idx);
+
+    return(READSTAT);
+}
+
+int
+rs_write_traps(FILE *savef, struct trap *trap,int count)
+{
+    int n;
+
+    rs_write_int(savef, RSID_TRAP);
+    rs_write_int(savef, count);
+    
+    for(n=0; n<count; n++)
+    {
+        rs_write_char(savef, trap[n].tr_type);
+        rs_write_char(savef, trap[n].tr_show);
+        rs_write_coord(savef, trap[n].tr_pos);
+        rs_write_long(savef, trap[n].tr_flags);
+    }
+}
+
+int
+rs_read_traps(int inf, struct trap *trap, int count)
+{
+    int id = 0, value = 0, n = 0;
+
+    if (rs_read_int(inf,&id) != 0)
+        format_error = TRUE;
+    else if (rs_read_int(inf,&value) != 0)
+    {
+        if (value != count)
+	    format_error = TRUE;
+    }
+    else
+    {
+	for(n=0;n<value;n++)
+        {   
+	    rs_read_char(inf,&trap[n].tr_type);
+            rs_read_char(inf,&trap[n].tr_show);
+            rs_read_coord(inf,&trap[n].tr_pos);
+            rs_read_long(inf,&trap[n].tr_flags);
+	}
+    }
+    
+    return(READSTAT);
+}
+
+int
+rs_write_monsters(FILE *savef, struct monster *m, int count)
+{
+    int n;
+    
+    if (write_error)
+        return(WRITESTAT);
+
+    rs_write_marker(savef, RSID_MONSTERS);
+    rs_write_int(savef, count);
+
+    for(n=0;n<count;n++)
+    {
+        rs_write_boolean(savef, m[n].m_normal);
+        rs_write_boolean(savef, m[n].m_wander);
+        rs_write_short(savef, m[n].m_numsum);
+    }
+    
+    return(WRITESTAT);
+}
+
+int
+rs_read_monsters(int inf, struct monster *m, int count)
+{
+    int value = 0, n = 0;
+
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read_marker(inf, RSID_MONSTERS);
+
+    rs_read_int(inf, &value);
+
+    if (value != count)
+        format_error = TRUE;
+
+    for(n = 0; n < count; n++)
+    {
+        rs_read_boolean(inf, &m[n].m_normal);
+        rs_read_boolean(inf, &m[n].m_wander);
+	rs_read_short(inf, &m[n].m_numsum);
+    }
+
+    return(READSTAT);
+}
+
+int
+rs_write_object(FILE *savef, struct object *o)
+{
+    if (write_error)
+        return(WRITESTAT);
+
+    rs_write_marker(savef, RSID_OBJECT);
+    rs_write_int(savef, o->o_type);
+    rs_write_coord(savef, o->o_pos);
+    rs_write_char(savef, o->o_launch);
+    rs_write(savef, o->o_damage, sizeof(o->o_damage));
+    rs_write(savef, o->o_hurldmg, sizeof(o->o_hurldmg));
+    rs_write_object_list(savef, o->contents);
+    rs_write_int(savef, o->o_count);
+    rs_write_int(savef, o->o_which);
+    rs_write_int(savef, o->o_hplus);
+    rs_write_int(savef, o->o_dplus);
+    rs_write_int(savef, o->o_ac);
+    rs_write_long(savef, o->o_flags);
+    rs_write_int(savef, o->o_group);
+    rs_write_int(savef, o->o_weight);
+    rs_write(savef, o->o_mark, MARKLEN);
+       
+    
+    return(WRITESTAT);
+}
+
+int
+rs_read_object(int inf, struct object *o)
+{
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read_marker(inf, RSID_OBJECT);
+    rs_read_int(inf, &o->o_type);
+    rs_read_coord(inf, &o->o_pos);
+    rs_read_char(inf, &o->o_launch);
+    rs_read(inf, o->o_damage, sizeof(o->o_damage));
+    rs_read(inf, o->o_hurldmg, sizeof(o->o_hurldmg));
+    rs_read_object_list(inf,&o->contents);
+    rs_read_int(inf, &o->o_count);
+    rs_read_int(inf, &o->o_which);
+    rs_read_int(inf, &o->o_hplus);
+    rs_read_int(inf, &o->o_dplus);
+    rs_read_int(inf, &o->o_ac);
+    rs_read_long(inf,&o->o_flags);
+    rs_read_int(inf, &o->o_group);
+    rs_read_int(inf, &o->o_weight);
+    rs_read(inf, o->o_mark, MARKLEN);
+    
+    return(READSTAT);
+}
+
+int
+rs_write_object_list(FILE *savef, struct linked_list *l)
+{
+    if (write_error)
+        return(WRITESTAT);
+
+    rs_write_marker(savef, RSID_OBJECTLIST);
+    rs_write_int(savef, list_size(l));
+
+    for( ;l != NULL; l = l->l_next)
+        rs_write_object(savef, OBJPTR(l));
+    
+    return(WRITESTAT);
+}
+
+int
+rs_read_object_list(int inf, struct linked_list **list)
+{
+    int i, cnt;
+    struct linked_list *l = NULL, *previous = NULL, *head = NULL;
+
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read_marker(inf, RSID_OBJECTLIST);
+    rs_read_int(inf, &cnt);
+
+    for (i = 0; i < cnt; i++) 
+    {
+        l = new_item(sizeof(struct object));
+
+	l->l_prev = previous;
+
+        if (previous != NULL)
+            previous->l_next = l;
+
+        rs_read_object(inf,OBJPTR(l));
+
+        if (previous == NULL)
+            head = l;
+
+        previous = l;
+    }
+            
+    if (l != NULL)
+        l->l_next = NULL;
+    
+    *list = head;
+
+    return(READSTAT);
+}
+
+int
+rs_write_object_reference(FILE *savef, struct linked_list *list, struct object *item)
+{
+    int i;
+    
+    if (write_error)
+        return(WRITESTAT);
+
+    i = find_list_ptr(list, item);
+
+    rs_write_int(savef, i);
+
+    return(WRITESTAT);
+}
+
+int
+rs_read_object_reference(int inf, struct linked_list *list, struct object **item)
+{
+    int i;
+    
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read_int(inf, &i);
+
+    *item = get_list_item(list,i);
+            
+    return(READSTAT);
+}
+
+int
+find_thing_coord(struct linked_list *monlist, coord *c)
+{
+    struct linked_list *mitem;
+    struct thing *tp;
+    int i = 0;
+
+    for(mitem = monlist; mitem != NULL; mitem = mitem->l_next)
+    {
+        tp = THINGPTR(mitem);
+
+        if (c == &tp->t_pos)
+            return(i);
+
+        i++;
+    }
+
+    return(-1);
+}
+
+int
+find_object_coord(struct linked_list *objlist, coord *c)
+{
+    struct linked_list *oitem;
+    struct object *obj;
+    int i = 0;
+
+    for(oitem = objlist; oitem != NULL; oitem = oitem->l_next)
+    {
+        obj = OBJPTR(oitem);
+
+        if (c == &obj->o_pos)
+            return(i);
+
+        i++;
+    }
+
+    return(-1);
+}
+
+int
+rs_write_thing(FILE *savef, struct thing *t)
+{
+    int i = -1;
+    
+    if (write_error)
+        return(WRITESTAT);
+
+    rs_write_marker(savef, RSID_THING);
+
+    if (t == NULL)
+    {
+        rs_write_int(savef, 0);
+        return(WRITESTAT);
+    }
+    
+    rs_write_int(savef, 1);
+
+    rs_write_boolean(savef, t->t_turn);
+    rs_write_boolean(savef, t->t_wasshot);
+    rs_write_char(savef, t->t_type);
+    rs_write_char(savef, t->t_disguise);
+    rs_write_char(savef, t->t_oldch);
+
+    rs_write_short(savef, t->t_ctype);
+    rs_write_short(savef, t->t_index);
+    rs_write_short(savef, t->t_no_move);
+    rs_write_short(savef, t->t_quiet);
+
+    rs_write_door_reference(savef, t->t_doorgoal);
+ 
+    rs_write_coord(savef, t->t_pos);
+    rs_write_coord(savef, t->t_oldpos);
+
+    /* 
+        t_dest can be:
+        0,0: NULL
+        0,1: location of hero
+        0,3: global coord 'delta'
+        1,i: location of a thing (monster)
+        2,i: location of an object
+        3,i: location of gold in a room
+
+        We need to remember what we are chasing rather than 
+        the current location of what we are chasing.
+    */
+
+    if (t->t_dest == &hero)
+    {
+        rs_write_int(savef,0);
+        rs_write_int(savef,1);
+    }
+    else if (t->t_dest != NULL)
+    {
+        i = find_thing_coord(mlist, t->t_dest);
+            
+        if (i >=0 )
+        {
+            rs_write_int(savef,1);
+            rs_write_int(savef,i);
+        }
+        else
+        {
+            i = find_object_coord(lvl_obj, t->t_dest);
+            
+            if (i >= 0)
+            {
+                rs_write_int(savef,2);
+                rs_write_int(savef,i);
+            }
+            else
+            {
+                rs_write_int(savef, 0);
+                rs_write_int(savef,1); /* chase the hero anyway */
+            }
+        }
+    }
+    else
+    {
+        rs_write_int(savef,0);
+        rs_write_int(savef,0);
+    }
+    
+    rs_write_ulongs(savef, t->t_flags, 16);
+    rs_write_object_list(savef, t->t_pack);
+    rs_write_stats(savef, &t->t_stats);
+    rs_write_stats(savef, &t->maxstats);
+    
+    return(WRITESTAT);
+}
+
+int
+rs_read_thing(int inf, struct thing *t)
+{
+    int listid = 0, index = -1;
+
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read_marker(inf, RSID_THING);
+
+    rs_read_int(inf, &index);
+
+    if (index == 0)
+        return(READSTAT);
+
+    rs_read_boolean(inf, &t->t_turn);
+    rs_read_boolean(inf, &t->t_wasshot);
+    rs_read_char(inf, &t->t_type);
+    rs_read_char(inf, &t->t_disguise);
+    rs_read_char(inf, &t->t_oldch);
+    rs_read_short(inf, &t->t_ctype);
+    rs_read_short(inf, &t->t_index);
+    rs_read_short(inf, &t->t_no_move);
+    rs_read_short(inf, &t->t_quiet);
+    rs_read_door_reference(inf,&t->t_doorgoal);
+    rs_read_coord(inf, &t->t_pos);
+    rs_read_coord(inf, &t->t_oldpos);
+
+    /* 
+	t_dest can be (listid,index):
+	    0,0: NULL
+            0,1: location of hero
+            1,i: location of a thing (monster)
+            2,i: location of an object
+            3,i: location of gold in a room
+
+	We need to remember what we are chasing rather than 
+        the current location of what we are chasing.
+    */
+            
+    rs_read_int(inf, &listid);
+    rs_read_int(inf, &index);
+    t->t_reserved = -1;
+
+    if (listid == 0) /* hero or NULL */
+    {
+	if (index == 1)
+	    t->t_dest = &hero;
+        else
+	    t->t_dest = NULL;
+    }
+    else if (listid == 1) /* monster/thing */
+    {
+	t->t_dest     = NULL;
+        t->t_reserved = index;
+    }
+    else if (listid == 2) /* object */
+    {
+	struct object *obj;
+
+        obj = get_list_item(lvl_obj, index);
+
+        if (obj != NULL)
+        {
+            t->t_dest = &obj->o_pos;
+        }
+    }
+    else
+	t->t_dest = NULL;
+
+    rs_read_ulongs(inf, t->t_flags, 16);
+    rs_read_object_list(inf, &t->t_pack);
+    rs_read_stats(inf, &t->t_stats);
+    rs_read_stats(inf, &t->maxstats);
+    
+    return(READSTAT);
+}
+
+int
+rs_fix_thing(struct thing *t)
+{
+    struct thing *tp;
+
+    if (t->t_reserved < 0)
+        return;
+
+    tp = get_list_item(mlist,t->t_reserved);
+
+    if (tp != NULL)
+    {
+        t->t_dest = &tp->t_pos;
+    }
+}
+
+int
+rs_write_thing_list(FILE *savef, struct linked_list *l)
+{
+    int cnt = 0;
+    
+    if (write_error)
+        return(WRITESTAT);
+
+    rs_write_marker(savef, RSID_MONSTERLIST);
+
+    cnt = list_size(l);
+
+    rs_write_int(savef, cnt);
+
+    if (cnt < 1)
+        return(WRITESTAT);
+
+    while (l != NULL) {
+        rs_write_thing(savef, (struct thing *)l->l_data);
+        l = l->l_next;
+    }
+    
+    return(WRITESTAT);
+}
+
+int
+rs_read_thing_list(int inf, struct linked_list **list)
+{
+    int i, cnt;
+    struct linked_list *l = NULL, *previous = NULL, *head = NULL;
+
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read_marker(inf, RSID_MONSTERLIST);
+
+    rs_read_int(inf, &cnt);
+
+    for (i = 0; i < cnt; i++) 
+    {
+        l = new_item(sizeof(struct thing));
+
+        l->l_prev = previous;
+            
+        if (previous != NULL)
+            previous->l_next = l;
+
+        rs_read_thing(inf,THINGPTR(l));
+
+        if (previous == NULL)
+            head = l;
+
+        previous = l;
+    }
+        
+    if (l != NULL)
+        l->l_next = NULL;
+
+    *list = head;
+    
+    return(READSTAT);
+}
+
+int
+rs_fix_thing_list(struct linked_list *list)
+{
+    struct linked_list *item;
+
+    for(item = list; item != NULL; item = item->l_next)
+        rs_fix_thing(THINGPTR(item));
+}
+
+int
+rs_save_file(FILE *savef)
+{
+    int i;
+
+    if (write_error)
+        return(WRITESTAT);
+
+    rs_write_object_list(savef, lvl_obj);
+    rs_write_thing(savef, &player);
+    rs_write_thing_list(savef, mlist);
+    rs_write_thing_list(savef, tlist);
+    rs_write_thing_list(savef, monst_dead);
+    
+    rs_write_traps(savef, traps, MAXTRAPS);             
+    rs_write_rooms(savef, rooms, MAXROOMS);
+    rs_write_room_reference(savef, oldrp);
+
+    rs_write_object_reference(savef, player.t_pack, cur_armor);
+
+    for(i = 0; i < NUM_FINGERS; i++)
+        rs_write_object_reference(savef, player.t_pack, cur_ring[i]);
+
+    for(i = 0; i < NUM_MM; i++)
+        rs_write_object_reference(savef, player.t_pack, cur_misc[i]);
+
+    rs_write_ints(savef, cur_relic, MAXRELIC);
+    
+    rs_write_object_reference(savef, player.t_pack, cur_weapon); 
+
+    rs_write_int(savef, char_type);
+    rs_write_int(savef, foodlev);
+    rs_write_int(savef, ntraps);
+    rs_write_int(savef, trader);
+    rs_write_int(savef, curprice);
+    rs_write_int(savef, no_move);
+    rs_write_int(savef, seed);
+    rs_write_int(savef, dnum);
+    rs_write_int(savef, max_level);
+    rs_write_int(savef, cur_max);
+    rs_write_int(savef, lost_dext);
+    rs_write_int(savef, no_command);
+    rs_write_int(savef, level);
+    rs_write_int(savef, purse);
+    rs_write_int(savef, inpack);
+    rs_write_int(savef, total);
+    rs_write_int(savef, no_food);
+    rs_write_int(savef, foods_this_level);
+    rs_write_int(savef, count);
+    rs_write_int(savef, food_left);
+    rs_write_int(savef, group);
+    rs_write_int(savef, hungry_state);
+    rs_write_int(savef, infest_dam);
+    rs_write_int(savef, lost_str);
+    rs_write_int(savef, lastscore);
+    rs_write_int(savef, hold_count);
+    rs_write_int(savef, trap_tries);
+    rs_write_int(savef, pray_time);
+    rs_write_int(savef, spell_power);
+    rs_write_int(savef, turns);
+    rs_write_int(savef, quest_item);
+    rs_write_char(savef, nfloors);
+    rs_write(savef, curpurch, 15);
+    rs_write_char(savef, PLAYER);
+    rs_write_char(savef, take);
+    rs_write(savef, prbuf, LINELEN);
+    rs_write_char(savef, runch);
+    rs_write(savef, whoami, LINELEN);
+    rs_write(savef, fruit, LINELEN);
+    rs_write_scrolls(savef);
+    rs_write_potions(savef);
+    rs_write_rings(savef);
+    rs_write_sticks(savef);
+    for(i = 0; i < MAXMM; i++)
+        rs_write_string(savef, m_guess[i]);
+    rs_write_window(savef, cw);
+    rs_write_window(savef, mw);
+    rs_write_window(savef, stdscr);
+    rs_write_boolean(savef, pool_teleport);
+    rs_write_boolean(savef, inwhgt);
+    rs_write_boolean(savef, after);
+    rs_write_boolean(savef, waswizard);
+    rs_write_booleans(savef, m_know, MAXMM);
+    rs_write_boolean(savef, playing);
+    rs_write_boolean(savef, running);
+    rs_write_boolean(savef, wizard);
+    rs_write_boolean(savef, notify);
+    rs_write_boolean(savef, fight_flush);
+    rs_write_boolean(savef, terse);
+    rs_write_boolean(savef, auto_pickup);
+    rs_write_boolean(savef, door_stop);
+    rs_write_boolean(savef, jump);
+    rs_write_boolean(savef, slow_invent);
+    rs_write_boolean(savef, firstmove);
+    rs_write_boolean(savef, askme);
+    rs_write_boolean(savef, in_shell);
+    rs_write_boolean(savef, daytime);
+    rs_write_coord(savef, delta);
+    rs_write_levtype(savef, levtype);
+
+    rs_write_monsters(savef, monsters, NUMMONST+1);
+
+    rs_write_magic_items(savef, things, NUMTHINGS);
+    rs_write_magic_items(savef, s_magic, MAXSCROLLS);
+    rs_write_magic_items(savef, p_magic, MAXPOTIONS);
+    rs_write_magic_items(savef, r_magic, MAXRINGS);
+    rs_write_magic_items(savef, ws_magic, MAXSTICKS);
+    rs_write_magic_items(savef, m_magic, MAXMM);
+
+
+    rs_write_coord(savef, ch_ret);
+    rs_write_int(savef, demoncnt);
+    rs_write_int(savef, fusecnt);
+    rs_write_daemons(savef, d_list, MAXDAEMONS);
+    rs_write_daemons(savef, f_list, MAXFUSES);
+    rs_write_int(savef, between);
+
+    fflush(savef);
+
+    return(WRITESTAT);
+}
+
+rs_restore_file(int inf)
+{
+    int i;
+    
+    if (read_error || format_error)
+        return(READSTAT);
+    
+    rs_read_object_list(inf, &lvl_obj);
+    rs_read_thing(inf, &player);
+    rs_read_thing_list(inf, &mlist);
+    rs_read_thing_list(inf, &tlist);
+    rs_read_thing_list(inf, &monst_dead);
+
+    rs_fix_thing(&player);
+    rs_fix_thing_list(mlist);
+    rs_fix_thing_list(tlist);
+    rs_fix_thing_list(monst_dead);
+
+    rs_read_traps(inf, traps, MAXTRAPS);             
+    rs_read_rooms(inf, rooms, MAXROOMS);
+    rs_read_room_reference(inf, &oldrp);
+
+    rs_read_object_reference(inf, player.t_pack, &cur_armor);
+
+    for(i = 0; i < NUM_FINGERS; i++)
+        rs_read_object_reference(inf, player.t_pack, &cur_ring[i]);
+
+    for(i = 0; i < NUM_MM; i++)
+        rs_read_object_reference(inf, player.t_pack, &cur_misc[i]);
+
+    rs_read_ints(inf, cur_relic, MAXRELIC);
+
+    rs_read_object_reference(inf, player.t_pack, &cur_weapon);
+
+    rs_read_int(inf, &char_type);
+    rs_read_int(inf, &foodlev);
+    rs_read_int(inf, &ntraps);
+    rs_read_int(inf, &trader);
+    rs_read_int(inf, &curprice);
+    rs_read_int(inf, &no_move);
+    rs_read_int(inf, &seed);
+    rs_read_int(inf, &dnum);
+    rs_read_int(inf, &max_level);
+    rs_read_int(inf, &cur_max);
+    rs_read_int(inf, &lost_dext);
+    rs_read_int(inf, &no_command);
+    rs_read_int(inf, &level);
+    rs_read_int(inf, &purse);
+    rs_read_int(inf, &inpack);
+    rs_read_int(inf, &total);
+    rs_read_int(inf, &no_food);
+    rs_read_int(inf, &foods_this_level);
+    rs_read_int(inf, &count);
+    rs_read_int(inf, &food_left);
+    rs_read_int(inf, &group);
+    rs_read_int(inf, &hungry_state);
+    rs_read_int(inf, &infest_dam);
+    rs_read_int(inf, &lost_str);
+    rs_read_int(inf, &lastscore);
+    rs_read_int(inf, &hold_count);
+    rs_read_int(inf, &trap_tries);
+    rs_read_int(inf, &pray_time);
+    rs_read_int(inf, &spell_power);
+    rs_read_int(inf, &turns);
+    rs_read_int(inf, &quest_item);
+    rs_read_char(inf, &nfloors);
+    rs_read(inf, &curpurch, 15);
+    rs_read_char(inf, &PLAYER);
+    rs_read_char(inf, &take);
+    rs_read(inf, &prbuf, LINELEN);
+    rs_read_char(inf, &runch);
+    rs_read(inf, &whoami, LINELEN);
+    rs_read(inf, &fruit, LINELEN);
+    rs_read_scrolls(inf);
+    rs_read_potions(inf);
+    rs_read_rings(inf);
+    rs_read_sticks(inf);
+    for(i = 0; i < MAXMM; i++)
+        rs_read_new_string(inf, &m_guess[i]);
+    rs_read_window(inf, cw);
+    rs_read_window(inf, mw);
+    rs_read_window(inf, stdscr);
+    rs_read_boolean(inf, &pool_teleport);
+    rs_read_boolean(inf, &inwhgt);
+    rs_read_boolean(inf, &after);
+    rs_read_boolean(inf, &waswizard);
+    rs_read_booleans(inf, m_know, MAXMM);
+    rs_read_boolean(inf, &playing);
+    rs_read_boolean(inf, &running);
+    rs_read_boolean(inf, &wizard);
+    rs_read_boolean(inf, &notify);
+    rs_read_boolean(inf, &fight_flush);
+    rs_read_boolean(inf, &terse);
+    rs_read_boolean(inf, &auto_pickup);
+    rs_read_boolean(inf, &door_stop);
+    rs_read_boolean(inf, &jump);
+    rs_read_boolean(inf, &slow_invent);
+    rs_read_boolean(inf, &firstmove);
+    rs_read_boolean(inf, &askme);
+    rs_read_boolean(inf, &in_shell);
+    rs_read_boolean(inf, &daytime);
+    rs_read_coord(inf, &delta);
+    rs_read_levtype(inf, &levtype);
+
+    rs_read_monsters(inf, monsters, NUMMONST+1);
+
+    rs_read_magic_items(inf, things, NUMTHINGS);
+    rs_read_magic_items(inf, s_magic, MAXSCROLLS);
+    rs_read_magic_items(inf, p_magic, MAXPOTIONS);
+    rs_read_magic_items(inf, r_magic, MAXRINGS);
+    rs_read_magic_items(inf, ws_magic, MAXSTICKS);
+    rs_read_magic_items(inf, m_magic, MAXMM);
+
+    rs_read_coord(inf, &ch_ret);
+    rs_read_int(inf, &demoncnt);
+    rs_read_int(inf, &fusecnt);
+    rs_read_daemons(inf, d_list, MAXDAEMONS);
+    rs_read_daemons(inf, f_list, MAXFUSES);
+    rs_read_int(inf, &between);
+
+    return(READSTAT);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/sticks.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,1076 @@
+/*
+ * Functions to implement the various sticks one might find
+ * while wandering around the dungeon.
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include <ctype.h>
+#include "rogue.h"
+
+
+/*
+ * zap a stick and see what happens
+ */
+do_zap(gotdir, which, flag)
+bool gotdir;
+int which;
+int flag;
+{
+    register struct linked_list *item;
+    register struct object *obj = NULL;
+    register struct thing *tp;
+    register int y, x;
+    struct linked_list *nitem;
+    struct object *nobj;
+    bool cursed, blessed, is_stick;
+
+    blessed = FALSE;
+    cursed = FALSE;
+    is_stick = FALSE;
+
+    if (which == 0) {
+	if ((item = get_item(pack, "zap with", ZAPPABLE)) == NULL)
+	    return(FALSE);
+	obj = OBJPTR(item);
+
+	/* Handle relics specially here */
+	if (obj->o_type == RELIC) {
+	    switch (obj->o_which) {
+		case ORCUS_WAND:
+		    msg(nothing);
+		    return(TRUE);
+		when MING_STAFF:
+		    which = WS_MISSILE;
+		when ASMO_ROD:
+		    switch (rnd(3)) {
+			case 0:
+			    which = WS_ELECT;
+			when 1:
+			    which = WS_COLD;
+			otherwise:
+			    which = WS_FIRE;
+		    }
+	    }
+	    cursed = FALSE;
+	    blessed = FALSE;
+	}
+	else {
+	    which = obj->o_which;
+	    ws_know[which] = TRUE;
+	    cursed = (obj->o_flags & ISCURSED) != 0;
+	    blessed = (obj->o_flags & ISBLESSED) != 0;
+	    is_stick = TRUE;
+	}
+    }
+    else {
+	cursed = flag & ISCURSED;
+	blessed = flag & ISBLESSED;
+    }
+    switch (which) {	/* no direction for these */
+	case WS_LIGHT:
+	case WS_DRAIN:
+	case WS_CHARGE:
+	case WS_CURING:
+	    break;
+
+	default:
+	    if (!get_dir())
+		return(FALSE);
+	    if (!gotdir) {
+		do {
+		    delta.y = rnd(3) - 1;
+		    delta.x = rnd(3) - 1;
+		} while (delta.y == 0 && delta.x == 0);
+	    }
+    }
+
+    if (is_stick) {
+	if (obj->o_charges < 1) {
+	    msg(nothing);
+	    return(TRUE);
+	}
+	obj->o_charges--;
+    }
+    if (which == WS_WONDER) {
+	switch (rnd(14)) {
+	    case  0: which = WS_ELECT;
+	    when  1: which = WS_FIRE;
+	    when  2: which = WS_COLD;
+	    when  3: which = WS_POLYMORPH;
+	    when  4: which = WS_MISSILE;
+	    when  5: which = WS_SLOW_M;
+	    when  6: which = WS_TELMON;
+	    when  7: which = WS_CANCEL;
+	    when  8: which = WS_CONFMON;
+	    when  9: which = WS_DISINTEGRATE;
+	    when 10: which = WS_PETRIFY;
+	    when 11: which = WS_PARALYZE;
+	    when 12: which = WS_MDEG;
+	    when 13: which = WS_FEAR;
+	}
+	if(ws_magic[which].mi_curse>0 && rnd(100)<=ws_magic[which].mi_curse){
+	    cursed = TRUE;
+	    blessed = FALSE;
+	}
+    }
+
+    switch (which) {
+	case WS_LIGHT:
+	    /*
+	     * Reddy Kilowat wand.  Light up the room
+	     */
+	    blue_light(blessed, cursed);
+	when WS_DRAIN:
+	    /*
+	     * Take away 1/2 of hero's hit points, then take it away
+	     * evenly from the monsters in the room or next to hero
+	     * if he is in a passage (but leave the monsters alone
+	     * if the stick is cursed)
+	     */
+	    if (pstats.s_hpt < 2) {
+		msg("You are too weak to use it.");
+		return(TRUE);
+	    }
+	    if (cursed)
+		pstats.s_hpt /= 2;
+	    else
+		drain(hero.y-1, hero.y+1, hero.x-1, hero.x+1);
+	when WS_POLYMORPH:
+	case WS_TELMON:
+	case WS_CANCEL:
+	{
+	    register char monster, oldch;
+	    register int rm;
+
+	    y = hero.y;
+	    x = hero.x;
+	    while (shoot_ok(winat(y, x))) {
+		y += delta.y;
+		x += delta.x;
+	    }
+	    if (isalpha(monster = CCHAR( mvwinch(mw, y, x) ))) {
+		register struct room *rp;
+
+		item = find_mons(y, x);
+		tp = THINGPTR(item);
+		/* if the monster gets the saving throw, leave the case */
+		if (save(VS_MAGIC, tp, 0)) {
+		    msg(nothing);
+		    break;
+		}
+
+		/* Unhold player */
+		if (on(*tp, DIDHOLD)) {
+		    turn_off(*tp, DIDHOLD);
+		    if (--hold_count == 0) turn_off(player, ISHELD);
+		}
+		/* unsuffocate player */
+		if (on(*tp, DIDSUFFOCATE)) {
+		    turn_off(*tp, DIDSUFFOCATE);
+		    extinguish(suffocate);
+		}
+		rp = roomin(&tp->t_pos);
+		/*
+		 * check to see if room should go dark
+		 */
+		if (on(*tp, HASFIRE)) {
+		    if (rp != NULL) {
+			register struct linked_list *fire_item;
+
+			for (fire_item = rp->r_fires; fire_item != NULL;
+			     fire_item = next(fire_item)) {
+			    if (THINGPTR(fire_item) == tp) {
+				detach(rp->r_fires, fire_item);
+				destroy_item(fire_item);
+				if (rp->r_fires == NULL) {
+				    rp->r_flags &= ~HASFIRE;
+				    if(cansee(tp->t_pos.y,tp->t_pos.x))
+					light(&hero);
+				}
+				break;
+			    }
+			}
+		    }
+		}
+
+		if (which == WS_POLYMORPH) {
+		    register struct linked_list *pitem;
+
+		    delta.x = x;
+		    delta.y = y;
+		    detach(mlist, item);
+		    oldch = tp->t_oldch;
+		    pitem = tp->t_pack; /* save his pack */
+		    tp->t_pack = NULL;
+		    new_monster(item,rnd(NUMMONST-NUMUNIQUE-1)+1,&delta,FALSE);
+		    if (tp->t_pack != NULL) 
+			o_free_list (tp->t_pack);
+		    tp->t_pack = pitem;
+		    monster = tp->t_type;
+		    if (isalpha(mvwinch(cw, y, x)))
+			mvwaddch(cw, y, x, monster);
+		    tp->t_oldch = oldch;
+		    /*
+		     * should the room light up?
+		     */
+		    if (on(*tp, HASFIRE)) {
+			if (rp) {
+			    register struct linked_list *fire_item;
+
+			    fire_item = creat_item();
+			    ldata(fire_item) = (char *) tp;
+			    attach(rp->r_fires, fire_item);
+			    rp->r_flags |= HASFIRE;
+			    if (cansee(tp->t_pos.y,tp->t_pos.x) &&
+				next(rp->r_fires) == NULL) light(&hero);
+			}
+		    }
+		    msg(terse ? "A new %s!" : "You have created a new %s!",
+			monsters[tp->t_index].m_name);
+		}
+		else if (which == WS_CANCEL) {
+		    tp->t_flags[0] &= CANC0MASK;
+		    tp->t_flags[1] &= CANC1MASK;
+		    tp->t_flags[2] &= CANC2MASK;
+		    tp->t_flags[3] &= CANC3MASK;
+		    tp->t_flags[4] &= CANC4MASK;
+		    tp->t_flags[4] &= CANC5MASK;
+		}
+		else { /* A teleport stick */
+		    if (cursed) {	/* Teleport monster to player */
+			if ((y == (hero.y + delta.y)) &&
+			    (x == (hero.x + delta.x)))
+				msg(nothing);
+			else {
+			    tp->t_pos.y = hero.y + delta.y;
+			    tp->t_pos.x = hero.x + delta.x;
+			}
+		    }
+		    else if (blessed) {	/* Get rid of monster */
+			killed(item, FALSE, TRUE);
+			return(TRUE);
+		    }
+		    else {
+			register int i=0;
+
+			do {	/* Move monster to another room */
+			    rm = rnd_room();
+			    rnd_pos(&rooms[rm], &tp->t_pos);
+			}until(winat(tp->t_pos.y,tp->t_pos.x)==FLOOR ||i++>500);
+			rp = &rooms[rm];
+		    }
+
+		    /* Now move the monster */
+		    if (isalpha(mvwinch(cw, y, x)))
+			mvwaddch(cw, y, x, tp->t_oldch);
+		    turn_off(*tp, ISDISGUISE);
+		    mvwaddch(mw, y, x, ' ');
+		    mvwaddch(mw, tp->t_pos.y, tp->t_pos.x, monster);
+		    if (tp->t_pos.y != y || tp->t_pos.x != x)
+			tp->t_oldch = CCHAR( mvwinch(cw, tp->t_pos.y, tp->t_pos.x) );
+		    /*
+		     * check to see if room that creature appears in should
+		     * light up
+		     */
+		    if (on(*tp, HASFIRE)) {
+			register struct linked_list *fire_item;
+
+			fire_item = creat_item();
+			ldata(fire_item) = (char *) tp;
+			attach(rp->r_fires, fire_item);
+			rp->r_flags |= HASFIRE;
+			if(cansee(tp->t_pos.y, tp->t_pos.x) && 
+			   next(rp->r_fires) == NULL)
+			    light(&hero);
+		    }
+		}
+		runto(tp, &hero);
+	    }
+	}
+	when WS_MISSILE:
+	{
+	    static struct object bolt =
+	    {
+		MISSILE , {0, 0}, "", 0, "", "1d4 " , NULL, 0, WS_MISSILE, 50, 1
+	    };
+
+	    sprintf(bolt.o_hurldmg, "%dd4", pstats.s_lvl);
+	    do_motion(&bolt, delta.y, delta.x, &player);
+	    if (!hit_monster(unc(bolt.o_pos), &bolt, &player))
+	       msg("The missile vanishes with a puff of smoke");
+	}
+	when WS_HIT:
+	{
+	    register char ch;
+	    struct object strike; /* don't want to change sticks attributes */
+
+	    delta.y += hero.y;
+	    delta.x += hero.x;
+	    ch = CCHAR( winat(delta.y, delta.x) );
+	    if (isalpha(ch))
+	    {
+		strike = *obj;
+		strike.o_hplus  = 6;
+		if (EQUAL(ws_type[which], "staff"))
+		    strcpy(strike.o_damage,"3d8");
+		else
+		    strcpy(strike.o_damage,"2d8");
+		fight(&delta, &strike, FALSE);
+	    }
+	}
+	case WS_SLOW_M:
+	    y = hero.y;
+	    x = hero.x;
+	    while (shoot_ok(winat(y, x))) {
+		y += delta.y;
+		x += delta.x;
+	    }
+	    if (isalpha(mvwinch(mw, y, x))) {
+		item = find_mons(y, x);
+		tp = THINGPTR(item);
+		runto(tp, &hero);
+		if (on(*tp, ISUNIQUE) && save(VS_MAGIC, tp, 0))
+		    msg(nothing);
+		else if (on(*tp, NOSLOW))
+		    msg(nothing);
+		else if (cursed) {
+		    if (on(*tp, ISSLOW))
+			turn_off(*tp, ISSLOW);
+		    else
+			turn_on(*tp, ISHASTE);
+		}
+		else if (blessed) {
+		    turn_off(*tp, ISRUN);
+		    turn_on(*tp, ISHELD);
+		    return(TRUE);
+		}
+		else {
+		    if (on(*tp, ISHASTE))
+			turn_off(*tp, ISHASTE);
+		    else
+			turn_on(*tp, ISSLOW);
+		    tp->t_turn = TRUE;
+		}
+	    }
+	when WS_CHARGE:
+	    if (ws_know[WS_CHARGE] != TRUE && is_stick)
+		msg("This is a wand of charging.");
+	    if ((nitem = get_item(pack, "charge", STICK)) != NULL) {
+		nobj = OBJPTR(nitem);
+	        if ((++(nobj->o_charges) == 1) && (nobj->o_which == WS_HIT))
+		    fix_stick(nobj);
+	        if (EQUAL(ws_type[nobj->o_which], "staff")) {
+		    if (nobj->o_charges > 100) 
+		        nobj->o_charges = 100;
+		}
+	        else {
+		    if (nobj->o_charges > 50)
+		        nobj->o_charges = 50;
+		}
+	    }
+	when WS_ELECT:
+	case WS_FIRE:
+	case WS_COLD:
+	    {
+		char *name;
+
+		if (which == WS_ELECT)
+		    name = "lightning bolt";
+		else if (which == WS_FIRE)
+		    name = "flame";
+		else
+		    name = "ice";
+
+		shoot_bolt(	&player, hero, 
+				delta, TRUE, D_BOLT, 
+				name, roll(pstats.s_lvl,6));
+	    }
+	when WS_PETRIFY: {
+	    reg int m1, m2, x1, y1;
+	    reg char ch;
+	    reg struct linked_list *ll;
+	    reg struct thing *lt;
+
+	    y1 = hero.y;
+	    x1 = hero.x;
+	    do {
+		y1 += delta.y;
+		x1 += delta.x;
+		ch = CCHAR( winat(y1,x1) );
+	    } while (ch == PASSAGE || ch == FLOOR);
+	    for (m1 = x1 - 1 ; m1 <= x1 + 1 ; m1++) {
+		for(m2 = y1 - 1 ; m2 <= y1 + 1 ; m2++) {
+		    ch = CCHAR( winat(m2,m1) );
+		    if (m1 == hero.x && m2 == hero.y)
+			continue;
+		    if (ch != ' ') {
+			ll = find_obj(m2,m1);
+			if (ll != NULL) {
+			    detach(lvl_obj,ll);
+			    o_discard(ll);
+			}
+			ll = find_mons(m2,m1);
+			if (ll != NULL) {
+			    lt = THINGPTR(ll);
+			    if (on(*lt, ISUNIQUE)) 
+			        monsters[lt->t_index].m_normal = TRUE;
+			    check_residue(lt);
+			    detach(mlist,ll);
+			    t_discard(ll);
+			    mvwaddch(mw,m2,m1,' ');
+			}
+			mvaddch(m2,m1,' ');
+			mvwaddch(cw,m2,m1,' ');
+		    }
+		}
+	    }
+	    touchwin(cw);
+	    touchwin(mw);
+	}
+	when WS_CONFMON:
+	    if (cursed) {
+		if (off(player, ISCLEAR)) {
+		    if (on(player, ISHUH))
+			lengthen(unconfuse, rnd(20)+HUHDURATION);
+		    else {
+			turn_on(player, ISHUH);
+			fuse(unconfuse,0,rnd(20)+HUHDURATION,AFTER);
+			msg("Wait, what's going on here. Huh? What? Who?");
+		    }
+		}
+		else msg("You feel dizzy for a moment, but it quickly passes.");
+	    }
+	    else {
+		y = hero.y;
+		x = hero.x;
+		while (shoot_ok(winat(y, x)))
+		{
+		    y += delta.y;
+		    x += delta.x;
+		}
+		if (isalpha(mvwinch(mw, y, x)))
+		{
+		    item = find_mons(y, x);
+		    tp = THINGPTR(item);
+		    if (save(VS_MAGIC, tp, 0) || on(*tp, ISCLEAR))
+			 msg(nothing);
+		    else
+			 turn_on (*tp, ISHUH);
+		    runto(tp, &hero);
+		}
+	    }
+	when WS_PARALYZE:
+	    if (cursed) {
+		no_command += FREEZETIME;
+		msg("You can't move.");
+	    }
+	    else {
+		y = hero.y;
+		x = hero.x;
+		while (shoot_ok(winat(y, x)))
+		{
+		    y += delta.y;
+		    x += delta.x;
+		}
+		if (isalpha(mvwinch(mw, y, x)))
+		{
+		    item = find_mons(y, x);
+		    tp = THINGPTR(item);
+		    if (save(VS_WAND, tp, 0) || on(*tp, NOPARALYZE))
+			msg(nothing);
+		    else {
+			tp->t_no_move = FREEZETIME;
+		    }
+		    runto(tp, &hero);
+		}
+	    }
+	    when WS_FEAR:
+		y = hero.y;
+		x = hero.x;
+		while (shoot_ok(winat(y, x)))
+		{
+		    y += delta.y;
+		    x += delta.x;
+		}
+		if (isalpha(mvwinch(mw, y, x)))
+		{
+		    item = find_mons(y, x);
+		    tp = THINGPTR(item);
+		    runto(tp, &hero);
+		    if (save(VS_WAND, tp, 0) || 
+			on(*tp, ISUNDEAD)    || 
+			on(*tp, NOFEAR))
+			    msg(nothing);
+		    else {
+			turn_on(*tp, ISFLEE);
+			turn_on(*tp, WASTURNED);
+
+			/* If monster was suffocating, stop it */
+			if (on(*tp, DIDSUFFOCATE)) {
+			    turn_off(*tp, DIDSUFFOCATE);
+			    extinguish(suffocate);
+			}
+
+			/* If monster held us, stop it */
+			if (on(*tp, DIDHOLD) && (--hold_count == 0))
+				turn_off(player, ISHELD);
+			turn_off(*tp, DIDHOLD);
+		    }
+		}
+	when WS_MDEG:
+	    y = hero.y;
+	    x = hero.x;
+	    while (shoot_ok(winat(y, x)))
+	    {
+		y += delta.y;
+		x += delta.x;
+	    }
+	    if (isalpha(mvwinch(mw, y, x)))
+	    {
+		item = find_mons(y, x);
+		tp = THINGPTR(item);
+		if (cursed) {
+		     tp->t_stats.s_hpt *= 2;
+		     msg("The %s appears to be stronger now!", 
+			monsters[tp->t_index].m_name);
+		}
+		else if (on(*tp, ISUNIQUE) && save(VS_WAND, tp, 0))
+		     msg (nothing);
+		else {
+		     tp->t_stats.s_hpt /= 2;
+		     msg("The %s appears to be weaker now", 
+			monsters[tp->t_index].m_name);
+		}
+		runto(tp, &hero);
+	        if (tp->t_stats.s_hpt < 1)
+		     killed(item, TRUE, TRUE);
+	    }
+	when WS_DISINTEGRATE:
+	    y = hero.y;
+	    x = hero.x;
+	    while (shoot_ok(winat(y, x))) {
+		y += delta.y;
+		x += delta.x;
+	    }
+	    if (isalpha(mvwinch(mw, y, x))) {
+		item = find_mons(y, x);
+		tp = THINGPTR(item);
+		turn_on (*tp, ISMEAN);
+		runto(tp, &hero);
+		if (cursed) {
+		    register int m1, m2;
+		    coord mp;
+		    struct linked_list *titem;
+		    char ch;
+		    struct thing *th;
+
+		    if (on(*tp, ISUNIQUE)) {
+			msg (nothing);
+			break;
+		    }
+		    for (m1=tp->t_pos.x-1 ; m1 <= tp->t_pos.x+1 ; m1++) {
+			for(m2=tp->t_pos.y-1 ; m2<=tp->t_pos.y+1 ; m2++) {
+			    ch = CCHAR( winat(m2,m1) );
+			    if (shoot_ok(ch) && ch != PLAYER) {
+				mp.x = m1;	/* create it */
+				mp.y = m2;
+				titem = new_item(sizeof(struct thing));
+				new_monster(titem,(short)tp->t_index,&mp,FALSE);
+				th = THINGPTR(titem);
+				turn_on (*th, ISMEAN);
+				runto(th,&hero);
+				if (on(*th, HASFIRE)) {
+				    register struct room *rp;
+
+				    rp = roomin(&th->t_pos);
+				    if (rp) {
+					register struct linked_list *fire_item;
+
+					fire_item = creat_item();
+					ldata(fire_item) = (char *) th;
+					attach(rp->r_fires, fire_item);
+					rp->r_flags |= HASFIRE;
+					if (cansee(th->t_pos.y, th->t_pos.x) &&
+					    next(rp->r_fires) == NULL)
+					    light(&hero);
+				    }
+				}
+			    }
+			}
+		    }
+		}
+		else { /* if its a UNIQUE it might still live */
+		    tp = THINGPTR(item);
+		    if (on(*tp, ISUNIQUE) && save(VS_MAGIC, tp, 0)) {
+			tp->t_stats.s_hpt /= 2;
+			if (tp->t_stats.s_hpt < 1) {
+			     killed(item, FALSE, TRUE);
+			     msg("You have disintegrated the %s", 
+				    monsters[tp->t_index].m_name);
+			}
+			else {
+			    msg("The %s appears wounded",
+				monsters[tp->t_index].m_name);
+			}
+		    }
+		    else {
+			msg("You have disintegrated the %s", 
+				monsters[tp->t_index].m_name);
+			killed (item, FALSE, TRUE);
+		    }
+		}
+	    }
+	when WS_CURING:
+	    ws_know[WS_CURING] = TRUE;
+	    if (cursed) {
+		if (!save(VS_POISON, &player, 0)) {
+		    msg("You feel extremely sick now");
+		    pstats.s_hpt /=2;
+		    if (pstats.s_hpt == 0) death (D_POISON);
+		}
+		if (!save(VS_WAND, &player, 0) && !ISWEARING(R_HEALTH)) {
+		    turn_on(player, HASDISEASE);
+		    turn_on(player, HASINFEST);
+		    turn_on(player, DOROT);
+		    fuse(cure_disease, 0, roll(HEALTIME,SICKTIME), AFTER);
+		    infest_dam++;
+		}
+		else msg("You fell momentarily sick");
+	    }
+	    else {
+		if (on(player, HASDISEASE)) {
+		    extinguish(cure_disease);
+		    cure_disease();
+		    msg(terse ? "You feel yourself improving."
+			      : "You begin to feel yourself improving again.");
+		}
+		if (on(player, HASINFEST)) {
+		    turn_off(player, HASINFEST);
+		    infest_dam = 0;
+		    msg(terse ? "You feel yourself improving."
+			      : "You begin to feel yourself improving again.");
+		}
+		if (on(player, DOROT)) {
+		    msg("You feel your skin returning to normal.");
+		    turn_off(player, DOROT);
+		}
+		pstats.s_hpt += roll(pstats.s_lvl, blessed ? 6 : 4);
+		if (pstats.s_hpt > max_stats.s_hpt)
+		    pstats.s_hpt = max_stats.s_hpt;
+		msg("You begin to feel %sbetter.", blessed ? "much " : "");
+		    
+	    }
+	otherwise:
+	    msg("What a bizarre schtick!");
+    }
+    return(TRUE);
+}
+
+
+/*
+ * drain:
+ *	Do drain hit points from player shtick
+ */
+
+drain(ymin, ymax, xmin, xmax)
+int ymin, ymax, xmin, xmax;
+{
+    register int i, j, count;
+    register struct thing *ick;
+    register struct linked_list *item;
+
+    /*
+     * First count how many things we need to spread the hit points among
+     */
+    count = 0;
+    for (i = ymin; i <= ymax; i++) {
+	if (i < 1 || i > LINES - 3)
+	    continue;
+	for (j = xmin; j <= xmax; j++) {
+	    if (j < 0 || j > COLS - 1)
+		continue;
+	    if (isalpha(mvwinch(mw, i, j)))
+		count++;
+	}
+    }
+    if (count == 0)
+    {
+	msg("You have a tingling feeling");
+	return;
+    }
+    count = pstats.s_hpt / count;
+    pstats.s_hpt /= 2;
+    /*
+     * Now zot all of the monsters
+     */
+    for (i = ymin; i <= ymax; i++) {
+	if (i < 1 || i > LINES - 3)
+	    continue;
+	for (j = xmin; j <= xmax; j++) {
+	    if (j < 0 || j > COLS - 1)
+		continue;
+	    if (isalpha(mvwinch(mw, i, j)) &&
+	        ((item = find_mons(i, j)) != NULL)) {
+		ick = THINGPTR(item);
+		if (on(*ick, ISUNIQUE) && save(VS_MAGIC, ick, 0)) 
+		    ick->t_stats.s_hpt -= count / 2;
+		else
+		    ick->t_stats.s_hpt -= count;
+		if (ick->t_stats.s_hpt < 1)
+		    killed(item, 
+			   cansee(i,j)&&(!on(*ick,ISINVIS)||on(player,CANSEE)),
+			   TRUE);
+		else {
+		    runto(ick, &hero);
+		    if (cansee(i,j) && (!on(*ick,ISINVIS)||on(player,CANSEE)))
+			    msg("The %s appears wounded",
+				monsters[ick->t_index].m_name);
+		}
+	    }
+	}
+    }
+}
+
+/*
+ * initialize a stick
+ */
+fix_stick(cur)
+register struct object *cur;
+{
+    if (EQUAL(ws_type[cur->o_which], "staff")) {
+	cur->o_weight = 100;
+	cur->o_charges = 5 + rnd(10);
+	strcpy(cur->o_damage,"2d3");
+	cur->o_hplus = 1;
+	cur->o_dplus = 0;
+	switch (cur->o_which) {
+	    case WS_HIT:
+		cur->o_hplus = 3;
+		cur->o_dplus = 3;
+		strcpy(cur->o_damage,"2d8");
+	    when WS_LIGHT:
+		cur->o_charges = 20 + rnd(10);
+	    }
+    }
+    else {
+	strcpy(cur->o_damage,"1d3");
+	cur->o_weight = 60;
+	cur->o_hplus = 1;
+	cur->o_dplus = 0;
+	cur->o_charges = 3 + rnd(5);
+	switch (cur->o_which) {
+	    case WS_HIT:
+		cur->o_hplus = 3;
+		cur->o_dplus = 3;
+		strcpy(cur->o_damage,"1d8");
+	    when WS_LIGHT:
+		cur->o_charges = 10 + rnd(10);
+	    }
+    }
+    strcpy(cur->o_hurldmg,"1d1");
+
+}
+
+/*
+ * shoot_bolt fires a bolt from the given starting point in the
+ * 	      given direction
+ */
+
+shoot_bolt(shooter, start, dir, get_points, reason, name, damage)
+struct thing *shooter;
+coord start, dir;
+bool get_points;
+short reason;
+char *name;
+int damage;
+{
+    register char dirch = 0, ch;
+    register bool used, change;
+    register short y, x, bounces;
+    bool mdead = FALSE;
+    coord pos;
+    struct {
+	coord place;
+	char oldch;
+    } spotpos[BOLT_LENGTH];
+
+    switch (dir.y + dir.x) {
+	case 0: dirch = '/';
+	when 1: case -1: dirch = (dir.y == 0 ? '-' : '|');
+	when 2: case -2: dirch = '\\';
+    }
+    pos.y = start.y + dir.y;
+    pos.x = start.x + dir.x;
+    used = FALSE;
+    change = FALSE;
+
+    bounces = 0;	/* No bounces yet */
+    for (y = 0; y < BOLT_LENGTH && !used; y++)
+    {
+	ch = CCHAR( winat(pos.y, pos.x) );
+	spotpos[y].place = pos;
+	spotpos[y].oldch = CCHAR( mvwinch(cw, pos.y, pos.x) );
+
+	/* Are we at hero? */
+	if (ce(pos, hero)) goto at_hero;
+
+	switch (ch)
+	{
+	    case SECRETDOOR:
+	    case '|':
+	    case '-':
+	    case ' ':
+		if (dirch == '-' || dirch == '|') {
+		    dir.y = -dir.y;
+		    dir.x = -dir.x;
+		}
+		else {
+		    char chx = CCHAR( mvinch(pos.y-dir.y, pos.x) ),
+			 chy = CCHAR( mvinch(pos.y, pos.x-dir.x) );
+		    bool anychange = FALSE; /* Did we change anthing */
+
+		    if (chy == WALL || chy == SECRETDOOR ||
+			chy == '-' || chy == '|') {
+			dir.y = -dir.y;
+			change ^= TRUE;	/* Change at least one direction */
+			anychange = TRUE;
+		    }
+		    if (chx == WALL || chx == SECRETDOOR ||
+			chx == '-' || chx == '|') {
+			dir.x = -dir.x;
+			change ^= TRUE;	/* Change at least one direction */
+			anychange = TRUE;
+		    }
+
+		    /* If we didn't make any change, make both changes */
+		    if (!anychange) {
+			dir.x = -dir.x;
+			dir.y = -dir.y;
+		    }
+		}
+
+		/* Do we change how the bolt looks? */
+		if (change) {
+		    change = FALSE;
+		    if (dirch == '\\') dirch = '/';
+		    else if (dirch == '/') dirch = '\\';
+		}
+
+		y--;	/* The bounce doesn't count as using up the bolt */
+
+		/* Make sure we aren't in an infinite bounce */
+		if (++bounces > BOLT_LENGTH) used = TRUE;
+		msg("The %s bounces", name);
+		break;
+	    default:
+		if (isalpha(ch)) {
+		    register struct linked_list *item;
+		    register struct thing *tp;
+		    register const char *mname;
+		    bool see_monster = cansee(pos.y, pos.x);
+
+		    item = find_mons(unc(pos));
+		    tp = THINGPTR(item);
+		    mname = monsters[tp->t_index].m_name;
+
+		    if (!save(VS_BREATH, tp, -(shooter->t_stats.s_lvl/10))) {
+			if (see_monster) {
+			    if (on(*tp, ISDISGUISE) &&
+				(tp->t_type != tp->t_disguise)) {
+				msg("Wait! That's a %s!", mname);
+				turn_off(*tp, ISDISGUISE);
+			    }
+
+			    sprintf(outstring,"The %s hits the %s", name, mname);
+			    msg(outstring);
+			}
+
+			tp->t_wasshot = TRUE;
+			runto(tp, &hero);
+			used = TRUE;
+
+			/* Hit the monster -- does it do anything? */
+			if ((EQUAL(name,"ice")           &&
+			     (on(*tp, NOCOLD) || on(*tp, ISUNDEAD)))          ||
+			    (EQUAL(name,"flame")         && on(*tp, NOFIRE))  ||
+			    (EQUAL(name,"acid")          && on(*tp, NOACID))  ||
+			    (EQUAL(name,"lightning bolt")&& on(*tp,NOBOLT))   ||
+			    (EQUAL(name,"nerve gas")     &&on(*tp,NOPARALYZE))||
+			    (EQUAL(name,"sleeping gas")  &&
+			     (on(*tp, NOSLEEP) || on(*tp, ISUNDEAD)))         ||
+			    (EQUAL(name,"slow gas")      && on(*tp,NOSLOW))   ||
+			    (EQUAL(name,"fear gas")      && on(*tp,NOFEAR))   ||
+			    (EQUAL(name,"confusion gas") && on(*tp,ISCLEAR))  ||
+			    (EQUAL(name,"chlorine gas")  && on(*tp,NOGAS))) {
+			    if (see_monster){
+				sprintf(outstring,"The %s has no effect on the %s.",
+					name, mname);
+				msg(outstring);
+			    }
+			}
+
+			/* 
+			 * Check for gas with special effects 
+			 */
+			else if (EQUAL(name, "nerve gas")) {
+			    tp->t_no_move = FREEZETIME;
+			}
+			else if (EQUAL(name, "sleeping gas")) {
+			    tp->t_no_move = SLEEPTIME;
+			}
+			else if (EQUAL(name, "slow gas")) {
+			    if (on(*tp, ISHASTE))
+				turn_off(*tp, ISHASTE);
+			    else
+				turn_on(*tp, ISSLOW);
+			    tp->t_turn = TRUE;
+			}
+			else if (EQUAL(name, "fear gas")) {
+			    turn_on(*tp, ISFLEE);
+			    tp->t_dest = &hero;
+			}
+			else if (EQUAL(name, "confusion gas")) {
+			    turn_on(*tp, ISHUH);
+			    tp->t_dest = &hero;
+			}
+			else if ((EQUAL(name, "lightning bolt")) &&
+				 on(*tp, BOLTDIVIDE)) {
+				if (creat_mons(tp, tp->t_index, FALSE)) {
+				  if (see_monster){
+				      sprintf(outstring,"The %s divides the %s.",name,mname);
+				      msg(outstring);
+				  }
+				  light(&hero);
+				}
+				else if (see_monster){
+				    sprintf(outstring,"The %s has no effect on the %s.",
+					name, mname);
+				    msg(outstring);
+				}
+			}
+			else {
+			    if(save(VS_BREATH,tp, -(shooter->t_stats.s_lvl/10)))
+				damage /= 2;
+
+			    /* The poor fellow got killed! */
+			    if ((tp->t_stats.s_hpt -= damage) <= 0) {
+				if (see_monster){
+				    sprintf(outstring,"The %s kills the %s", name, mname);
+				    msg(outstring);
+				}
+				else
+				 msg("You hear a faint groan in the distance");
+				killed(item, FALSE, get_points);
+
+				/* Replace the screen character */
+				spotpos[y].oldch = CCHAR( mvwinch(cw, pos.y, pos.x) );
+
+				mdead = TRUE;
+			    }
+			    else {	/* Not dead, so just scream */
+			         if (!see_monster)
+				     msg("You hear a scream in the distance");
+			    }
+			}
+		    }
+		    else if (isalpha(show(pos.y, pos.x))) {
+			if (see_monster) {
+			    if (terse)
+				msg("%s misses", name);
+			    else {
+				sprintf(outstring,"The %s whizzes past the %s", name, mname);
+				msg(outstring);
+			    }
+			}
+			if (get_points) runto(tp, &hero);
+		    }
+		}
+		else if (pos.y == hero.y && pos.x == hero.x) {
+at_hero: 	    if (!save(VS_BREATH, &player,
+				-(shooter->t_stats.s_lvl/10))){
+			if (terse)
+			    msg("The %s hits you", name);
+			else
+			    msg("You are hit by the %s", name);
+			used = TRUE;
+
+			/* 
+			 * The Amulet of Yendor protects against all "breath" 
+			 *
+			 * The following two if statements could be combined 
+			 * into one, but it makes the compiler barf, so split 
+			 * it up
+			 */
+			if (cur_relic[YENDOR_AMULET]			    ||
+			    (EQUAL(name,"chlorine gas")&&on(player, NOGAS)) ||
+			    (EQUAL(name,"sleeping gas")&&ISWEARING(R_ALERT))){
+			     msg("The %s has no affect", name);
+			}
+			else if((EQUAL(name, "flame") && on(player, NOFIRE)) ||
+			        (EQUAL(name, "ice")   && on(player, NOCOLD)) ||
+			        (EQUAL(name,"fear gas")&&ISWEARING(R_HEROISM))){
+			     msg("The %s has no affect", name);
+			}
+			/* 
+			 * Check for gas with special effects 
+			 */
+			else if (EQUAL(name, "nerve gas")) {
+			    msg("The nerve gas paralyzes you.");
+			    no_command += FREEZETIME;
+			}
+			else if (EQUAL(name, "sleeping gas")) {
+			    msg("The sleeping gas puts you to sleep.");
+			    no_command += SLEEPTIME;
+			}
+			else if (EQUAL(name, "confusion gas")) {
+			    if (off(player, ISCLEAR)) {
+				if (on(player, ISHUH))
+				    lengthen(unconfuse, rnd(20)+HUHDURATION);
+				else {
+				    turn_on(player, ISHUH);
+				    fuse(unconfuse,0,rnd(20)+HUHDURATION,AFTER);
+				    msg("The confusion gas has confused you.");
+				}
+			    }
+			    else msg("You feel dizzy for a moment, but it quickly passes.");
+			}
+			else if (EQUAL(name, "slow gas")) {
+			    add_slow();
+			}
+			else if (EQUAL(name, "fear gas")) {
+			    turn_on(player, ISFLEE);
+			    player.t_dest = &shooter->t_pos;
+			    msg("The fear gas terrifies you.");
+			}
+			else {
+			    if(save(VS_BREATH,&player, -(shooter->t_stats.s_lvl/10)))
+				damage /= 2;
+			    if ((pstats.s_hpt -= damage) <= 0) 
+				death(reason);
+			}
+		    }
+		    else
+			msg("The %s whizzes by you", name);
+		}
+
+		mvwaddch(cw, pos.y, pos.x, dirch);
+		draw(cw);
+	}
+
+	pos.y += dir.y;
+	pos.x += dir.x;
+    }
+    for (x = y - 1; x >= 0; x--)
+	mvwaddch(cw, spotpos[x].place.y, spotpos[x].place.x, spotpos[x].oldch);
+    return(mdead);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/things.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,849 @@
+/*
+ * Contains functions for dealing with things like
+ * potions and scrolls
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include <ctype.h>
+#include "rogue.h"
+
+/*
+ * print out the number of charges on a stick
+ */
+char *
+charge_str(obj)
+register struct object *obj;
+{
+    static char buf[20];
+
+    if (!(obj->o_flags & ISKNOW))
+	buf[0] = '\0';
+    else if (terse)
+	sprintf(buf, " [%d]", obj->o_charges);
+    else
+	sprintf(buf, " [%d charges]", obj->o_charges);
+    return buf;
+}
+/*
+ * inv_name:
+ *	return the name of something as it would appear in an
+ *	inventory.
+ */
+char *
+inv_name(obj, drop)
+register struct object *obj;
+bool drop;
+{
+    register char *pb;
+
+    pb = prbuf;
+    pb[0] = '\0';
+    switch(obj->o_type) {
+	case SCROLL:
+	    if (obj->o_count == 1)
+		 sprintf(pb, "A %sscroll ", blesscurse(obj->o_flags));
+	    else
+		 sprintf(pb, "%d %sscrolls ", 
+			obj->o_count, blesscurse(obj->o_flags));
+	    pb = &pb[strlen(pb)];
+	    if (s_know[obj->o_which] || (obj->o_flags & ISPOST))
+		sprintf(pb, "of %s", s_magic[obj->o_which].mi_name);
+	    else if (s_guess[obj->o_which])
+		sprintf(pb, "called %s", s_guess[obj->o_which]);
+	    else
+		sprintf(pb, "titled '%s'", s_names[obj->o_which]);
+        when POTION:
+	    if (obj->o_count == 1)
+		 sprintf(pb, "A %spotion ", blesscurse(obj->o_flags));
+	    else
+		 sprintf(pb, "%d %spotions ", 
+			obj->o_count, blesscurse(obj->o_flags));
+	    pb = &pb[strlen(pb)];
+	    if (obj->o_flags & ISPOST)
+		sprintf(pb, "of %s", p_magic[obj->o_which].mi_name);
+	    else if (p_know[obj->o_which])
+		sprintf(pb, "of %s (%s)", p_magic[obj->o_which].mi_name,
+		    p_colors[obj->o_which]);
+	    else if (p_guess[obj->o_which])
+		sprintf(pb, "called %s (%s)", p_guess[obj->o_which],
+		    p_colors[obj->o_which]);
+	    else {
+		pb = prbuf;
+		if (obj->o_count == 1)
+		    sprintf(pb, "A%s %s potion",
+			    vowelstr(p_colors[obj->o_which]),
+			    p_colors[obj->o_which]);
+		else
+		    sprintf(pb, "%d %s potions",
+			    obj->o_count, p_colors[obj->o_which]);
+	    }
+	when FOOD:
+	    if (obj->o_which == 1)
+		if (obj->o_count == 1)
+		    sprintf(pb, "A%s %s", vowelstr(fruit), fruit);
+		else
+		    sprintf(pb, "%d %ss", obj->o_count, fruit);
+	    else
+		if (obj->o_count == 1)
+		    strcpy(pb, "Some food");
+		else
+		    sprintf(pb, "%d rations of food", obj->o_count);
+	when WEAPON:
+	    if (obj->o_count > 1)
+		sprintf(pb, "%d ", obj->o_count);
+	    else
+		strcpy(pb, "A ");
+	    pb = &pb[strlen(pb)];
+	    if (obj->o_flags & ISKNOW) {
+		strcat(pb, num(obj->o_hplus, obj->o_dplus));
+		strcat (pb, " ");
+	    }
+	    strcat(pb, weaps[obj->o_which].w_name);
+	    if (obj->o_count > 1)
+		strcat(pb, "s");
+	    if (obj == cur_weapon)
+		strcat(pb, " (weapon in hand)");
+	when ARMOR:
+	    if (obj->o_flags & ISKNOW) {
+		strcat(pb, num(armors[obj->o_which].a_class - obj->o_ac, 0));
+		strcat(pb, " ");
+	    }
+	    strcat(pb, armors[obj->o_which].a_name);
+	    if (obj == cur_armor)
+		strcat(pb, " (being worn)");
+	when STICK:
+	    sprintf(pb, "A %s%s ", 
+		blesscurse(obj->o_flags), ws_type[obj->o_which]);
+	    pb = &pb[strlen(pb)];
+	    if (obj->o_flags & ISPOST)
+		sprintf(pb, "of %s", ws_magic[obj->o_which].mi_name);
+	    else if (ws_know[obj->o_which])
+		sprintf(pb, "of %s%s (%s)", ws_magic[obj->o_which].mi_name,
+		    charge_str(obj), ws_made[obj->o_which]);
+	    else if (ws_guess[obj->o_which])
+		sprintf(pb, "called %s (%s)", ws_guess[obj->o_which],
+		    ws_made[obj->o_which]);
+	    else {
+		pb = prbuf;
+		sprintf(pb, "A %s %s", ws_made[obj->o_which],
+		    ws_type[obj->o_which]);
+	    }
+	    if (obj == cur_weapon)
+		strcat(prbuf, " (weapon in hand)");
+        when RING:
+	    if (obj->o_flags & ISPOST)
+		sprintf(pb, "A ring of %s", r_magic[obj->o_which].mi_name);
+	    else if (r_know[obj->o_which])
+		sprintf(pb, "A%s ring of %s (%s)", ring_num(obj),
+		    r_magic[obj->o_which].mi_name, r_stones[obj->o_which]);
+	    else if (r_guess[obj->o_which])
+		sprintf(pb, "A ring called %s (%s)",
+		    r_guess[obj->o_which], r_stones[obj->o_which]);
+	    else
+		sprintf(pb, "A%s %s ring", vowelstr(r_stones[obj->o_which]),
+		    r_stones[obj->o_which]);
+	    if     (obj == cur_ring[LEFT_1] || obj == cur_ring[LEFT_2] ||
+		    obj == cur_ring[LEFT_3] || obj == cur_ring[LEFT_4])  
+			strcat(pb, " (on left hand)");
+	    if	   (obj == cur_ring[RIGHT_1] || obj == cur_ring[RIGHT_2] ||
+		    obj == cur_ring[RIGHT_3] || obj == cur_ring[RIGHT_4]) 
+			strcat(pb, " (on right hand)");
+	when RELIC:
+	    if (obj->o_flags & ISKNOW)
+		strcpy(pb, rel_magic[obj->o_which].mi_name);
+	    else switch(obj->o_which) {
+		case MUSTY_DAGGER:
+		    strcpy(pb, "Two very fine daggers marked MDDE");
+		when EMORI_CLOAK:
+		    strcpy(pb, "A silk cloak");
+		when HEIL_ANKH:
+		    strcpy(pb, "A golden ankh");
+		when MING_STAFF:
+		    strcpy(pb, "A finely carved staff");
+		when ORCUS_WAND:
+		    strcpy(pb, "A sparkling ivory wand");
+		when ASMO_ROD:
+		    strcpy(pb, "A glistening ebony rod");
+		when YENDOR_AMULET:
+		    strcpy(pb, "A silver amulet");
+		when BRIAN_MANDOLIN:
+		    strcpy(pb, "A gleaming mandolin");
+		when HRUGGEK_MSTAR:
+		    strcpy(pb, "A huge morning star");
+		when GERYON_HORN:
+		    strcpy(pb, "A jet black horn");
+		when YEENOGHU_FLAIL:
+		    strcpy(pb, "A shimmering flail");
+		otherwise:
+		    strcpy(pb, "A magical item");
+	    }
+
+	    /* Take care of wielding and wearing */
+	    switch (obj->o_which) {
+		case EMORI_CLOAK:
+		    if (cur_armor == NULL && cur_misc[WEAR_CLOAK] == NULL)
+			strcat(pb, " (being worn)");
+		when HEIL_ANKH:
+		    if (cur_relic[HEIL_ANKH]) strcat(pb, " (in hand)");
+		when YENDOR_AMULET:
+		    if (cur_relic[YENDOR_AMULET] &&
+			cur_misc[WEAR_JEWEL] == NULL)
+			strcat(pb, " (in chest)");
+		when MUSTY_DAGGER:
+		case HRUGGEK_MSTAR:
+		case YEENOGHU_FLAIL:
+		case MING_STAFF:
+		case ASMO_ROD:
+		case ORCUS_WAND:
+		    if (cur_weapon == obj) strcat(pb, " (weapon in hand)");
+	    }
+	when MM:
+	    if (m_know[obj->o_which])
+			strcpy(pb, misc_name(obj));
+	    else {
+		switch (obj->o_which) {
+		    case MM_JUG:
+		    case MM_BEAKER:
+			strcpy(pb, "A bottle");
+		    when MM_KEOGHTOM:
+			strcpy(pb, "A jar");
+		    when MM_JEWEL:
+			strcpy(pb, "An amulet");
+		    when MM_BOOK:
+		    case MM_SKILLS:
+			strcpy(pb, "A book");
+		    when MM_ELF_BOOTS:
+		    case MM_DANCE:
+			strcpy(pb, "A pair of boots");
+		    when MM_BRACERS:
+			strcpy(pb, "A pair of bracers");
+		    when MM_OPEN:
+		    case MM_HUNGER:
+			strcpy(pb, "A chime");
+		    when MM_DISP:
+		    case MM_R_POWERLESS:
+		    case MM_PROTECT:
+			strcpy(pb, "A cloak");
+		    when MM_DRUMS:
+			strcpy(pb, "A set of drums");
+		    when MM_DISAPPEAR:
+		    case MM_CHOKE:
+			strcpy(pb, "A pouch of dust");
+		    when MM_G_DEXTERITY:
+		    case MM_G_OGRE:
+		    case MM_FUMBLE:
+			strcpy(pb, "A pair of gauntlets");
+		    when MM_ADAPTION:
+		    case MM_STRANGLE:
+			strcpy(pb, "A necklace");
+		    otherwise:
+			strcpy(pb, "A magical item");
+		}
+		if (m_guess[obj->o_which]) {
+		    strcat(pb, " called: ");
+		    strcat(pb, m_guess[obj->o_which]);
+		}
+	    }
+	    if (obj == cur_misc[WEAR_BOOTS]	||
+		obj == cur_misc[WEAR_BRACERS]	||
+		obj == cur_misc[WEAR_CLOAK]	||
+		obj == cur_misc[WEAR_GAUNTLET]	||
+		obj == cur_misc[WEAR_NECKLACE]	||
+		obj == cur_misc[WEAR_JEWEL]) 
+		    strcat(pb, " (being worn)");
+	when GOLD:
+		sprintf(pb, "%d Pieces of Gold", obj->o_count);
+	otherwise:
+	    debug("Picked up something funny");
+	    sprintf(pb, "Something bizarre %s", unctrl(obj->o_type));
+    }
+
+    /* Is it marked? */
+    if (obj->o_mark[0]) {
+	pb = &pb[strlen(pb)];
+	sprintf(pb, " <%s>", obj->o_mark);
+    }
+
+    if (obj->o_flags & ISPROT)
+	strcat(pb, " [protected]");
+    if (drop && isupper(prbuf[0]))
+	prbuf[0] = tolower(prbuf[0]);
+    else if (!drop && islower(*prbuf))
+	*prbuf = toupper(*prbuf);
+    if (!drop)
+	strcat(pb, ".");
+    /* 
+     * Truncate if long. Use COLS-4 to offset the "pack letter" of a normal
+     * inventory listing.
+     */
+    prbuf[COLS-4] = '\0';	
+    return prbuf;
+}
+
+/*
+ * weap_name:
+ *	Return the name of a weapon.
+ */
+char *
+weap_name(obj)
+register struct object *obj;
+{
+    switch (obj->o_type) {
+	case WEAPON:
+	    return(weaps[obj->o_which].w_name);
+	when RELIC:
+	    switch (obj->o_which) {
+		case MUSTY_DAGGER:
+		    return("daggers");
+		when YEENOGHU_FLAIL:
+		    return("flail");
+		when HRUGGEK_MSTAR:
+		    return("morning star");
+		when MING_STAFF:
+		    return("staff");
+		when ORCUS_WAND:
+		    return("wand");
+		when ASMO_ROD:
+		    return("rod");
+	    }
+    }
+    return("weapon");
+}
+
+/*
+ * drop:
+ *	put something down
+ */
+drop(item)
+struct linked_list *item;
+{
+    register char ch = 0;
+    register struct linked_list *obj, *nobj;
+    register struct object *op;
+
+    if (item == NULL) {
+	switch(ch = CCHAR( mvwinch(stdscr, hero.y, hero.x) )) {
+	case PASSAGE: 
+	case SCROLL:
+	case POTION:
+	case WEAPON:
+	case FLOOR:
+	case STICK:
+	case ARMOR:
+	case POOL:
+	case RELIC:
+	case GOLD:
+	case FOOD:
+	case RING:
+	case MM:
+	    break;
+	default:
+	    msg("Can't leave it here");
+	    return(FALSE);
+	}
+	if ((obj = get_item(pack, "drop", ALL)) == NULL)
+	    return(FALSE);
+    }
+    else {
+	obj = item;
+    }
+    op = OBJPTR(obj);
+    if (!dropcheck(op))
+	return(FALSE);
+
+    /*
+     * If it is a scare monster scroll, curse it
+     */
+    if (op->o_type == SCROLL && op->o_which == S_SCARE) {
+	if (op->o_flags & ISBLESSED)
+	    op->o_flags &= ~ISBLESSED;
+	else op->o_flags |= ISCURSED;
+    }
+
+    /*
+     * Take it out of the pack
+     */
+    if (op->o_count >= 2 && op->o_group == 0)
+    {
+	nobj = new_item(sizeof *op);
+	op->o_count--;
+	op = OBJPTR(nobj);
+	*op = *(OBJPTR(obj));
+	op->o_count = 1;
+	obj = nobj;
+    }
+    else {
+	detach(pack, obj);
+        inpack--;
+    }
+    if(ch == POOL) {
+	msg("Your %s sinks out of sight.",inv_name(op,TRUE));
+	o_discard(obj);
+    }
+    else if (levtype == POSTLEV) {
+	op->o_pos = hero;	/* same place as hero */
+	fall(obj,FALSE);
+	if (item == NULL)	/* if item wasn't sold */
+	    msg("Thanks for your donation to the fiend's flea market.");
+    }
+    else {
+	/*
+	 * Link it into the level object list
+	 */
+	attach(lvl_obj, obj);
+	mvaddch(hero.y, hero.x, op->o_type);
+	op->o_pos = hero;
+	msg("Dropped %s", inv_name(op, TRUE));
+    }
+    updpack(FALSE);
+    return (TRUE);
+}
+
+/*
+ * do special checks for dropping or unweilding|unwearing|unringing
+ */
+dropcheck(op)
+register struct object *op;
+{
+    int save_max;
+
+    if (op == NULL)
+	return TRUE;
+    if (levtype == POSTLEV) {
+	if ((op->o_flags & ISCURSED) && (op->o_flags & ISKNOW)) {
+	    msg("The trader does not accept your shoddy merchandise");
+	    return(FALSE);
+	}
+    }
+
+    /* Player will not drop a relic */
+    if (op->o_type == RELIC) {
+	/*
+	 * There is a 1% cumulative chance per relic that trying to get
+	 * rid of it will cause the relic to turn on the player.
+	 */
+	if (rnd(100) < cur_relic[op->o_which]++) {
+	    msg("The artifact turns on you.");
+	    msg("It crushes your mind!!! -- More --");
+	    pstats.s_hpt = -1;
+	    wait_for (cw,' ');
+	    death(D_RELIC);
+	}
+	else {
+	    if (terse) msg("Can't release it.");
+	    else msg("You cannot bring yourself to release it.");
+	    return FALSE;
+	}
+    }
+
+    /* If we aren't wearing it, we can drop it */
+    if (!is_current(op)) return TRUE;
+
+    /* At this point, we know we are wearing the item */
+    if (op->o_flags & ISCURSED) {
+	msg("You can't.  It appears to be cursed.");
+	return FALSE;
+    }
+    if (op == cur_armor) {
+	waste_time();
+    }
+    else if (op->o_type == RING) {
+	if (cur_misc[WEAR_GAUNTLET] != NULL) {
+	    msg ("You have to remove your gauntlets first!");
+	    return FALSE;
+	}
+
+	switch (op->o_which) {
+	case R_ADDSTR:    save_max = max_stats.s_str;
+			  chg_str(-op->o_ac);
+			  max_stats.s_str = save_max;
+	when R_ADDHIT:    pstats.s_dext -= op->o_ac;
+	when R_ADDINTEL:  pstats.s_intel -= op->o_ac;
+	when R_ADDWISDOM: pstats.s_wisdom -= op->o_ac;
+	when R_SEEINVIS:  if (find_slot(unsee) == 0) {
+				turn_off(player, CANSEE);
+				msg("The tingling feeling leaves your eyes");
+			  }
+			  light(&hero);
+			  mvwaddch(cw, hero.y, hero.x, PLAYER);
+	when R_WARMTH:    turn_off(player, NOCOLD);
+	when R_FIRE:   	  turn_off(player, NOFIRE);
+	when R_LIGHT: {
+			  if(roomin(&hero) != NULL) {
+				light(&hero);
+				mvwaddch(cw, hero.y, hero.x, PLAYER);
+			  }
+		      }
+	when R_SEARCH:    kill_daemon(ring_search);
+	when R_TELEPORT:  kill_daemon(ring_teleport);
+	}
+    }
+    else if (op->o_type == MM) {
+	switch (op->o_which) {
+	    case MM_ADAPTION:
+		turn_off(player, NOGAS);
+
+	    when MM_STRANGLE:
+		msg("You can breathe again.....whew!");
+		kill_daemon(strangle);
+
+	    when MM_DANCE:
+		turn_off(player, ISDANCE);
+		msg ("Your feet take a break.....whew!");
+
+	    when MM_FUMBLE:
+		kill_daemon(fumble);
+	}
+    }
+    cur_null(op);	/* set current to NULL */
+    return TRUE;
+}
+
+/*
+ * return a new thing
+ */
+struct linked_list *
+new_thing(thing_type)
+int thing_type;
+{
+    register struct linked_list *item;
+    register struct object *cur;
+    register int j, k;
+    register int blesschance, cursechance;
+
+    item = new_item(sizeof *cur);
+    cur = OBJPTR(item);
+    cur->o_hplus = cur->o_dplus = 0;
+    strcpy(cur->o_damage,"0d0");
+    strcpy(cur->o_hurldmg,"0d0");
+    cur->o_ac = 0;
+    cur->o_count = 1;
+    cur->o_group = 0;
+    cur->contents = NULL;
+    cur->o_flags = 0;
+    cur->o_weight = 0;
+    cur->o_mark[0] = '\0';
+    /*
+     * Decide what kind of object it will be
+     * If we haven't had food for a while, let it be food.
+     */
+    blesschance = rnd(100);
+    cursechance = rnd(100);
+
+    /* Get the type of item (pick one if 'any' is specified) */
+    if (thing_type == ALL) j = pick_one(things, NUMTHINGS);
+    else j = thing_type;
+
+    /* 
+     * make sure he gets his vitamins 
+     */
+    if (thing_type == ALL && no_food > 3)
+	j = 2;	
+    /*
+     * limit the number of foods on a level because it sometimes
+     * gets out of hand in the "deep" levels where there is a 
+     * treasure room on most every level with lots of food in it
+     */
+    while (thing_type == ALL && levtype != POSTLEV && foods_this_level > 2 &&
+	   j == 2)
+	j = pick_one(things, NUMTHINGS);	/* not too many.... */
+    switch (j)
+    {
+	case TYP_POTION:
+	    cur->o_type = POTION;
+	    cur->o_which = pick_one(p_magic, MAXPOTIONS);
+	    cur->o_weight = things[TYP_POTION].mi_wght;
+	    if (cursechance < p_magic[cur->o_which].mi_curse)
+		cur->o_flags |= ISCURSED;
+	    else if (blesschance < p_magic[cur->o_which].mi_bless)
+		cur->o_flags |= ISBLESSED;
+	when TYP_SCROLL:
+	    cur->o_type = SCROLL;
+	    cur->o_which = pick_one(s_magic, MAXSCROLLS);
+	    cur->o_weight = things[TYP_SCROLL].mi_wght;
+	    if (cursechance < s_magic[cur->o_which].mi_curse)
+		cur->o_flags |= ISCURSED;
+	    else if (blesschance < s_magic[cur->o_which].mi_bless)
+		cur->o_flags |= ISBLESSED;
+	when TYP_FOOD:
+	    no_food = 0;
+	    cur->o_type = FOOD;
+	    cur->o_weight = things[TYP_FOOD].mi_wght;
+	    cur->o_count += extras();
+	    foods_this_level += cur->o_count;
+	    if (rnd(100) > 10)
+		cur->o_which = 0;
+	    else
+		cur->o_which = 1;
+	when TYP_WEAPON:
+	    cur->o_type = WEAPON;
+	    cur->o_which = rnd(MAXWEAPONS);
+	    init_weapon(cur, cur->o_which);
+	    if (cursechance < 20)
+	    {
+
+		cur->o_flags |= ISCURSED;
+		cur->o_hplus -= rnd(2) + 1;
+		cur->o_dplus -= rnd(2) + 1;
+	    }
+	    else if (blesschance < 50) {
+
+		cur->o_hplus += rnd(5) + 1;
+		cur->o_dplus += rnd(5) + 1;
+	    }
+	when TYP_ARMOR:
+	    cur->o_type = ARMOR;
+	    for (j = 0; j < MAXARMORS; j++)
+		if (blesschance < armors[j].a_prob)
+		    break;
+	    if (j == MAXARMORS)
+	    {
+		debug("Picked a bad armor %d", blesschance);
+		j = 0;
+	    }
+	    cur->o_which = j;
+	    cur->o_ac = armors[j].a_class;
+	    cur->o_weight = armors[j].a_wght;
+	    if ((k = rnd(100)) < 20)
+	    {
+		cur->o_flags |= ISCURSED;
+		cur->o_ac += rnd(3)+1;
+	    }
+	    else if (k < 35)
+		cur->o_ac -= rnd(3)+1;
+	when TYP_RING:
+	    cur->o_type = RING;
+	    cur->o_which = pick_one(r_magic, MAXRINGS);
+	    cur->o_weight = things[TYP_RING].mi_wght;
+	    if (cursechance < r_magic[cur->o_which].mi_curse)
+		cur->o_flags |= ISCURSED;
+	    else if (blesschance < r_magic[cur->o_which].mi_bless)
+		cur->o_flags |= ISBLESSED;
+	    switch (cur->o_which)
+	    {
+		case R_ADDSTR:
+		case R_ADDWISDOM:
+		case R_ADDINTEL:
+		case R_PROTECT:
+		case R_ADDHIT:
+		case R_ADDDAM:
+		    cur->o_ac = rnd(2) + 1;	/* From 1 to 3 */
+		    if (cur->o_flags & ISCURSED)
+			cur->o_ac = -cur->o_ac;
+		    if (cur->o_flags & ISBLESSED) cur->o_ac++;
+		when R_DIGEST:
+		    if (cur->o_flags & ISCURSED) cur->o_ac = -1;
+		    else if (cur->o_flags & ISBLESSED) cur->o_ac = 2;
+		    else cur->o_ac = 1;
+	    }
+	when TYP_STICK:
+	    cur->o_type = STICK;
+	    cur->o_which = pick_one(ws_magic, MAXSTICKS);
+	    fix_stick(cur);
+	    if (cursechance < ws_magic[cur->o_which].mi_curse)
+		cur->o_flags |= ISCURSED;
+	    else if (blesschance < ws_magic[cur->o_which].mi_bless)
+		cur->o_flags |= ISBLESSED;
+	when TYP_MM:
+	    cur->o_type = MM;
+	    cur->o_which = pick_one(m_magic, MAXMM);
+	    cur->o_weight = things[TYP_MM].mi_wght;
+	    if (cursechance < m_magic[cur->o_which].mi_curse)
+		cur->o_flags |= ISCURSED;
+	    else if (blesschance < m_magic[cur->o_which].mi_bless)
+		cur->o_flags |= ISBLESSED;
+	    switch (cur->o_which) {
+		case MM_JUG:
+		    switch(rnd(7)) {
+			case 0: cur->o_ac = P_PHASE;
+			when 1: cur->o_ac = P_CLEAR;
+			when 2: cur->o_ac = P_SEEINVIS;
+			when 3: cur->o_ac = P_HEALING;
+			when 4: cur->o_ac = P_MFIND;
+			when 5: cur->o_ac = P_TFIND;
+			when 6: cur->o_ac = P_HASTE;
+			when 7: cur->o_ac = P_RESTORE;
+		    }
+		when MM_OPEN:
+		case MM_HUNGER:
+		case MM_DRUMS:
+		case MM_DISAPPEAR:
+		case MM_CHOKE:
+		case MM_KEOGHTOM:
+		    cur->o_ac = 3 + (rnd(3)+1) * 3;
+		when MM_BRACERS:
+		    if (cur->o_flags & ISCURSED) 
+			cur->o_ac = -(rnd(3)+1);
+		    else
+			cur->o_ac = rnd(8)+1;
+		when MM_PROTECT:
+		    if (cur->o_flags & ISCURSED) 
+		    	cur->o_ac = -(rnd(3)+1);
+		    else
+			cur->o_ac = rnd(5)+1;
+		when MM_DISP:
+		    cur->o_ac = 2;
+		when MM_SKILLS:
+		    cur->o_ac = rnd(4);	/*  set it to some character class */
+		otherwise:
+		    cur->o_ac = 0;
+	    }
+	otherwise:
+	    debug("Picked a bad kind of object");
+	    wait_for(msg,' ');
+    }
+    return item;
+}
+
+/*
+ * provide a new item tailored to specification
+ */
+struct linked_list *
+spec_item(type, which, hit, damage)
+int type, which, hit, damage;
+{
+    register struct linked_list *item;
+    register struct object *obj;
+
+    item = new_item(sizeof *obj);
+    obj = OBJPTR(item);
+    obj->o_count = 1;
+    obj->o_group = 0;
+    obj->contents = NULL;
+    obj->o_type = type;
+    obj->o_which = which;
+    strcpy(obj->o_damage,"0d0");
+    strcpy(obj->o_hurldmg,"0d0");
+    obj->o_hplus = 0;
+    obj->o_dplus = 0;
+    obj->o_flags = 0;
+    obj->o_mark[0] = '\0';
+    obj->o_text = NULL;
+    obj->o_launch = 0;
+    obj->o_weight = 0;
+
+    /* Handle special characteristics */
+    switch (type) {
+	case WEAPON:
+	    init_weapon(obj, which);
+	    obj->o_hplus = hit;
+	    obj->o_dplus = damage;
+	    obj->o_ac = 10;
+
+	    if (hit > 0 || damage > 0) obj->o_flags |= ISBLESSED;
+	    else if (hit < 0 || damage < 0) obj->o_flags |= ISCURSED;
+
+	when ARMOR:
+	    obj->o_ac = armors[which].a_class - hit;
+	    if (hit > 0) obj->o_flags |= ISBLESSED;
+	    else if (hit < 0) obj->o_flags |= ISCURSED;
+
+	when RING:
+	    obj->o_ac = hit;
+	    switch (obj->o_which) {
+		case R_ADDSTR:
+		case R_ADDWISDOM:
+		case R_ADDINTEL:
+		case R_PROTECT:
+		case R_ADDHIT:
+		case R_ADDDAM:
+		case R_DIGEST:
+		    if (hit > 1) obj->o_flags |= ISBLESSED;
+		    else if (hit < 0) obj->o_flags |= ISCURSED;
+	    }
+
+	when STICK:
+	    fix_stick(obj);
+	    obj->o_charges = hit;
+
+	when GOLD:
+	    obj->o_type = GOLD;
+	    obj->o_count = GOLDCALC;
+	    obj->o_ac = 11;
+	
+	when MM:
+	    obj->o_type = MM;
+	    obj->o_ac = hit;
+
+	when RELIC:
+	    /* Handle weight here since these are all created uniquely */
+	    obj->o_weight = things[TYP_RELIC].mi_wght;
+
+    }
+    return(item);
+}
+
+/*
+ * pick an item out of a list of nitems possible magic items
+ */
+pick_one(magic, nitems)
+register struct magic_item *magic;
+int nitems;
+{
+    register struct magic_item *end;
+    register int i;
+    register struct magic_item *start;
+
+    start = magic;
+    for (end = &magic[nitems], i = rnd(1000); magic < end; magic++)
+	if (i < magic->mi_prob)
+	    break;
+    if (magic == end)
+    {
+	if (wizard)
+	{
+	    sprintf(outstring,"bad pick_one: %d from %d items", i, nitems);
+	    msg(outstring);
+	    for (magic = start; magic < end; magic++){
+		sprintf(outstring,"%s: %d%%", magic->mi_name, magic->mi_prob);
+		msg(outstring);
+	    }
+	}
+	magic = start;
+    }
+    return (int)(magic - start);
+}
+
+
+/* blesscurse returns whether, according to the flag, the object is
+ * blessed, cursed, or neither
+ */
+
+char *
+blesscurse(flags)
+int flags;
+{
+    if (flags & ISKNOW)  {
+	if (flags & ISCURSED) return("cursed ");
+	if (flags & ISBLESSED) return("blessed ");
+	return("normal ");
+    }
+    return("");
+}
+
+/*
+ * extras:
+ *	Return the number of extra items to be created
+ */
+extras()
+{
+	reg int i;
+
+	i = rnd(100);
+	if (i < 4)		/* 4% for 2 more */
+	    return (2);
+	else if (i < 11)	/* 7% for 1 more */
+	    return (1);
+	else			/* otherwise no more */
+	    return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/trader.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,336 @@
+/*
+ * Anything to do with trading posts
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Super-Rogue"
+ * Copyright (C) 1984 Robert D. Kindelberger
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include "rogue.h"
+
+
+
+
+
+/*
+ * buy_it:
+ *	Buy the item on which the hero stands
+ */
+buy_it()
+{
+	reg int wh;
+	struct linked_list *item;
+
+	if (purse <= 0) {
+	    msg("You have no money.");
+	    return;
+	}
+	if (curprice < 0) {		/* if not yet priced */
+	    wh = price_it();
+	    if (!wh)			/* nothing to price */
+		return;
+	    msg("Do you want to buy it? ");
+	    do {
+		wh = tolower(readchar());
+		if (wh == ESCAPE || wh == 'n') {
+		    msg("");
+		    return;
+		}
+	    } until(wh == 'y');
+	}
+	mpos = 0;
+	if (curprice > purse) {
+	    msg("You can't afford to buy that %s !",curpurch);
+	    return;
+	}
+	/*
+	 * See if the hero has done all his transacting
+	 */
+	if (!open_market())
+	    return;
+	/*
+	 * The hero bought the item here
+	 */
+	item = find_obj(hero.y, hero.x);
+	mpos = 0;
+	if (add_pack(NULL,TRUE,&item)) {	/* try to put it in his pack */
+	    purse -= curprice;		/* take his money */
+	    ++trader;			/* another transaction */
+	    trans_line();		/* show remaining deals */
+	    curprice = -1;		/* reset stuff */
+	    curpurch[0] = 0;
+	    whatis (item);		/* identify it after purchase */
+	    (OBJPTR(item))->o_flags &= ~ISPOST; /* turn off ISPOST */
+	    msg("%s", inv_name(OBJPTR(item), TRUE));
+	}
+}
+
+/*
+ * do_post:
+ *	Put a trading post room and stuff on the screen
+ */
+do_post()
+{
+	coord tp;
+	reg int i;
+	reg struct room *rp;
+	reg struct object *op;
+	reg struct linked_list *ll;
+
+	o_free_list(lvl_obj);		/* throw old items away */
+
+	for (rp = rooms; rp < &rooms[MAXROOMS]; rp++)
+	    rp->r_flags = ISGONE;		/* kill all rooms */
+
+	rp = &rooms[0];				/* point to only room */
+	rp->r_flags = 0;			/* this room NOT gone */
+	rp->r_max.x = 40;
+	rp->r_max.y = 10;			/* 10 * 40 room */
+	rp->r_pos.x = (COLS - rp->r_max.x) / 2;	/* center horizontal */
+	rp->r_pos.y = 1;			/* 2nd line */
+	draw_room(rp);				/* draw the only room */
+	i = roll(4,10);				/* 10 to 40 items */
+	for (; i > 0 ; i--) {			/* place all the items */
+	    ll = new_thing(ALL);		/* get something */
+	    attach(lvl_obj, ll);
+	    op = OBJPTR(ll);
+	    op->o_flags |= ISPOST;		/* object in trading post */
+	    do {
+		rnd_pos(rp,&tp);
+	    } until (mvinch(tp.y, tp.x) == FLOOR);
+	    op->o_pos = tp;
+	    mvaddch(tp.y,tp.x,op->o_type);
+	}
+	trader = 0;
+	wmove(cw,12,0);
+	waddstr(cw,"Welcome to Friendly Fiend's Flea Market\n\r");
+	waddstr(cw,"=======================================\n\r");
+	waddstr(cw,"$: Prices object that you stand upon.\n\r");
+	waddstr(cw,"#: Buys the object that you stand upon.\n\r");
+	waddstr(cw,"%: Trades in something in your pack for gold.\n\r");
+	trans_line();
+}
+
+
+/*
+ * get_worth:
+ *	Calculate an objects worth in gold
+ */
+get_worth(obj)
+reg struct object *obj;
+{
+	reg int worth, wh;
+
+	worth = 0;
+	wh = obj->o_which;
+	switch (obj->o_type) {
+	    case FOOD:
+		worth = 2;
+	    when WEAPON:
+		if (wh < MAXWEAPONS) {
+		    worth = weaps[wh].w_worth;
+		    worth += s_magic[S_ALLENCH].mi_worth * 
+		   		 (obj->o_hplus + obj->o_dplus);
+		}
+	    when ARMOR:
+		if (wh < MAXARMORS) {
+		    worth = armors[wh].a_worth;
+		    worth += s_magic[S_ALLENCH].mi_worth * 
+				(armors[wh].a_class - obj->o_ac);
+		}
+	    when SCROLL:
+		if (wh < MAXSCROLLS)
+		    worth = s_magic[wh].mi_worth;
+	    when POTION:
+		if (wh < MAXPOTIONS)
+		    worth = p_magic[wh].mi_worth;
+	    when RING:
+		if (wh < MAXRINGS) {
+		    worth = r_magic[wh].mi_worth;
+		    worth += obj->o_ac * 40;
+		}
+	    when STICK:
+		if (wh < MAXSTICKS) {
+		    worth = ws_magic[wh].mi_worth;
+		    worth += 20 * obj->o_charges;
+		}
+	    when MM:
+		if (wh < MAXMM) {
+		    worth = m_magic[wh].mi_worth;
+		    switch (wh) {
+			case MM_BRACERS:	worth += 40  * obj->o_ac;
+			when MM_PROTECT:	worth += 60  * obj->o_ac;
+			when MM_DISP:		/* ac already figured in price*/
+			otherwise:		worth += 20  * obj->o_ac;
+		    }
+		}
+	    when RELIC:
+		if (wh < MAXRELIC) {
+		    worth = rel_magic[wh].mi_worth;
+		    if (wh == quest_item) worth *= 10;
+		}
+	    otherwise:
+		worth = 0;
+	}
+	if (obj->o_flags & ISPROT)	/* 300% more for protected */
+	    worth *= 3;
+	if (obj->o_flags &  ISBLESSED)	/* 50% more for blessed */
+	    worth = worth * 3 / 2;
+	if (obj->o_flags & ISCURSED)	/* half for cursed */
+	    worth /= 2;
+	if (worth < 0)
+	    worth = 0;
+	return worth;
+}
+
+/*
+ * open_market:
+ *	Retruns TRUE when ok do to transacting
+ */
+open_market()
+{
+	if (trader >= MAXPURCH && !wizard) {
+	    msg("The market is closed. The stairs are that-a-way.");
+	    return FALSE;
+	}
+	else {
+	    return TRUE;
+	}
+}
+
+/*
+ * price_it:
+ *	Price the object that the hero stands on
+ */
+price_it()
+{
+	reg struct linked_list *item;
+	reg struct object *obj;
+	reg int worth;
+	reg char *str;
+
+	if (!open_market())		/* after buying hours */
+	    return FALSE;
+	if ((item = find_obj(hero.y,hero.x)) == NULL)
+	    return FALSE;
+	obj = OBJPTR(item);
+	worth = get_worth(obj);
+	if (worth < 0) {
+	    msg("That's not for sale.");
+	    return FALSE;
+	}
+	if (worth < 25)
+	    worth = 25;
+	worth *= 3;			/* slightly expensive */
+	str = inv_name(obj, TRUE);
+	sprintf(outstring,"%s for only %d pieces of gold", str, worth);
+	msg(outstring);
+	curprice = worth;		/* save price */
+	strcpy(curpurch,str);		/* save item */
+	return TRUE;
+}
+
+
+
+/*
+ * sell_it:
+ *	Sell an item to the trading post
+ */
+sell_it()
+{
+	reg struct linked_list *item;
+	reg struct object *obj;
+	reg int wo, ch;
+
+	if (!open_market())		/* after selling hours */
+	    return;
+
+	if ((item = get_item(pack, "sell", ALL)) == NULL)
+	    return;
+	obj = OBJPTR(item);
+	wo = get_worth(obj);
+	if (wo <= 0) {
+	    mpos = 0;
+	    msg("We don't buy those.");
+	    return;
+	}
+	if (wo < 25)
+	    wo = 25;
+	sprintf(outstring,"Your %s is worth %d pieces of gold.",typ_name(obj),wo);
+	msg(outstring);
+	msg("Do you want to sell it? ");
+	do {
+	    ch = tolower(readchar());
+	    if (ch == ESCAPE || ch == 'n') {
+		msg("");
+		return;
+	    }
+	} until (ch == 'y');
+	mpos = 0;
+	if (drop(item) == TRUE) {		/* drop this item */	
+	    purse += wo;			/* give him his money */
+	    ++trader;				/* another transaction */
+	    wo = obj->o_count;
+	    if (obj->o_group == 0) 		/* dropped one at a time */
+		obj->o_count = 1;
+	    msg("Sold %s",inv_name(obj,TRUE));
+	    obj->o_count = wo;
+	    trans_line();			/* show remaining deals */
+	}
+}
+
+/*
+ * trans_line:
+ *	Show how many transactions the hero has left
+ */
+trans_line()
+{
+	if (!wizard)
+	    sprintf(prbuf,"You have %d transactions remaining.",
+		    MAXPURCH - trader);
+	else
+	    sprintf(prbuf,
+		"You have infinite transactions remaining oh great wizard");
+	mvwaddstr(cw,LINES - 3,0,prbuf);
+}
+
+
+
+/*
+ * typ_name:
+ * 	Return the name for this type of object
+ */
+char *
+typ_name(obj)
+reg struct object *obj;
+{
+	static char buff[20];
+	reg int wh;
+
+	switch (obj->o_type) {
+		case POTION:  wh = TYP_POTION;
+		when SCROLL:  wh = TYP_SCROLL;
+		when STICK:   wh = TYP_STICK;
+		when RING:    wh = TYP_RING;
+		when ARMOR:   wh = TYP_ARMOR;
+		when WEAPON:  wh = TYP_WEAPON;
+		when MM:      wh = TYP_MM;
+		when FOOD:    wh = TYP_FOOD;
+		when RELIC:   wh = TYP_RELIC;
+		otherwise:    wh = -1;
+	}
+	if (wh < 0)
+		strcpy(buff,"unknown");
+	else
+		strcpy(buff,things[wh].mi_name);
+	return (buff);
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/util.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,921 @@
+/*
+ * all sorts of miscellaneous routines
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include "rogue.h"
+#include <ctype.h>
+
+/*
+ * aggravate:
+ *	aggravate all the monsters on this level
+ */
+
+aggravate()
+{
+    register struct linked_list *mi;
+
+    for (mi = mlist; mi != NULL; mi = next(mi))
+	runto(THINGPTR(mi), &hero);
+}
+
+/*
+ * cansee:
+ *	returns true if the hero can see a certain coordinate.
+ */
+
+cansee(y, x)
+register int y, x;
+{
+    register struct room *rer;
+    register int radius;
+    coord tp;
+
+    if (on(player, ISBLIND))
+	return FALSE;
+
+    tp.y = y;
+    tp.x = x;
+    rer = roomin(&tp);
+
+    /* How far can we see? */
+    if (levtype == OUTSIDE) {
+	if (daytime) radius = 36;
+	else if (lit_room(rer)) radius = 9;
+	else radius = 3;
+    }
+    else radius = 3;
+
+    /*
+     * We can only see if the hero in the same room as
+     * the coordinate and the room is lit or if it is close.
+     */
+    return ((rer != NULL && 
+	     levtype != OUTSIDE &&
+	     (levtype != MAZELEV ||	/* Maze level needs direct line */
+	      maze_view(tp.y, tp.x)) &&
+	     rer == roomin(&hero) &&
+	     lit_room(rer)) ||
+	    DISTANCE(y, x, hero.y, hero.x) < radius);
+}
+
+/*
+ * check_level:
+ *	Check to see if the guy has gone up a level.
+ *
+ *	Return points needed to obtain next level.
+ *
+ * These are the beginning experience levels for all players.
+ * All further experience levels are computed by muliplying by 2
+ * up through MAXDOUBLE.
+ */
+#define MAXDOUBLE 14	/* Maximum number of times score is doubled */
+static struct {
+    long base;	/* What it starts out at for doubling */
+    long cap;	/* The maximum before doubling stops */
+} e_levels[4] = {
+	/* You must change MAXDOUBLE if you change the cap figure */
+	{ 90L,	1474560L },	/* Fighter */
+	{ 130L,	2129920L }, 	/* Magician */
+	{ 110L, 1802240L },	/* cleric */
+	{ 75L,	1228800L }	/* Thief */
+};
+
+long
+check_level(get_spells)
+bool get_spells;
+{
+    register int i, j, add = 0;
+    register unsigned long exp;
+    long retval;	/* Return value */
+    int nsides = 0;
+
+    /* See if we are past the doubling stage */
+    exp = e_levels[player.t_ctype].cap;
+    if (pstats.s_exp >= exp) {
+	i = pstats.s_exp/exp;	/* First get amount above doubling area */
+	retval = exp + i * exp; /* Compute next higher boundary */
+	i += MAXDOUBLE;	/* Add in the previous doubled levels */
+    }
+    else {
+	i = 0;
+	exp = e_levels[player.t_ctype].base;
+	while (exp <= pstats.s_exp) {
+	    i++;
+	    exp <<= 1;
+	}
+	retval = exp;
+    }
+    if (++i > pstats.s_lvl) {
+	switch (player.t_ctype) {
+	    case C_FIGHTER:	nsides = 10;
+	    when C_MAGICIAN:	nsides = 4;
+	    when C_CLERIC:	nsides = 8;
+	    when C_THIEF:	nsides = 6;
+	}
+
+	/* Take care of multi-level jumps */
+	for (j=0; j < (i-pstats.s_lvl); j++)
+	    add += max(1, roll(1,nsides) + const_bonus());
+	max_stats.s_hpt += add;
+	if ((pstats.s_hpt += add) > max_stats.s_hpt)
+	    pstats.s_hpt = max_stats.s_hpt;
+	sprintf(outstring,"Welcome, %s, to level %d",
+	    cnames[player.t_ctype][min(i-1, 10)], i);
+	msg(outstring);
+	if (get_spells) {
+	    pray_time = 0;	/* A new round of prayers */
+	    spell_power = 0; /* A new round of spells */
+	}
+    }
+    pstats.s_lvl = i;
+    return(retval);
+}
+
+/*
+ * Used to modify the playes strength
+ * it keeps track of the highest it has been, just in case
+ */
+
+chg_str(amt)
+register int amt;
+{
+    register int ring_str;		/* ring strengths */
+    register struct stats *ptr;		/* for speed */
+
+    ptr = &pstats;
+    ring_str = ring_value(R_ADDSTR);
+    ptr->s_str -= ring_str;
+    ptr->s_str += amt;
+    if (ptr->s_str > 25)
+	ptr->s_str = 25;
+    if (ptr->s_str > max_stats.s_str)
+	max_stats.s_str = ptr->s_str;
+    ptr->s_str += ring_str;
+    if (ptr->s_str <= 0)
+	death(D_STRENGTH);
+    updpack(TRUE);
+}
+
+/*
+ * this routine computes the players current AC without dex bonus's
+ */
+int 
+ac_compute()
+{
+    register int ac;
+
+    ac  = cur_armor != NULL ? cur_armor->o_ac : pstats.s_arm;
+    ac -= ring_value(R_PROTECT);
+    if (cur_misc[WEAR_BRACERS] != NULL)
+	ac -= cur_misc[WEAR_BRACERS]->o_ac;
+    if (cur_misc[WEAR_CLOAK] != NULL)
+	ac -= cur_misc[WEAR_CLOAK]->o_ac;
+
+    /* If player has the cloak, must be wearing it */
+    if (cur_relic[EMORI_CLOAK]) ac -= 5;
+
+    if (ac > 10)
+	ac = 10;
+    return(ac);
+}
+
+/*
+ * this routine computes the players current strength
+ */
+str_compute()
+{
+    if (cur_misc[WEAR_GAUNTLET] != NULL		&&
+	cur_misc[WEAR_GAUNTLET]->o_which == MM_G_OGRE) {
+	if (cur_misc[WEAR_GAUNTLET]->o_flags & ISCURSED)
+	    return (3);
+	else
+	    return (18);
+    }
+    else
+	    return (pstats.s_str);
+}
+
+/*
+ * this routine computes the players current dexterity
+ */
+dex_compute()
+{
+    if (cur_misc[WEAR_GAUNTLET] != NULL		&&
+	cur_misc[WEAR_GAUNTLET]->o_which == MM_G_DEXTERITY) {
+	if (cur_misc[WEAR_GAUNTLET]->o_flags & ISCURSED)
+	    return (3);
+	else
+	    return (18);
+    }
+    else
+	    return (pstats.s_dext);
+}
+    
+
+/*
+ * diag_ok:
+ *	Check to see if the move is legal if it is diagonal
+ */
+
+diag_ok(sp, ep, flgptr)
+register coord *sp, *ep;
+struct thing *flgptr;
+{
+    register int numpaths = 0;
+
+    /* Horizontal and vertical moves are always ok */
+    if (ep->x == sp->x || ep->y == sp->y)
+	return TRUE;
+
+    /* Diagonal moves are not allowed if there is a horizontal or
+     * vertical path to the destination
+     */
+    if (step_ok(ep->y, sp->x, MONSTOK, flgptr)) numpaths++;
+    if (step_ok(sp->y, ep->x, MONSTOK, flgptr)) numpaths++;
+    return(numpaths != 1);
+}
+
+/*
+ * eat:
+ *	He wants to eat something, so let him try
+ */
+
+eat()
+{
+    register struct linked_list *item;
+
+    if ((item = get_item(pack, "eat", FOOD)) == NULL)
+	return;
+    if ((OBJPTR(item))->o_which == 1)
+	msg("My, that was a yummy %s", fruit);
+    else {
+	if (rnd(100) > 70) {
+	    msg("Yuk, this food tastes awful");
+
+	    /* Do a check for overflow before increasing experience */
+	    if (pstats.s_exp + 1L > pstats.s_exp) pstats.s_exp++;
+	    check_level(TRUE);
+	}
+	else
+	    msg("Yum, that tasted good");
+    }
+    if ((food_left += HUNGERTIME + rnd(400) - 200) > STOMACHSIZE)
+	food_left = STOMACHSIZE;
+    del_pack(item);
+    hungry_state = F_OKAY;
+    updpack(TRUE);
+}
+
+/*
+ * pick a random position around the give (y, x) coordinates
+ */
+coord *
+fallpos(pos, be_clear, range)
+register coord *pos;
+bool be_clear;
+int range;
+{
+	register int tried, i, j;
+	register char ch;
+	static coord ret;
+	static short masks[] = {
+		0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x100 };
+
+/*
+ * Pick a spot at random centered on the position given by 'pos' and
+ * up to 'range' squares away from 'pos'
+ *
+ * If 'be_clear' is TRUE, the spot must be either FLOOR or PASSAGE
+ * inorder to be considered valid
+ *
+ *
+ * Generate a number from 0 to 8, representing the position to pick.
+ * Note that this DOES include the positon 'pos' itself
+ *
+ * If this position is not valid, mark it as 'tried', and pick another.
+ * Whenever a position is picked that has been tried before,
+ * sequentially find the next untried position. This eliminates costly
+ * random number generation
+ */
+
+	tried = 0;
+	while( tried != 0x1ff ) {
+		i = rnd(9);
+		while( tried & masks[i] )
+			i = (i + 1) % 9;
+
+		tried |= masks[i];
+
+		for( j = 1; j <= range; j++ ) {
+			ret.x = pos->x + j*grid[i].x;
+			ret.y = pos->y + j*grid[i].y;
+
+			if (ret.x == hero.x && ret.y == hero.y)
+				continue; /* skip the hero */
+
+			if (ret.x < 0 || ret.x > COLS - 1 ||
+			    ret.y < 1 || ret.y > LINES - 3)
+				continue; /* off the screen? */
+
+			ch = CCHAR( winat(ret.y, ret.x) );
+
+			/*
+			 * Check to make certain the spot is valid
+			 */
+			switch( ch ) {
+			case FLOOR:
+			case PASSAGE:
+				return( &ret );
+			case GOLD:
+			case SCROLL:
+			case POTION:
+			case STICK:
+			case RING:
+			case WEAPON:
+			case ARMOR:
+			case MM:
+			case FOOD:
+				if(!be_clear && levtype != POSTLEV)
+					return( &ret );
+			default:
+				break;
+			}
+		}
+	}
+	return( NULL );
+}
+
+
+/*
+ * find_mons:
+ *	Find the monster from his corrdinates
+ */
+
+struct linked_list *
+find_mons(y, x)
+register int y;
+register int x;
+{
+    register struct linked_list *item;
+    register struct thing *th;
+
+    for (item = mlist; item != NULL; item = next(item))
+    {
+	th = THINGPTR(item);
+	if (th->t_pos.y == y && th->t_pos.x == x)
+	    return item;
+    }
+    return NULL;
+}
+
+/*
+ * find_obj:
+ *	find the unclaimed object at y, x
+ */
+
+struct linked_list *
+find_obj(y, x)
+register int y;
+register int x;
+{
+    register struct linked_list *obj;
+    register struct object *op;
+
+    for (obj = lvl_obj; obj != NULL; obj = next(obj))
+    {
+	op = OBJPTR(obj);
+	if (op->o_pos.y == y && op->o_pos.x == x)
+		return obj;
+    }
+    return NULL;
+}
+
+
+/*
+ * set up the direction co_ordinate for use in varios "prefix" commands
+ */
+get_dir()
+{
+    register char *prompt;
+    register bool gotit;
+
+    prompt = terse ? "Direction?" :  "Which direction? ";
+    msg(prompt);
+    do
+    {
+	gotit = TRUE;
+	switch (readchar())
+	{
+	    case 'h': case'H': delta.y =  0; delta.x = -1;
+	    when 'j': case'J': delta.y =  1; delta.x =  0;
+	    when 'k': case'K': delta.y = -1; delta.x =  0;
+	    when 'l': case'L': delta.y =  0; delta.x =  1;
+	    when 'y': case'Y': delta.y = -1; delta.x = -1;
+	    when 'u': case'U': delta.y = -1; delta.x =  1;
+	    when 'b': case'B': delta.y =  1; delta.x = -1;
+	    when 'n': case'N': delta.y =  1; delta.x =  1;
+	    when ESCAPE: return FALSE;
+	    otherwise:
+		mpos = 0;
+		msg(prompt);
+		gotit = FALSE;
+	}
+    } until (gotit);
+    if ((on(player, ISHUH) || on(player, ISDANCE)) && rnd(100) > 20) {
+	do
+	{
+	    delta = grid[rnd(9)];
+	} while (delta.y == 0 && delta.x == 0);
+    }
+    mpos = 0;
+    return TRUE;
+}
+
+/* 
+ * see if the object is one of the currently used items
+ */
+is_current(obj)
+register struct object *obj;
+{
+    if (obj == NULL)
+	return FALSE;
+    if (obj == cur_armor		|| obj == cur_weapon		|| 
+	obj == cur_ring[LEFT_1]		|| obj == cur_ring[LEFT_2]	||
+	obj == cur_ring[LEFT_3]		|| obj == cur_ring[LEFT_4]	||
+	obj == cur_ring[RIGHT_1]	|| obj == cur_ring[RIGHT_2]	||
+	obj == cur_ring[RIGHT_3]	|| obj == cur_ring[RIGHT_4]	||
+	obj == cur_misc[WEAR_BOOTS]	|| obj == cur_misc[WEAR_JEWEL]	||
+	obj == cur_misc[WEAR_BRACERS]	|| obj == cur_misc[WEAR_CLOAK]	||
+	obj == cur_misc[WEAR_GAUNTLET]	|| obj == cur_misc[WEAR_NECKLACE]) {
+
+	return TRUE;
+    }
+
+    /* Is it a "current" relic? */
+    if (obj->o_type == RELIC) {
+	switch (obj->o_which) {
+	    case MUSTY_DAGGER:
+	    case EMORI_CLOAK:
+	    case HEIL_ANKH:
+	    case YENDOR_AMULET:
+	    case HRUGGEK_MSTAR:
+	    case YEENOGHU_FLAIL:
+		if (cur_relic[obj->o_which]) return TRUE;
+	}
+    }
+
+    return FALSE;
+}
+
+
+/*
+ * Look:
+ *	A quick glance all around the player
+ */
+
+look(wakeup, runend)
+bool wakeup;	/* Should we wake up monsters */
+bool runend;	/* At end of a run -- for mazes */
+{
+    register int x, y, radius;
+    register char ch, och;
+    register int oldx, oldy;
+    register bool inpass, horiz, vert, do_light = FALSE, do_blank = FALSE;
+    register int passcount = 0, curfloorcount = 0, nextfloorcount = 0;
+    register struct room *rp;
+    register int ey, ex;
+
+    inpass = ((rp = roomin(&hero)) == NULL); /* Are we in a passage? */
+
+    /* Are we moving vertically or horizontally? */
+    if (runch == 'h' || runch == 'l') horiz = TRUE;
+    else horiz = FALSE;
+    if (runch == 'j' || runch == 'k') vert = TRUE;
+    else vert = FALSE;
+
+    /* How far around himself can the player see? */
+    if (levtype == OUTSIDE) {
+	if (daytime) radius = 6;
+	else if (lit_room(rp)) radius = 3;
+	else radius = 1;
+    }
+    else radius = 1;
+
+    getyx(cw, oldy, oldx);	/* Save current position */
+
+    /* Blank out the floor around our last position and check for
+     * moving out of a corridor in a maze.
+     */
+    if (levtype == OUTSIDE) do_blank = !daytime;
+    else if (oldrp != NULL && !lit_room(oldrp) && off(player, ISBLIND))
+	    do_blank = TRUE;
+
+    /* Now move around the old position and blank things out */
+    ey = player.t_oldpos.y + radius;
+    ex = player.t_oldpos.x + radius;
+    for (x = player.t_oldpos.x - radius; x <= ex; x++)
+      if (x >= 0 && x < COLS)
+	for (y = player.t_oldpos.y - radius; y <= ey; y++) {
+	    char savech;	/* Saves character in monster window */
+
+	    if (y < 1 || y > LINES - 3) continue;
+
+	    /* See what's there -- ignore monsters, just see what they're on */
+	    savech = CCHAR( mvwinch(mw, y, x) );
+	    waddch(mw, ' ');
+	    ch = show(y, x);
+	    mvwaddch(mw, y, x, savech);	/* Restore monster */
+
+	    if (do_blank && (y != hero.y || x != hero.x))
+		switch (ch) {
+		    case DOOR:
+		    case SECRETDOOR:
+		    case PASSAGE:
+		    case STAIRS:
+		    case TRAPDOOR:
+		    case TELTRAP:
+		    case BEARTRAP:
+		    case SLEEPTRAP:
+		    case ARROWTRAP:
+		    case DARTTRAP:
+		    case MAZETRAP:
+		    case POOL:
+		    case POST:
+		    case '|':
+		    case '-':
+		    case WALL:
+			/* If there was a monster showing, make it disappear */
+			if (isalpha(savech)) mvwaddch(cw, y, x, ch);
+			break;
+		    when FLOOR:
+		    case FOREST:
+		    default:
+			mvwaddch(cw, y, x, ' ');
+		}
+		
+	    /* Moving out of a corridor? */
+	    if (levtype == MAZELEV && !ce(hero, player.t_oldpos) &&
+		!running && !isrock(ch) &&  /* Not running and not a wall */
+		((vert && x != player.t_oldpos.x && y==player.t_oldpos.y) ||
+		 (horiz && y != player.t_oldpos.y && x==player.t_oldpos.x)))
+		    do_light = off(player, ISBLIND);
+	}
+
+    /* Take care of unlighting a corridor */
+    if (do_light && lit_room(rp)) light(&player.t_oldpos);
+
+    /* Are we coming or going between a wall and a corridor in a maze? */
+    och = show(player.t_oldpos.y, player.t_oldpos.x);
+    ch = show(hero.y, hero.x);
+    if (levtype == MAZELEV &&
+	((isrock(och) && !isrock(ch)) || (isrock(ch) && !isrock(och)))) {
+	do_light = off(player, ISBLIND); /* Light it up if not blind */
+
+	/* Unlight what we just saw */
+	if (do_light && lit_room(&rooms[0])) light(&player.t_oldpos);
+    }
+
+    /* Look around the player */
+    ey = hero.y + radius;
+    ex = hero.x + radius;
+    for (x = hero.x - radius; x <= ex; x++)
+	if (x >= 0 && x < COLS) for (y = hero.y - radius; y <= ey; y++) {
+	    if (y < 1 || y >= LINES - 2)
+		continue;
+	    if (isalpha(mvwinch(mw, y, x)))
+	    {
+		register struct linked_list *it;
+		register struct thing *tp;
+
+		if (wakeup)
+		    it = wake_monster(y, x);
+		else
+		    it = find_mons(y, x);
+		tp = THINGPTR(it);
+		tp->t_oldch = CCHAR( mvinch(y, x) );
+		if (isatrap(tp->t_oldch)) {
+		    register struct trap *trp = trap_at(y, x);
+
+		    tp->t_oldch = (trp->tr_flags & ISFOUND) ? tp->t_oldch
+							    : trp->tr_show;
+		}
+		if (tp->t_oldch == FLOOR && !lit_room(rp) &&
+		    off(player, ISBLIND))
+			tp->t_oldch = ' ';
+	    }
+
+	    /*
+	     * Secret doors show as walls
+	     */
+	    if ((ch = show(y, x)) == SECRETDOOR)
+		ch = secretdoor(y, x);
+	    /*
+	     * Don't show room walls if he is in a passage and
+	     * check for maze turns
+	     */
+	    if (off(player, ISBLIND))
+	    {
+		if (y == hero.y && x == hero.x
+		    || (inpass && (ch == '-' || ch == '|')))
+			continue;
+
+		/* Did we come to a crossroads in a maze? */
+		if (levtype == MAZELEV &&
+		    (runend || !ce(hero, player.t_oldpos)) &&
+		    !isrock(ch) &&	/* Not a wall */
+		    ((vert && x != hero.x && y == hero.y) ||
+		     (horiz && y != hero.y && x == hero.x)))
+			/* Just came to a turn */
+			do_light = off(player, ISBLIND);
+	    }
+	    else if (y != hero.y || x != hero.x)
+		continue;
+
+	    wmove(cw, y, x);
+	    waddch(cw, ch);
+	    if (door_stop && !firstmove && running)
+	    {
+		switch (runch)
+		{
+		    case 'h':
+			if (x == hero.x + 1)
+			    continue;
+		    when 'j':
+			if (y == hero.y - 1)
+			    continue;
+		    when 'k':
+			if (y == hero.y + 1)
+			    continue;
+		    when 'l':
+			if (x == hero.x - 1)
+			    continue;
+		    when 'y':
+			if ((x + y) - (hero.x + hero.y) >= 1)
+			    continue;
+		    when 'u':
+			if ((y - x) - (hero.y - hero.x) >= 1)
+			    continue;
+		    when 'n':
+			if ((x + y) - (hero.x + hero.y) <= -1)
+			    continue;
+		    when 'b':
+			if ((y - x) - (hero.y - hero.x) <= -1)
+			    continue;
+		}
+		switch (ch)
+		{
+		    case DOOR:
+			if (x == hero.x || y == hero.y)
+			    running = FALSE;
+			break;
+		    case PASSAGE:
+			if (x == hero.x || y == hero.y)
+			    passcount++;
+			break;
+		    case FLOOR:
+			/* Stop by new passages in a maze (floor next to us) */
+			if ((levtype == MAZELEV) &&
+			    !(hero.y == y && hero.x == x)) {
+			    if (vert) {	/* Moving vertically */
+				/* We have a passage on our row */
+				if (y == hero.y) curfloorcount++;
+
+				/* Some passage on the next row */
+				else if (y != player.t_oldpos.y)
+				    nextfloorcount++;
+			    }
+			    else {	/* Moving horizontally */
+				/* We have a passage on our column */
+				if (x == hero.x) curfloorcount++;
+
+				/* Some passage in the next column */
+				else if (x != player.t_oldpos.x)
+				    nextfloorcount++;
+			    }
+			}
+		    case '|':
+		    case '-':
+		    case ' ':
+			break;
+		    default:
+			running = FALSE;
+			break;
+		}
+	    }
+	}
+
+    /* Have we passed a side passage, with multiple choices? */
+    if (curfloorcount > 0 && nextfloorcount > 0) running = FALSE;
+
+    else if (door_stop && !firstmove && passcount > 1)
+	running = FALSE;
+
+    /* Do we have to light up the area (just stepped into a new corridor)? */
+    if (do_light && !running && lit_room(rp)) light(&hero);
+
+    mvwaddch(cw, hero.y, hero.x, PLAYER);
+    wmove(cw, oldy, oldx);
+    if (!ce(player.t_oldpos, hero)) {
+	player.t_oldpos = hero; /* Don't change if we didn't move */
+	oldrp = rp;
+    }
+}
+
+/*
+ * raise_level:
+ *	The guy just magically went up a level.
+ */
+
+raise_level(get_spells)
+bool get_spells;
+{
+    unsigned long test;	/* Next level -- be sure it is not an overflow */
+
+    test = check_level(FALSE);	/* Get next boundary */
+
+    /* Be sure it is higher than what we have no -- else overflow */
+    if (test > pstats.s_exp) pstats.s_exp = test;
+    check_level(get_spells);
+}
+
+/*
+ * saving throw matrix for character saving throws
+ * this table is indexed by char type and saving throw type
+ */
+static int st_matrix[5][5] = {
+/* Poison,	Petrify,	wand,		Breath,		Magic */
+{ 14,		15,		16,		16,		17 },
+{ 14,		13,		11,		15,		12 },
+{ 10,		13,		14,		16,		15 },
+{ 13,		12,		14,		16,		15 },
+{ 14,		15,		16,		16,		17 }
+};
+
+/*
+ * save:
+ *	See if a creature saves against something
+ */
+save(which, who, adj)
+int which;		/* which type of save */
+struct thing *who;	/* who is saving */
+int adj;		/* saving throw adjustment */
+{
+    register int need, level;
+
+    level = who->t_stats.s_lvl;
+    need = st_matrix[who->t_ctype][which];
+    switch (who->t_ctype) {
+    case C_FIGHTER:
+	need -= (level-1) / 2;
+    when C_MAGICIAN:
+	need -= 2 * (level-1) / 5;
+    when C_CLERIC:
+	need -= (level-1) / 3;
+    when C_THIEF:
+	need -= 2 * (level-1) / 4;
+    when C_MONSTER:
+	need -= level / 2;
+    }
+    /* 
+     * add in pluses against poison for execeptional constitution 
+     */
+    if (which == VS_POISON && who->t_stats.s_const > 18)
+	need -= (who->t_stats.s_const - 17) / 2;
+    /*
+     * does the player have a ring of protection on?
+     */
+    if (who == &player)
+	need -= (min(ring_value(R_PROTECT),3)); /* no more than +3 bonus */
+    /*
+     * does the player have a cloak of protection on?
+     */
+    if (who == &player && cur_misc[WEAR_CLOAK])
+	need -= (min(cur_misc[WEAR_CLOAK]->o_ac,3)); /* no more than +3 bonus */
+    need -= adj;
+    debug("need a %d to save", need);
+    return (roll(1, 20) >= need);
+}
+
+
+/*
+ * secret_door:
+ *	Figure out what a secret door looks like.
+ */
+
+secretdoor(y, x)
+register int y, x;
+{
+    register int i;
+    register struct room *rp;
+    register coord *cpp;
+    static coord cp;
+
+    cp.y = y;
+    cp.x = x;
+    cpp = &cp;
+    for (rp = rooms, i = 0; i < MAXROOMS; rp++, i++)
+	if (inroom(rp, cpp))
+	    if (y == rp->r_pos.y || y == rp->r_pos.y + rp->r_max.y - 1)
+		return('-');
+	    else
+		return('|');
+
+    return('p');
+}
+
+/*
+ * copy string using unctrl for things
+ */
+strucpy(s1, s2, len)
+register char *s1, *s2;
+register int len;
+{
+    register char *sp;
+
+    while (len--)
+    {
+	strcpy(s1, (sp = unctrl(*s2)));
+	s1 += strlen(sp);
+        s2++;
+    }
+    *s1 = '\0';
+}
+
+/*
+ * tr_name:
+ *	print the name of a trap
+ */
+
+char *
+tr_name(ch)
+char ch;
+{
+    register char *s = NULL;
+
+    switch (ch)
+    {
+	case TRAPDOOR:
+	    s = terse ? "A trapdoor." : "You found a trapdoor.";
+	when BEARTRAP:
+	    s = terse ? "A beartrap." : "You found a beartrap.";
+	when SLEEPTRAP:
+	    s = terse ? "A sleeping gas trap.":"You found a sleeping gas trap.";
+	when ARROWTRAP:
+	    s = terse ? "An arrow trap." : "You found an arrow trap.";
+	when TELTRAP:
+	    s = terse ? "A teleport trap." : "You found a teleport trap.";
+	when DARTTRAP:
+	    s = terse ? "A dart trap." : "You found a poison dart trap.";
+	when POOL:
+	    s = terse ? "A shimmering pool." : "You found a shimmering pool";
+	when MAZETRAP:
+	    s = terse ? "A maze entrance." : "You found a maze entrance";
+    }
+    return s;
+}
+
+/*
+ * for printfs: if string starts with a vowel, return "n" for an "an"
+ */
+char *
+vowelstr(str)
+register char *str;
+{
+    switch (*str)
+    {
+	case 'a':
+	case 'e':
+	case 'i':
+	case 'o':
+	case 'u':
+	    return "n";
+	default:
+	    return "";
+    }
+}
+
+/*
+ * waste_time:
+ *	Do nothing but let other things happen
+ */
+
+waste_time()
+{
+    if (inwhgt)			/* if from wghtchk then done */
+	return;
+    do_daemons(BEFORE);
+    do_fuses(BEFORE);
+    do_daemons(AFTER);
+    do_fuses(AFTER);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/vers.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,20 @@
+/*
+ * version number.  Whenever a new version number is desired, use
+ * sccs to get vers.c.  Environ and encstr are declared here to
+ * force them to be loaded before the version number, and therefore
+ * not to be written in saved games.
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+char encstr[] = "\354\251\243\332A\201|\301\321p\210\251\327\"\257\365t\341%3\271^`~\203z{\341};\f\341\231\222e\234\351]\321\234";
+char version[] = "@(#)vers.c	5.8 (Bell Labs) 1/03/85";
+char *release = "5.8.2";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/weapons.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,310 @@
+/*
+ * Functions for dealing with problems brought about by weapons
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include <ctype.h>
+#include "rogue.h"
+
+
+
+/*
+ * do the actual motion on the screen done by an object traveling
+ * across the room
+ */
+do_motion(obj, ydelta, xdelta, tp)
+register struct object *obj;
+register int ydelta, xdelta;
+register struct thing *tp;
+{
+
+	/*
+	* Come fly with us ...
+	*/
+	obj->o_pos = tp->t_pos;
+	for (; ;) {
+		register int ch;
+		/*
+		* Erase the old one
+		*/
+		if (!ce(obj->o_pos, tp->t_pos) &&
+		    cansee(unc(obj->o_pos)) &&
+		    mvwinch(cw, obj->o_pos.y, obj->o_pos.x) != ' ') {
+			mvwaddch(cw, obj->o_pos.y, obj->o_pos.x, show(obj->o_pos.y, obj->o_pos.x));
+		}
+		/*
+		* Get the new position
+		*/
+		obj->o_pos.y += ydelta;
+		obj->o_pos.x += xdelta;
+		if (shoot_ok(ch = winat(obj->o_pos.y, obj->o_pos.x)) && ch != DOOR && !ce(obj->o_pos, hero)) {
+			/*
+			* It hasn't hit anything yet, so display it
+			* If it alright.
+			*/
+			if (cansee(unc(obj->o_pos)) &&
+			    mvwinch(cw, obj->o_pos.y, obj->o_pos.x) != ' ') {
+				mvwaddch(cw, obj->o_pos.y, obj->o_pos.x, obj->o_type);
+				draw(cw);
+			}
+			continue;
+		}
+		break;
+	}
+}
+
+
+/*
+ * fall:
+ *	Drop an item someplace around here.
+ */
+
+fall(item, pr)
+register struct linked_list *item;
+bool pr;
+{
+	register struct object *obj;
+	register struct room *rp;
+	register int i;
+	coord *fpos = NULL;
+
+	obj = OBJPTR(item);
+	/*
+	 * try to drop the item, look up to 3 squares away for now
+	 */
+	for (i=1; i<4; i++) {
+	    if ((fpos = fallpos(&obj->o_pos, FALSE, i)) != NULL)
+		break;
+	}
+
+	if (fpos != NULL) {
+		mvaddch(fpos->y, fpos->x, obj->o_type);
+		obj->o_pos = *fpos;
+		if ((rp = roomin(&hero)) != NULL &&
+		    lit_room(rp)) {
+			light(&hero);
+			mvwaddch(cw, hero.y, hero.x, PLAYER);
+		}
+		attach(lvl_obj, item);
+		return;
+	}
+
+
+	if (pr) {
+            if (obj->o_type == WEAPON) /* BUGFIX: Identification trick */
+                msg("The %s vanishes as it hits the ground.", 
+                    weaps[obj->o_which].w_name);
+            else
+                msg("%s vanishes as it hits the ground.", inv_name(obj,TRUE));
+	}
+	o_discard(item);
+}
+
+
+/*
+ * Does the missile hit the monster
+ */
+
+hit_monster(y, x, obj, tp)
+register int y, x;
+struct object *obj;
+register struct thing *tp;
+{
+	static coord mp;
+
+	mp.y = y;
+	mp.x = x;
+	if (tp == &player) {
+		/* Make sure there is a monster where it landed */
+		if (!isalpha(mvwinch(mw, y, x))) {
+			return(FALSE);
+		}
+		return(fight(&mp, obj, TRUE));
+	} else {
+		if (!ce(mp, hero)) {
+			return(FALSE);
+		}
+		return(attack(tp, obj, TRUE));
+	}
+}
+
+/*
+ * init_weapon:
+ *	Set up the initial goodies for a weapon
+ */
+
+init_weapon(weap, type)
+register struct object *weap;
+char type;
+{
+	register struct init_weps *iwp;
+
+	iwp = &weaps[type];
+	strcpy(weap->o_damage,iwp->w_dam);
+	strcpy(weap->o_hurldmg,iwp->w_hrl);
+	weap->o_launch = iwp->w_launch;
+	weap->o_flags = iwp->w_flags;
+	weap->o_weight = iwp->w_wght;
+	if (weap->o_flags & ISMANY) {
+		weap->o_count = rnd(8) + 8;
+		weap->o_group = newgrp();
+	} else {
+		weap->o_count = 1;
+	}
+}
+
+/*
+ * missile:
+ *	Fire a missile in a given direction
+ */
+
+missile(ydelta, xdelta, item, tp)
+int ydelta, xdelta;
+register struct linked_list *item;
+register struct thing *tp;
+{
+	register struct object *obj;
+	register struct linked_list *nitem;
+	char ch;
+
+	/*
+	* Get which thing we are hurling
+	*/
+	if (item == NULL) {
+		return;
+	}
+	obj = OBJPTR(item);
+
+#if 0	/* Do we really want to make this check */
+	if (is_current(obj)) {		/* Are we holding it? */
+	    msg(terse ? "Holding it." : "You are already holding it.");
+	    return;
+	}
+#endif
+
+	if (!dropcheck(obj)) return;	/* Can we get rid of it? */
+
+	if(!(obj->o_flags & ISMISL)) {
+	    for(;;) {
+		msg(terse ? "Really throw? (y or n): "
+			  : "Do you really want to throw %s? (y or n): ",
+				inv_name(obj, TRUE));
+		mpos = 0;
+		ch = readchar();
+		if (ch == 'n' || ch == ESCAPE) {
+		    after = FALSE;
+		    return;
+		}
+		if (ch == 'y')
+		    break;
+	    }
+	}
+	/*
+	 * Get rid of the thing. If it is a non-multiple item object, or
+	 * if it is the last thing, just drop it. Otherwise, create a new
+	 * item with a count of one.
+	 */
+	if (obj->o_count < 2) {
+		detach(tp->t_pack, item);
+		if (tp->t_pack == pack) {
+			inpack--;
+		}
+	} 
+	else {
+		obj->o_count--;
+		nitem = (struct linked_list *) new_item(sizeof *obj);
+		obj = OBJPTR(nitem);
+		*obj = *(OBJPTR(item));
+		obj->o_count = 1;
+		item = nitem;
+	}
+	updpack (FALSE);
+	do_motion(obj, ydelta, xdelta, tp);
+	/*
+	* AHA! Here it has hit something. If it is a wall or a door,
+	* or if it misses (combat) the monster, put it on the floor
+	*/
+	if (!hit_monster(unc(obj->o_pos), obj, tp)) {
+		fall(item, TRUE);
+	}
+	mvwaddch(cw, hero.y, hero.x, PLAYER);
+}
+
+/*
+ * num:
+ *	Figure out the plus number for armor/weapons
+ */
+
+char *
+num(n1, n2)
+register int n1, n2;
+{
+	static char numbuf[LINELEN];
+
+	if (n1 == 0 && n2 == 0) {
+		return "+0";
+	}
+	if (n2 == 0) {
+		sprintf(numbuf, "%s%d", n1 < 0 ? "" : "+", n1);
+	} else {
+		sprintf(numbuf, "%s%d, %s%d", n1 < 0 ? "" : "+", n1, n2 < 0 ? "" : "+", n2);
+	}
+	return(numbuf);
+}
+
+/*
+ * wield:
+ *	Pull out a certain weapon
+ */
+
+wield()
+{
+	register struct linked_list *item;
+	register struct object *obj, *oweapon;
+
+	if ((oweapon = cur_weapon) != NULL) {
+	    if (!dropcheck(cur_weapon)) {
+		    cur_weapon = oweapon;
+		    return;
+	    }
+	    if (terse)
+		addmsg("Was ");
+	    else
+		addmsg("You were ");
+	    msg("wielding %s", inv_name(oweapon, TRUE));
+	}
+	if ((item = get_item(pack, "wield", WIELDABLE)) == NULL) {
+		after = FALSE;
+		return;
+	}
+	obj = OBJPTR(item);
+	if (is_current(obj)) {
+		msg("Item in use.");
+		after = FALSE;
+		return;
+	}
+	if (player.t_ctype != C_FIGHTER &&
+	    obj->o_type == WEAPON	&&
+	   (obj->o_which == TWOSWORD || obj->o_which == BASWORD)) {
+		msg("Only fighters can wield a %s", weaps[obj->o_which].w_name);
+		return;
+	}
+	if (terse) {
+		addmsg("W");
+	} else {
+		addmsg("You are now w");
+	}
+	msg("ielding %s", inv_name(obj, TRUE));
+	cur_weapon = obj;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/wear.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,259 @@
+/*
+ * This file contains misc functions for dealing with armor
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include "rogue.h"
+
+
+/*
+ * take_off:
+ *	Get the armor off of the players back
+ */
+
+take_off()
+{
+    register struct object *obj;
+    register struct linked_list *item;
+
+    /* What does player want to take off? */
+    if ((item = get_item(pack, "take off", REMOVABLE)) == NULL)
+	return;
+
+    obj = OBJPTR(item);
+    if (!is_current(obj)) {
+	sprintf(outstring,"Not wearing %c) %s", pack_char(pack, obj),inv_name(obj, TRUE));
+	msg(outstring);
+	return;
+    }
+
+    /* Can the player remove the item? */
+    if (!dropcheck(obj)) return;
+    updpack(TRUE);
+
+    sprintf(outstring,"Was wearing %c) %s", pack_char(pack, obj),inv_name(obj,TRUE));
+    msg(outstring);
+}
+
+/*
+ * wear:
+ *	The player wants to wear something, so let him/her put it on.
+ */
+
+wear()
+{
+    register struct linked_list *item;
+    register struct object *obj;
+    register int i;
+    char buf[LINELEN];
+
+
+    /* What does player want to wear? */
+    if ((item = get_item(pack, "wear", WEARABLE)) == NULL)
+	return;
+
+    obj = OBJPTR(item);
+
+    switch (obj->o_type) {
+	case ARMOR:
+	    if (cur_armor != NULL) {
+		addmsg("You are already wearing armor");
+		if (!terse) addmsg(".  You'll have to take it off first.");
+		endmsg();
+		after = FALSE;
+		return;
+	    }
+	    if (cur_misc[WEAR_BRACERS] != NULL) {
+		msg("You can't wear armor with bracers of defense.");
+		return;
+	    }
+	    if (cur_misc[WEAR_CLOAK] != NULL || cur_relic[EMORI_CLOAK]) {
+		msg("You can't wear armor with a cloak.");
+		return;
+	    }
+	    if (player.t_ctype == C_THIEF	&&
+		(obj->o_which != LEATHER && obj->o_which != STUDDED_LEATHER)) {
+		if (terse) msg("Thieves can't wear that type of armor");
+		else
+		 msg("Thieves can only wear leather or studded leather armor");
+		return;
+	    }
+	    waste_time();
+	    obj->o_flags |= ISKNOW;
+	    cur_armor = obj;
+	    addmsg(terse ? "W" : "You are now w");
+	    msg("earing %s.", armors[obj->o_which].a_name);
+
+	when MM:
+	    switch (obj->o_which) {
+	    /*
+	     * when wearing the boots of elvenkind the player will not
+	     * set off any traps
+	     */
+	    case MM_ELF_BOOTS:
+		if (cur_misc[WEAR_BOOTS] != NULL)
+		    msg("already wearing a pair of boots");
+		else {
+		    msg("wearing %s",inv_name(obj,TRUE));
+		    cur_misc[WEAR_BOOTS] = obj;
+		}
+	    /*
+	     * when wearing the boots of dancing the player will dance
+	     * uncontrollably
+	     */
+	    when MM_DANCE:
+		if (cur_misc[WEAR_BOOTS] != NULL)
+		    msg("already wearing a pair of boots");
+		else {
+		    msg("wearing %s",inv_name(obj,TRUE));
+		    cur_misc[WEAR_BOOTS] = obj;
+		    msg("You begin to dance uncontrollably!");
+		    turn_on(player, ISDANCE);
+		}
+	    /*
+	     * bracers give the hero protection in he same way armor does.
+	     * they cannot be used with armor but can be used with cloaks
+	     */
+	    when MM_BRACERS:
+		if (cur_misc[WEAR_BRACERS] != NULL)
+			msg("already wearing bracers");
+		else {
+		    if (cur_armor != NULL) {
+			msg("You can't wear bracers of defense with armor.");
+		    }
+		    else {
+			msg("wearing %s",inv_name(obj,TRUE));
+			cur_misc[WEAR_BRACERS] = obj;
+		    }
+		}
+
+	    /*
+	     * The robe (cloak) of powerlessness disallows any spell casting
+	     */
+	    when MM_R_POWERLESS:
+	    /*
+	     * the cloak of displacement gives the hero an extra +2 on AC
+	     * and saving throws. Cloaks cannot be used with armor.
+	     */
+	    case MM_DISP:
+	    /*
+	     * the cloak of protection gives the hero +n on AC and saving
+	     * throws with a max of +3 on saves
+	     */
+	    case MM_PROTECT:
+		if (cur_misc[WEAR_CLOAK] != NULL || cur_relic[EMORI_CLOAK])
+		    msg("%slready wearing a cloak.", terse ? "A"
+							   : "You are a");
+		else {
+		    if (cur_armor != NULL) {
+			msg("You can't wear a cloak with armor.");
+		    }
+		    else {
+			msg("wearing %s",inv_name(obj,TRUE));
+			cur_misc[WEAR_CLOAK] = obj;
+		    }
+		}
+	    /*
+	     * the gauntlets of dexterity give the hero a dexterity of 18
+	     * the gauntlets of ogre power give the hero a strength of 18
+	     * the gauntlets of fumbling cause the hero to drop his weapon
+	     */
+	    when MM_G_DEXTERITY:
+	    case MM_G_OGRE:
+	    case MM_FUMBLE:
+		if (cur_misc[WEAR_GAUNTLET] != NULL)
+		    msg("Already wearing a pair of gauntlets.");
+		else {
+		    msg("wearing %s",inv_name(obj,TRUE));
+		    cur_misc[WEAR_GAUNTLET] = obj;
+		    if (obj->o_which == MM_FUMBLE)
+			daemon(fumble, 0, AFTER);
+		}
+	    /*
+	     * the jewel of attacks does an aggavate monster
+	     */
+	    when MM_JEWEL:
+		if (cur_misc[WEAR_JEWEL] != NULL || cur_relic[YENDOR_AMULET])
+		    msg("Already wearing an amulet.");
+		else {
+		    msg("wearing %s",inv_name(obj,TRUE));
+		    cur_misc[WEAR_JEWEL] = obj;
+		    aggravate();
+		}
+	    /*
+	     * the necklace of adaption makes the hero immune to
+	     * chlorine gas
+	     */
+	    when MM_ADAPTION:
+		if (cur_misc[WEAR_NECKLACE] != NULL)
+		    msg("already wearing a necklace");
+		else {
+		    msg("wearing %s",inv_name(obj,TRUE));
+		    cur_misc[WEAR_NECKLACE] = obj;
+		    turn_on(player, NOGAS);
+		}
+	    /*
+	     * the necklace of stragulation will try to strangle the
+	     * hero to death
+	     */
+	    when MM_STRANGLE:
+		if (cur_misc[WEAR_NECKLACE] != NULL)
+		    msg("already wearing a necklace");
+		else {
+		    msg("wearing %s",inv_name(obj,TRUE));
+		    cur_misc[WEAR_NECKLACE] = obj;
+		    msg("The necklace is beginning to strangle you!");
+		    daemon(strangle, 0, AFTER);
+		}
+	    otherwise:
+		msg("what a strange item you have!");
+	    }
+	    status(FALSE);
+	    if (m_know[obj->o_which] && m_guess[obj->o_which]) {
+		free(m_guess[obj->o_which]);
+		m_guess[obj->o_which] = NULL;
+	    }
+	    else if (!m_know[obj->o_which] && 
+		     askme &&
+		     (obj->o_flags & ISKNOW) == 0 &&
+		     m_guess[obj->o_which] == NULL) {
+		msg(terse ? "Call it: " : "What do you want to call it? ");
+		if (get_str(buf, cw) == NORM) {
+		    m_guess[obj->o_which] = new((unsigned int) strlen(buf) + 1);
+		    strcpy(m_guess[obj->o_which], buf);
+		}
+	    }
+
+	when RING:
+	    if (cur_misc[WEAR_GAUNTLET] != NULL) {
+		msg ("You have to remove your gauntlets first!");
+		return;
+	    }
+
+	    /* If there is room, put on the ring */
+	    for (i=0; i<NUM_FINGERS; i++)
+	        if (cur_ring[i] == NULL) {
+		    cur_ring[i] = obj;
+		    break;
+		}
+	    if (i == NUM_FINGERS) {	/* No room */
+		if (terse) msg("Wearing enough rings");
+		else msg("You already have on eight rings");
+		return;
+	    }
+
+	    /* Calculate the effect of the ring */
+	    ring_on(obj);
+    }
+    updpack(TRUE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/wizard.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,585 @@
+/*
+ * Special wizard commands (some of which are also non-wizard commands
+ * under strange circumstances)
+ *
+ * Advanced Rogue
+ * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
+ * All rights reserved.
+ *
+ * Based on "Rogue: Exploring the Dungeons of Doom"
+ * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
+ * All rights reserved.
+ *
+ * See the file LICENSE.TXT for full copyright and licensing information.
+ */
+
+#include "curses.h"
+#include <ctype.h>
+#include "rogue.h"
+
+
+/*
+ * create_obj:
+ *	Create any object for wizard, scroll, magician, or cleric
+ */
+create_obj(prompt, which_item, which_type)
+bool prompt;
+int which_item, which_type;
+{
+    reg struct linked_list *item;
+    reg struct object *obj;
+    reg int wh;
+    reg char ch, newitem, newtype = 0, whc, msz, *pt;
+    WINDOW *thiswin;
+
+    thiswin = cw;
+    if (prompt) {
+	bool nogood = TRUE;
+
+	thiswin = hw;
+	wclear(hw);
+	wprintw(hw,"Item\t\t\tKey\n\n");
+	wprintw(hw,"%s\t\t\t%c\n%s\t\t\t%c\n",things[TYP_RING].mi_name,RING,
+		things[TYP_STICK].mi_name,STICK);
+	wprintw(hw,"%s\t\t\t%c\n%s\t\t\t%c\n",things[TYP_POTION].mi_name,POTION,
+		things[TYP_SCROLL].mi_name,SCROLL);
+	wprintw(hw,"%s\t\t\t%c\n%s\t\t\t%c\n",things[TYP_ARMOR].mi_name,ARMOR,
+		things[TYP_WEAPON].mi_name,WEAPON);
+	wprintw(hw,"%s\t%c\n",things[TYP_MM].mi_name,MM);
+	wprintw(hw,"%s\t\t\t%c\n",things[TYP_FOOD].mi_name,FOOD);
+	if (wizard) {
+	    wprintw(hw,"%s\t\t%c\n",things[TYP_RELIC].mi_name,RELIC);
+	    waddstr(hw,"monster\t\t\tm");
+	}
+	wprintw(hw,"\n\nWhat do you want to create? ");
+	draw(hw);
+	do {
+	    ch = wgetch(hw);
+	    if (ch == ESCAPE) {
+		restscr(cw);
+		return;
+	    }
+	    switch (ch) {
+		case RING:
+		case STICK:	
+		case POTION:
+		case SCROLL:	
+		case ARMOR:	
+		case WEAPON:
+		case FOOD:
+		case MM:
+		    nogood = FALSE;
+		    break;
+		case RELIC:
+		case 'm':
+		    if (wizard) 
+			nogood = FALSE;
+		    break;
+		default:
+		    nogood = TRUE;
+	    }
+	} while (nogood);
+	newitem = ch;
+    }
+    else
+	newitem = which_item;
+
+    pt = "those";
+    msz = 0;
+    if(newitem == 'm') {
+	makemonster(TRUE);		/* make monster and be done with it */
+	return;
+    }
+    if(newitem == GOLD)
+	pt = "gold";
+    /* else if(isatrap(newitem))
+	pt = "traps";
+    */
+    switch(newitem) {
+	case POTION:	whc = TYP_POTION;	msz = MAXPOTIONS;
+	when SCROLL:	whc = TYP_SCROLL;	msz = MAXSCROLLS;
+	when WEAPON:	whc = TYP_WEAPON;	msz = MAXWEAPONS;
+	when ARMOR:	whc = TYP_ARMOR;	msz = MAXARMORS;
+	when RING:	whc = TYP_RING;		msz = MAXRINGS;
+	when STICK:	whc = TYP_STICK;	msz = MAXSTICKS;
+	when MM:	whc = TYP_MM;		msz = MAXMM;
+	when RELIC:	whc = TYP_RELIC;	msz = MAXRELIC;
+	when FOOD:
+	    whc = TYP_FOOD;
+	    msz = MAXFOODS;
+	    if (thiswin == hw)
+		restscr(cw);
+	    mpos = 0;
+	otherwise:
+	    if (thiswin == hw)
+		restscr(cw);
+	    mpos = 0;
+	    msg("Even wizards can't create %s !!",pt);
+	    return;
+    }
+    if(msz == 1) {		/* if only one type of item */
+	ch = 'a';
+    }
+    else if (prompt) {
+	register struct magic_item *wmi;
+	char wmn;
+	register int ii;
+	int old_prob;
+
+	mpos = 0;
+	wmi = NULL;
+	wmn = 0;
+	switch(newitem) {
+		case POTION:	wmi = &p_magic[0];
+		when SCROLL:	wmi = &s_magic[0];
+		when RING:	wmi = &r_magic[0];
+		when STICK:	wmi = &ws_magic[0];
+		when MM:	wmi = &m_magic[0];
+		when RELIC:	wmi = &rel_magic[0];
+		when WEAPON:	wmn = 1;
+		when ARMOR:	wmn = 2;
+	}
+	wclear(hw);
+	thiswin = hw;
+	if (wmi != NULL) {
+	    ii = old_prob = 0;
+	    while (ii < msz) {
+		if(wmi->mi_prob == old_prob && wizard == FALSE) { 
+		    msz--; /* can't make a unique item */
+		}
+		else {
+		    mvwaddch(hw,ii % 13,ii > 12 ? COLS/2 : 0, ii + 'a');
+		    waddstr(hw,") ");
+		    waddstr(hw,wmi->mi_name);
+		    ii++;
+		}
+		old_prob = wmi->mi_prob;
+	        wmi++;
+	    }
+	}
+	else if (wmn != 0) {
+	    for(ii = 0 ; ii < msz ; ii++) {
+	        mvwaddch(hw,ii % 13,ii > 12 ? COLS/2 : 0, ii + 'a');
+	        waddstr(hw,") ");
+	        if(wmn == 1)
+		    waddstr(hw,weaps[ii].w_name);
+	        else
+		    waddstr(hw,armors[ii].a_name);
+	    }
+	}
+	sprintf(prbuf,"Which %s? ",things[whc].mi_name);
+	mvwaddstr(hw,LINES - 1, 0, prbuf);
+	draw(hw);
+	do {
+	    ch = wgetch(hw);
+	    if (ch == ESCAPE) {
+	        restscr(cw);
+	        msg("");
+	        return;
+	    }
+	} until (isalpha(ch));
+        if (thiswin == hw)			/* restore screen if need be */
+	    restscr(cw);
+        newtype = tolower(ch) - 'a';
+        if(newtype < 0 || newtype >= msz) {	/* if an illegal value */
+	    mpos = 0;
+	    msg("There is no such %s",things[whc].mi_name);
+	    return;
+        }
+    }
+    else 
+	newtype = which_type;
+    item = new_item(sizeof *obj);	/* get some memory */
+    obj = OBJPTR(item);
+    obj->o_type = newitem;		/* store the new items */
+    obj->o_mark[0] = '\0';
+    obj->o_which = newtype;
+    obj->o_group = 0;
+    obj->contents = NULL;
+    obj->o_count = 1;
+    obj->o_flags = 0;
+    obj->o_dplus = obj->o_hplus = 0;
+    obj->o_weight = 0;
+    wh = obj->o_which;
+    mpos = 0;
+    if (!wizard)			/* users get 0 to +3 */
+	whc = rnd(4);
+    else			/* wizard gets to choose */
+	whc = getbless();
+    if (whc < 0)
+	obj->o_flags |= ISCURSED;
+    switch (obj->o_type) {
+	case WEAPON:
+	case ARMOR:
+	    if (obj->o_type == WEAPON) {
+		init_weapon(obj, wh);
+		obj->o_hplus += whc;
+		obj->o_dplus += whc;
+	    }
+	    else {				/* armor here */
+		obj->o_weight = armors[wh].a_wght;
+		obj->o_ac = armors[wh].a_class - whc;
+	    }
+	when RING:
+	    if (whc > 1 && r_magic[wh].mi_bless != 0)
+		obj->o_flags |= ISBLESSED;
+	    r_know[wh] = TRUE;
+	    switch(wh) {
+		case R_ADDSTR:
+		case R_ADDWISDOM:
+		case R_ADDINTEL:
+		case R_PROTECT:
+		case R_ADDHIT:
+		case R_ADDDAM:
+		case R_DIGEST:
+		    obj->o_ac = whc + 1;
+		    break;
+		default: 
+		    obj->o_ac = 0;
+	    }
+	    obj->o_weight = things[TYP_RING].mi_wght;
+	when MM:
+	    if (whc > 1 && m_magic[wh].mi_bless != 0)
+		obj->o_flags |= ISBLESSED;
+	    m_know[wh] = TRUE;
+	    switch(wh) {
+		case MM_JUG:
+		    switch(rnd(9)) {
+			case 0: obj->o_ac = P_PHASE;
+			when 1: obj->o_ac = P_CLEAR;
+			when 2: obj->o_ac = P_SEEINVIS;
+			when 3: obj->o_ac = P_HEALING;
+			when 4: obj->o_ac = P_MFIND;
+			when 5: obj->o_ac = P_TFIND;
+			when 6: obj->o_ac = P_HASTE;
+			when 7: obj->o_ac = P_RESTORE;
+			when 8: obj->o_ac = P_FLY;
+		    }
+		when MM_OPEN:
+		case MM_HUNGER:
+		case MM_DRUMS:
+		case MM_DISAPPEAR:
+		case MM_CHOKE:
+		case MM_KEOGHTOM:
+		    if (whc < 0)
+			whc = -whc; 	/* these cannot be negative */
+		    obj->o_ac = (whc + 1) * 5;
+		    break;
+		when MM_BRACERS:
+		    obj->o_ac = whc * 2 + 1;
+		when MM_DISP:
+		    obj->o_ac = 2;
+		when MM_PROTECT:
+		    obj->o_ac = whc;
+		when MM_SKILLS:
+		    if (wizard && whc != 0)
+			obj->o_ac = rnd(4);
+		    else
+			obj->o_ac = player.t_ctype;
+		otherwise: 
+		    obj->o_ac = 0;
+	    }
+	    obj->o_weight = things[TYP_MM].mi_wght;
+	when STICK:
+	    if (whc > 1 && ws_magic[wh].mi_bless != 0)
+		obj->o_flags |= ISBLESSED;
+	    ws_know[wh] = TRUE;
+	    fix_stick(obj);
+	when SCROLL:
+	    if (whc > 1 && s_magic[wh].mi_bless != 0)
+		obj->o_flags |= ISBLESSED;
+	    obj->o_weight = things[TYP_SCROLL].mi_wght;
+	    s_know[wh] = TRUE;
+	when POTION:
+	    if (whc > 1 && p_magic[wh].mi_bless != 0)
+		obj->o_flags |= ISBLESSED;
+	    obj->o_weight = things[TYP_POTION].mi_wght;
+	    p_know[wh] = TRUE;
+	when RELIC:
+	    obj->o_weight = things[TYP_RELIC].mi_wght;
+    }
+    mpos = 0;
+    obj->o_flags |= ISKNOW;
+    if (add_pack(item, FALSE, NULL) == FALSE) {
+	obj->o_pos = hero;
+	fall(item, TRUE);
+    }
+}
+
+/*
+ * getbless:
+ *	Get a blessing for a wizards object
+ */
+getbless()
+{
+	reg char bless;
+
+	msg("Blessing? (+,-,n)");
+	bless = readchar();
+	if (bless == '+')
+		return (rnd(3) + 2);
+	else if (bless == '-')
+		return (-rnd(3) - 1);
+	else
+		return (0);
+}
+
+/*
+ * get a non-monster death type
+ */
+getdeath()
+{
+    register int i;
+    int which_death;
+    char label[80];
+
+    clear();
+    for (i=0; i<DEATHNUM; i++) {
+	sprintf(label, "[%d] %s", i+1, deaths[i].name);
+	mvaddstr(i+2, 0, label);
+    }
+    mvaddstr(0, 0, "Which death? ");
+    refresh();
+
+    /* Get the death */
+    for (;;) {
+	get_str(label, stdscr);
+	which_death = atoi(label);
+	if ((which_death < 1 || which_death > DEATHNUM)) {
+	    mvaddstr(0, 0, "Please enter a number in the displayed range -- ");
+	    refresh();
+	}
+	else break;
+    }
+    return(deaths[which_death-1].reason);
+}
+
+/*
+ * make a monster for the wizard
+ */
+makemonster(create) 
+bool create;
+{
+    register int i;
+    register short which_monst;
+    register int num_monst = NUMMONST, pres_monst=1, num_lines=2*(LINES-3);
+    char monst_name[40];
+
+    /* Print out the monsters */
+    while (num_monst > 0) {
+	register left_limit;
+
+	if (num_monst < num_lines) left_limit = (num_monst+1)/2;
+	else left_limit = num_lines/2;
+
+	wclear(hw);
+	touchwin(hw);
+
+	/* Print left column */
+	wmove(hw, 2, 0);
+	for (i=0; i<left_limit; i++) {
+	    sprintf(monst_name, "[%d] %s\n",
+				pres_monst, monsters[pres_monst].m_name);
+	    waddstr(hw, monst_name);
+	    pres_monst++;
+	}
+
+	/* Print right column */
+	for (i=0; i<left_limit && pres_monst<=NUMMONST; i++) {
+	    sprintf(monst_name, "[%d] %s",
+				pres_monst, monsters[pres_monst].m_name);
+	    wmove(hw, i+2, COLS/2);
+	    waddstr(hw, monst_name);
+	    pres_monst++;
+	}
+
+	if ((num_monst -= num_lines) > 0) {
+	    mvwaddstr(hw, LINES-1, 0, morestr);
+	    draw(hw);
+	    wait_for(hw,' ');
+	}
+
+	else {
+	    mvwaddstr(hw, 0, 0, "Which monster");
+	    if (!terse && create) waddstr(hw, " do you wish to create");
+	    waddstr(hw, "? ");
+	    draw(hw);
+	}
+    }
+
+get_monst:
+    get_str(monst_name, hw);
+    which_monst = atoi(monst_name);
+    if ((which_monst < 1 || which_monst > NUMMONST)) {
+	mvwaddstr(hw, 0, 0, "Please enter a number in the displayed range -- ");
+	draw(hw);
+	goto get_monst;
+    }
+    restscr(cw);
+    if (create) {
+	creat_mons (&player, which_monst, TRUE);
+	light(&hero);
+    }
+    touchwin(cw);
+    return(which_monst);
+}
+
+/*
+ * passwd:
+ *	see if user knows password
+ */
+
+passwd()
+{
+    register char *sp, c;
+    char buf[LINELEN];
+
+    msg("Wizard's Password:");
+    mpos = 0;
+    sp = buf;
+    while ((c = readchar()) != '\n' && c != '\r' && c != '\033')
+	if (c == md_killchar())
+	    sp = buf;
+	else if (c == md_erasechar() && sp > buf)
+	    sp--;
+	else
+	    *sp++ = c;
+    if (sp == buf)
+	return FALSE;
+    *sp = '\0';
+    return (strcmp(PASSWD, md_crypt(buf, "Si")) == 0);
+}
+
+
+/*
+ * teleport:
+ *	Bamf the hero someplace else
+ */
+
+teleport()
+{
+    register struct room *new_rp, *old_rp = roomin(&hero);
+    register int rm;
+    coord c;
+
+    c = hero;
+    mvwaddch(cw, hero.y, hero.x, mvwinch(stdscr, hero.y, hero.x));
+    do
+    {
+	rm = rnd_room();
+	rnd_pos(&rooms[rm], &hero);
+    } until(winat(hero.y, hero.x) == FLOOR);
+    player.t_oldpos = c;	/* Save last position */
+
+    /* If hero gets moved, darken old room */
+    new_rp = &rooms[rm];
+    if (old_rp && old_rp != new_rp) {
+	old_rp->r_flags |= FORCEDARK;	/* Fake darkness */
+	light(&c);
+	old_rp->r_flags &= ~FORCEDARK; /* Restore light state */
+    }
+
+    /* Darken where we just came from */
+    else if (levtype == MAZELEV) light(&c);
+
+    light(&hero);
+    mvwaddch(cw, hero.y, hero.x, PLAYER);
+
+    /* Reset current room and position */
+    oldrp = new_rp;	/* Used in look() */
+    player.t_oldpos = hero;
+
+    /*
+     * turn off ISHELD in case teleportation was done while fighting
+     * something that holds you
+     */
+    if (on(player, ISHELD)) {
+	register struct linked_list *ip, *nip;
+	register struct thing *mp;
+
+	turn_off(player, ISHELD);
+	hold_count = 0;
+	for (ip = mlist; ip; ip = nip) {
+	    mp = THINGPTR(ip);
+	    nip = next(ip);
+	    if (on(*mp, DIDHOLD)) {
+		turn_off(*mp, DIDHOLD);
+		turn_on(*mp, CANHOLD);
+	    }
+	    turn_off(*mp, DIDSUFFOCATE); /* Suffocation -- see below */
+	}
+    }
+
+    /* Make sure player does not suffocate */
+    extinguish(suffocate);
+
+    count = 0;
+    running = FALSE;
+    md_flushinp();
+    return rm;
+}
+
+/*
+ * whatis:
+ *	What a certin object is
+ */
+
+whatis(what)
+struct linked_list *what;
+{
+    register struct object *obj;
+    register struct linked_list *item;
+
+    if (what == NULL) {		/* do we need to ask which one? */
+	if ((item = get_item(pack, "identify", IDENTABLE)) == NULL)
+	    return;
+    }
+    else
+	item = what;
+    obj = OBJPTR(item);
+    switch (obj->o_type) {
+        case SCROLL:
+	    s_know[obj->o_which] = TRUE;
+	    if (s_guess[obj->o_which]) {
+		free(s_guess[obj->o_which]);
+		s_guess[obj->o_which] = NULL;
+	    }
+        when POTION:
+	    p_know[obj->o_which] = TRUE;
+	    if (p_guess[obj->o_which]) {
+		free(p_guess[obj->o_which]);
+		p_guess[obj->o_which] = NULL;
+	    }
+	when STICK:
+	    ws_know[obj->o_which] = TRUE;
+	    if (ws_guess[obj->o_which]) {
+		free(ws_guess[obj->o_which]);
+		ws_guess[obj->o_which] = NULL;
+	    }
+        when RING:
+	    r_know[obj->o_which] = TRUE;
+	    if (r_guess[obj->o_which]) {
+		free(r_guess[obj->o_which]);
+		r_guess[obj->o_which] = NULL;
+	    }
+        when MM:
+	    /* If it's an identified jug, identify its potion */
+	    if (obj->o_which == MM_JUG && (obj->o_flags & ISKNOW)) {
+		if (obj->o_ac != JUG_EMPTY)
+		    p_know[obj->o_ac] = TRUE;
+		break;
+	    }
+
+	    m_know[obj->o_which] = TRUE;
+	    if (m_guess[obj->o_which]) {
+		free(m_guess[obj->o_which]);
+		m_guess[obj->o_which] = NULL;
+	    }
+	otherwise:
+	    break;
+    }
+    obj->o_flags |= ISKNOW;
+    if (what == NULL)
+	msg(inv_name(obj, FALSE));
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue5/xcrypt.c	Thu Aug 09 22:58:48 2012 +0000
@@ -0,0 +1,694 @@
+/*
+ * FreeSec: libcrypt
+ *
+ * Copyright (C) 1994 David Burren
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name(s) of the author(s) nor the names of other contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *
+ * This is an original implementation of the DES and the crypt(3) interfaces
+ * by David Burren <davidb@werj.com.au>.
+ *
+ * An excellent reference on the underlying algorithm (and related
+ * algorithms) is:
+ *
+ *	B. Schneier, Applied Cryptography: protocols, algorithms,
+ *	and source code in C, John Wiley & Sons, 1994.
+ *
+ * Note that in that book's description of DES the lookups for the initial,
+ * pbox, and final permutations are inverted (this has been brought to the
+ * attention of the author).  A list of errata for this book has been
+ * posted to the sci.crypt newsgroup by the author and is available for FTP.
+ *
+ * NOTE:
+ * This file has a static version of des_setkey() so that crypt.o exports
+ * only the crypt() interface. This is required to make binaries linked
+ * against crypt.o exportable or re-exportable from the USA.
+ */
+
+#include <sys/types.h>
+#include <string.h>
+
+#ifdef DEBUG
+# include <stdio.h>
+#endif
+#define _PASSWORD_EFMT1 '_'
+
+static unsigned char	IP[64] = {
+	58, 50, 42, 34, 26, 18, 10,  2, 60, 52, 44, 36, 28, 20, 12,  4,
+	62, 54, 46, 38, 30, 22, 14,  6, 64, 56, 48, 40, 32, 24, 16,  8,
+	57, 49, 41, 33, 25, 17,  9,  1, 59, 51, 43, 35, 27, 19, 11,  3,
+	61, 53, 45, 37, 29, 21, 13,  5, 63, 55, 47, 39, 31, 23, 15,  7
+};
+
+static unsigned char	inv_key_perm[64];
+static unsigned char	key_perm[56] = {
+	57, 49, 41, 33, 25, 17,  9,  1, 58, 50, 42, 34, 26, 18,
+	10,  2, 59, 51, 43, 35, 27, 19, 11,  3, 60, 52, 44, 36,
+	63, 55, 47, 39, 31, 23, 15,  7, 62, 54, 46, 38, 30, 22,
+	14,  6, 61, 53, 45, 37, 29, 21, 13,  5, 28, 20, 12,  4
+};
+
+static unsigned char	key_shifts[16] = {
+	1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
+};
+
+static unsigned char	inv_comp_perm[56];
+static unsigned char	comp_perm[48] = {
+	14, 17, 11, 24,  1,  5,  3, 28, 15,  6, 21, 10,
+	23, 19, 12,  4, 26,  8, 16,  7, 27, 20, 13,  2,
+	41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
+	44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
+};
+
+/*
+ *	No E box is used, as it's replaced by some ANDs, shifts, and ORs.
+ */
+
+static unsigned char	u_sbox[8][64];
+static unsigned char	sbox[8][64] = {
+	{
+		14,  4, 13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
+		 0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
+		 4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
+		15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13
+	},
+	{
+		15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
+		 3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
+		 0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
+		13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9
+	},
+	{
+		10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
+		13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
+		13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
+		 1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12
+	},
+	{
+		 7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
+		13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
+		10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
+		 3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14
+	},
+	{
+		 2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
+		14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
+		 4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
+		11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3
+	},
+	{
+		12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
+		10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
+		 9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
+		 4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13
+	},
+	{
+		 4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
+		13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
+		 1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
+		 6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12
+	},
+	{
+		13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
+		 1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
+		 7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
+		 2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11
+	}
+};
+
+static unsigned char	un_pbox[32];
+static unsigned char	pbox[32] = {
+	16,  7, 20, 21, 29, 12, 28, 17,  1, 15, 23, 26,  5, 18, 31, 10,
+	 2,  8, 24, 14, 32, 27,  3,  9, 19, 13, 30,  6, 22, 11,  4, 25
+};
+
+static unsigned int bits32[32] =
+{
+	0x80000000, 0x40000000, 0x20000000, 0x10000000,
+	0x08000000, 0x04000000, 0x02000000, 0x01000000,
+	0x00800000, 0x00400000, 0x00200000, 0x00100000,
+	0x00080000, 0x00040000, 0x00020000, 0x00010000,
+	0x00008000, 0x00004000, 0x00002000, 0x00001000,
+	0x00000800, 0x00000400, 0x00000200, 0x00000100,
+	0x00000080, 0x00000040, 0x00000020, 0x00000010,
+	0x00000008, 0x00000004, 0x00000002, 0x00000001
+};
+
+static unsigned char	bits8[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
+
+static unsigned int saltbits;
+static int	old_salt;
+static unsigned int *bits28, *bits24;
+static unsigned char	init_perm[64], final_perm[64];
+static unsigned int en_keysl[16], en_keysr[16];
+static unsigned int de_keysl[16], de_keysr[16];
+static int	des_initialised = 0;
+static unsigned char	m_sbox[4][4096];
+static unsigned int psbox[4][256];
+static unsigned int ip_maskl[8][256], ip_maskr[8][256];
+static unsigned int fp_maskl[8][256], fp_maskr[8][256];
+static unsigned int key_perm_maskl[8][128], key_perm_maskr[8][128];
+static unsigned int comp_maskl[8][128], comp_maskr[8][128];
+static unsigned int old_rawkey0, old_rawkey1;
+
+static unsigned char	ascii64[] =
+	 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+/*	  0000000000111111111122222222223333333333444444444455555555556666 */
+/*	  0123456789012345678901234567890123456789012345678901234567890123 */
+
+static __inline int
+ascii_to_bin(ch)
+	char ch;
+{
+	if (ch > 'z')
+		return(0);
+	if (ch >= 'a')
+		return(ch - 'a' + 38);
+	if (ch > 'Z')
+		return(0);
+	if (ch >= 'A')
+		return(ch - 'A' + 12);
+	if (ch > '9')
+		return(0);
+	if (ch >= '.')
+		return(ch - '.');
+	return(0);
+}
+
+static void
+des_init()
+{
+	int	i, j, b, k, inbit, obit;
+	unsigned int	*p, *il, *ir, *fl, *fr;
+
+	old_rawkey0 = old_rawkey1 = 0;
+	saltbits = 0;
+	old_salt = 0;
+	bits24 = (bits28 = bits32 + 4) + 4;
+
+	/*
+	 * Invert the S-boxes, reordering the input bits.
+	 */
+	for (i = 0; i < 8; i++)
+		for (j = 0; j < 64; j++) {
+			b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf);
+			u_sbox[i][j] = sbox[i][b];
+		}
+
+	/*
+	 * Convert the inverted S-boxes into 4 arrays of 8 bits.
+	 * Each will handle 12 bits of the S-box input.
+	 */
+	for (b = 0; b < 4; b++)
+		for (i = 0; i < 64; i++)
+			for (j = 0; j < 64; j++)
+				m_sbox[b][(i << 6) | j] =
+					(u_sbox[(b << 1)][i] << 4) |
+					u_sbox[(b << 1) + 1][j];
+
+	/*
+	 * Set up the initial & final permutations into a useful form, and
+	 * initialise the inverted key permutation.
+	 */
+	for (i = 0; i < 64; i++) {
+		init_perm[final_perm[i] = IP[i] - 1] = i;
+		inv_key_perm[i] = 255;
+	}
+
+	/*
+	 * Invert the key permutation and initialise the inverted key
+	 * compression permutation.
+	 */
+	for (i = 0; i < 56; i++) {
+		inv_key_perm[key_perm[i] - 1] = i;
+		inv_comp_perm[i] = 255;
+	}
+
+	/*
+	 * Invert the key compression permutation.
+	 */
+	for (i = 0; i < 48; i++) {
+		inv_comp_perm[comp_perm[i] - 1] = i;
+	}
+
+	/*
+	 * Set up the OR-mask arrays for the initial and final permutations,
+	 * and for the key initial and compression permutations.
+	 */
+	for (k = 0; k < 8; k++) {
+		for (i = 0; i < 256; i++) {
+			*(il = &ip_maskl[k][i]) = 0;
+			*(ir = &ip_maskr[k][i]) = 0;
+			*(fl = &fp_maskl[k][i]) = 0;
+			*(fr = &fp_maskr[k][i]) = 0;
+			for (j = 0; j < 8; j++) {
+				inbit = 8 * k + j;
+				if (i & bits8[j]) {
+					if ((obit = init_perm[inbit]) < 32)
+						*il |= bits32[obit];
+					else
+						*ir |= bits32[obit-32];
+					if ((obit = final_perm[inbit]) < 32)
+						*fl |= bits32[obit];
+					else
+						*fr |= bits32[obit - 32];
+				}
+			}
+		}
+		for (i = 0; i < 128; i++) {
+			*(il = &key_perm_maskl[k][i]) = 0;
+			*(ir = &key_perm_maskr[k][i]) = 0;
+			for (j = 0; j < 7; j++) {
+				inbit = 8 * k + j;
+				if (i & bits8[j + 1]) {
+					if ((obit = inv_key_perm[inbit]) == 255)
+						continue;
+					if (obit < 28)
+						*il |= bits28[obit];
+					else
+						*ir |= bits28[obit - 28];
+				}
+			}
+			*(il = &comp_maskl[k][i]) = 0;
+			*(ir = &comp_maskr[k][i]) = 0;
+			for (j = 0; j < 7; j++) {
+				inbit = 7 * k + j;
+				if (i & bits8[j + 1]) {
+					if ((obit=inv_comp_perm[inbit]) == 255)
+						continue;
+					if (obit < 24)
+						*il |= bits24[obit];
+					else
+						*ir |= bits24[obit - 24];
+				}
+			}
+		}
+	}
+
+	/*
+	 * Invert the P-box permutation, and convert into OR-masks for
+	 * handling the output of the S-box arrays setup above.
+	 */
+	for (i = 0; i < 32; i++)
+		un_pbox[pbox[i] - 1] = i;
+
+	for (b = 0; b < 4; b++)
+		for (i = 0; i < 256; i++) {
+			*(p = &psbox[b][i]) = 0;
+			for (j = 0; j < 8; j++) {
+				if (i & bits8[j])
+					*p |= bits32[un_pbox[8 * b + j]];
+			}
+		}
+
+	des_initialised = 1;
+}
+
+static void
+setup_salt(salt)
+	int salt;
+{
+	unsigned int	obit, saltbit;
+	int	i;
+
+	if (salt == old_salt)
+		return;
+	old_salt = salt;
+
+	saltbits = 0;
+	saltbit = 1;
+	obit = 0x800000;
+	for (i = 0; i < 24; i++) {
+		if (salt & saltbit)
+			saltbits |= obit;
+		saltbit <<= 1;
+		obit >>= 1;
+	}
+}
+
+static int
+des_setkey(key)
+	const char *key;
+{
+	unsigned int k0, k1, rawkey0, rawkey1;
+	int	shifts, round;
+
+	if (!des_initialised)
+		des_init();
+
+	rawkey0 = md_ntohl(*(unsigned int *) key);
+	rawkey1 = md_ntohl(*(unsigned int *) (key + 4));
+
+	if ((rawkey0 | rawkey1)
+	    && rawkey0 == old_rawkey0
+	    && rawkey1 == old_rawkey1) {
+		/*
+		 * Already setup for this key.
+		 * This optimisation fails on a zero key (which is weak and
+		 * has bad parity anyway) in order to simplify the starting
+		 * conditions.
+		 */
+		return(0);
+	}
+	old_rawkey0 = rawkey0;
+	old_rawkey1 = rawkey1;
+
+	/*
+	 *	Do key permutation and split into two 28-bit subkeys.
+	 */
+	k0 = key_perm_maskl[0][rawkey0 >> 25]
+	   | key_perm_maskl[1][(rawkey0 >> 17) & 0x7f]
+	   | key_perm_maskl[2][(rawkey0 >> 9) & 0x7f]
+	   | key_perm_maskl[3][(rawkey0 >> 1) & 0x7f]
+	   | key_perm_maskl[4][rawkey1 >> 25]
+	   | key_perm_maskl[5][(rawkey1 >> 17) & 0x7f]
+	   | key_perm_maskl[6][(rawkey1 >> 9) & 0x7f]
+	   | key_perm_maskl[7][(rawkey1 >> 1) & 0x7f];
+	k1 = key_perm_maskr[0][rawkey0 >> 25]
+	   | key_perm_maskr[1][(rawkey0 >> 17) & 0x7f]
+	   | key_perm_maskr[2][(rawkey0 >> 9) & 0x7f]
+	   | key_perm_maskr[3][(rawkey0 >> 1) & 0x7f]
+	   | key_perm_maskr[4][rawkey1 >> 25]
+	   | key_perm_maskr[5][(rawkey1 >> 17) & 0x7f]
+	   | key_perm_maskr[6][(rawkey1 >> 9) & 0x7f]
+	   | key_perm_maskr[7][(rawkey1 >> 1) & 0x7f];
+	/*
+	 *	Rotate subkeys and do compression permutation.
+	 */
+	shifts = 0;
+	for (round = 0; round < 16; round++) {
+		unsigned int	t0, t1;
+
+		shifts += key_shifts[round];
+
+		t0 = (k0 << shifts) | (k0 >> (28 - shifts));
+		t1 = (k1 << shifts) | (k1 >> (28 - shifts));
+
+		de_keysl[15 - round] =
+		en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f]
+				| comp_maskl[1][(t0 >> 14) & 0x7f]
+				| comp_maskl[2][(t0 >> 7) & 0x7f]
+				| comp_maskl[3][t0 & 0x7f]
+				| comp_maskl[4][(t1 >> 21) & 0x7f]
+				| comp_maskl[5][(t1 >> 14) & 0x7f]
+				| comp_maskl[6][(t1 >> 7) & 0x7f]
+				| comp_maskl[7][t1 & 0x7f];
+
+		de_keysr[15 - round] =
+		en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f]
+				| comp_maskr[1][(t0 >> 14) & 0x7f]
+				| comp_maskr[2][(t0 >> 7) & 0x7f]
+				| comp_maskr[3][t0 & 0x7f]
+				| comp_maskr[4][(t1 >> 21) & 0x7f]
+				| comp_maskr[5][(t1 >> 14) & 0x7f]
+				| comp_maskr[6][(t1 >> 7) & 0x7f]
+				| comp_maskr[7][t1 & 0x7f];
+	}
+	return(0);
+}
+
+static int
+do_des(l_in, r_in, l_out, r_out, count)
+	unsigned int l_in, r_in, *l_out, *r_out;
+	int count;
+{
+	/*
+	 *	l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format.
+	 */
+	unsigned int	l, r, *kl, *kr, *kl1, *kr1;
+	unsigned int	f = 0, r48l, r48r;
+	int		round;
+
+	if (count == 0) {
+		return(1);
+	} else if (count > 0) {
+		/*
+		 * Encrypting
+		 */
+		kl1 = en_keysl;
+		kr1 = en_keysr;
+	} else {
+		/*
+		 * Decrypting
+		 */
+		count = -count;
+		kl1 = de_keysl;
+		kr1 = de_keysr;
+	}
+
+	/*
+	 *	Do initial permutation (IP).
+	 */
+	l = ip_maskl[0][l_in >> 24]
+	  | ip_maskl[1][(l_in >> 16) & 0xff]
+	  | ip_maskl[2][(l_in >> 8) & 0xff]
+	  | ip_maskl[3][l_in & 0xff]
+	  | ip_maskl[4][r_in >> 24]
+	  | ip_maskl[5][(r_in >> 16) & 0xff]
+	  | ip_maskl[6][(r_in >> 8) & 0xff]
+	  | ip_maskl[7][r_in & 0xff];
+	r = ip_maskr[0][l_in >> 24]
+	  | ip_maskr[1][(l_in >> 16) & 0xff]
+	  | ip_maskr[2][(l_in >> 8) & 0xff]
+	  | ip_maskr[3][l_in & 0xff]
+	  | ip_maskr[4][r_in >> 24]
+	  | ip_maskr[5][(r_in >> 16) & 0xff]
+	  | ip_maskr[6][(r_in >> 8) & 0xff]
+	  | ip_maskr[7][r_in & 0xff];
+
+	while (count--) {
+		/*
+		 * Do each round.
+		 */
+		kl = kl1;
+		kr = kr1;
+		round = 16;
+		while (round--) {
+			/*
+			 * Expand R to 48 bits (simulate the E-box).
+			 */
+			r48l	= ((r & 0x00000001) << 23)
+				| ((r & 0xf8000000) >> 9)
+				| ((r & 0x1f800000) >> 11)
+				| ((r & 0x01f80000) >> 13)
+				| ((r & 0x001f8000) >> 15);
+
+			r48r	= ((r & 0x0001f800) << 7)
+				| ((r & 0x00001f80) << 5)
+				| ((r & 0x000001f8) << 3)
+				| ((r & 0x0000001f) << 1)
+				| ((r & 0x80000000) >> 31);
+			/*
+			 * Do salting for crypt() and friends, and
+			 * XOR with the permuted key.
+			 */
+			f = (r48l ^ r48r) & saltbits;
+			r48l ^= f ^ *kl++;
+			r48r ^= f ^ *kr++;
+			/*
+			 * Do sbox lookups (which shrink it back to 32 bits)
+			 * and do the pbox permutation at the same time.
+			 */
+			f = psbox[0][m_sbox[0][r48l >> 12]]
+			  | psbox[1][m_sbox[1][r48l & 0xfff]]
+			  | psbox[2][m_sbox[2][r48r >> 12]]
+			  | psbox[3][m_sbox[3][r48r & 0xfff]];
+			/*
+			 * Now that we've permuted things, complete f().
+			 */
+			f ^= l;
+			l = r;
+			r = f;
+		}
+		r = l;
+		l = f;
+	}
+	/*
+	 * Do final permutation (inverse of IP).
+	 */
+	*l_out	= fp_maskl[0][l >> 24]
+		| fp_maskl[1][(l >> 16) & 0xff]
+		| fp_maskl[2][(l >> 8) & 0xff]
+		| fp_maskl[3][l & 0xff]
+		| fp_maskl[4][r >> 24]
+		| fp_maskl[5][(r >> 16) & 0xff]
+		| fp_maskl[6][(r >> 8) & 0xff]
+		| fp_maskl[7][r & 0xff];
+	*r_out	= fp_maskr[0][l >> 24]
+		| fp_maskr[1][(l >> 16) & 0xff]
+		| fp_maskr[2][(l >> 8) & 0xff]
+		| fp_maskr[3][l & 0xff]
+		| fp_maskr[4][r >> 24]
+		| fp_maskr[5][(r >> 16) & 0xff]
+		| fp_maskr[6][(r >> 8) & 0xff]
+		| fp_maskr[7][r & 0xff];
+	return(0);
+}
+
+static int
+des_cipher(in, out, salt, count)
+	const char *in;
+	char *out;
+	int salt;
+	int count;
+{
+	unsigned int l_out, r_out, rawl, rawr;
+	unsigned int x[2];
+	int	retval;
+
+	if (!des_initialised)
+		des_init();
+
+	setup_salt(salt);
+
+	memcpy(x, in, sizeof x);
+	rawl = md_ntohl(x[0]);
+	rawr = md_ntohl(x[1]);
+	retval = do_des(rawl, rawr, &l_out, &r_out, count);
+
+	x[0] = md_htonl(l_out);
+	x[1] = md_htonl(r_out);
+	memcpy(out, x, sizeof x);
+	return(retval);
+}
+
+char *
+xcrypt(key, setting)
+	const char *key;
+	const char *setting;
+{
+	int		i;
+	unsigned int	count, salt, l, r0, r1, keybuf[2];
+	unsigned char		*p, *q;
+	static unsigned char	output[21];
+
+	if (!des_initialised)
+		des_init();
+
+	/*
+	 * Copy the key, shifting each character up by one bit
+	 * and padding with zeros.
+	 */
+	q = (unsigned char *) keybuf;
+	while ((q - (unsigned char *) keybuf) < sizeof(keybuf)) {
+		if ((*q++ = *key << 1))
+			key++;
+	}
+	if (des_setkey((unsigned char *) keybuf))
+		return(NULL);
+
+	if (*setting == _PASSWORD_EFMT1) {
+		/*
+		 * "new"-style:
+		 *	setting - underscore, 4 bytes of count, 4 bytes of salt
+		 *	key - unlimited characters
+		 */
+		for (i = 1, count = 0; i < 5; i++)
+			count |= ascii_to_bin(setting[i]) << (i - 1) * 6;
+
+		for (i = 5, salt = 0; i < 9; i++)
+			salt |= ascii_to_bin(setting[i]) << (i - 5) * 6;
+
+		while (*key) {
+			/*
+			 * Encrypt the key with itself.
+			 */
+			if (des_cipher((unsigned char*)keybuf, (unsigned char*)keybuf, 0, 1))
+				return(NULL);
+			/*
+			 * And XOR with the next 8 characters of the key.
+			 */
+			q = (unsigned char *) keybuf;
+			while (((q - (unsigned char *) keybuf) < sizeof(keybuf)) &&
+					*key)
+				*q++ ^= *key++ << 1;
+
+			if (des_setkey((unsigned char *) keybuf))
+				return(NULL);
+		}
+		strncpy((char *)output, setting, 9);
+
+		/*
+		 * Double check that we weren't given a short setting.
+		 * If we were, the above code will probably have created
+		 * wierd values for count and salt, but we don't really care.
+		 * Just make sure the output string doesn't have an extra
+		 * NUL in it.
+		 */
+		output[9] = '\0';
+		p = output + strlen((const char *)output);
+	} else {
+		/*
+		 * "old"-style:
+		 *	setting - 2 bytes of salt
+		 *	key - up to 8 characters
+		 */
+		count = 25;
+
+		salt = (ascii_to_bin(setting[1]) << 6)
+		     |  ascii_to_bin(setting[0]);
+
+		output[0] = setting[0];
+		/*
+		 * If the encrypted password that the salt was extracted from
+		 * is only 1 character long, the salt will be corrupted.  We
+		 * need to ensure that the output string doesn't have an extra
+		 * NUL in it!
+		 */
+		output[1] = setting[1] ? setting[1] : output[0];
+
+		p = output + 2;
+	}
+	setup_salt(salt);
+	/*
+	 * Do it.
+	 */
+	if (do_des(0, 0, &r0, &r1, count))
+		return(NULL);
+	/*
+	 * Now encode the result...
+	 */
+	l = (r0 >> 8);
+	*p++ = ascii64[(l >> 18) & 0x3f];
+	*p++ = ascii64[(l >> 12) & 0x3f];
+	*p++ = ascii64[(l >> 6) & 0x3f];
+	*p++ = ascii64[l & 0x3f];
+
+	l = (r0 << 16) | ((r1 >> 16) & 0xffff);
+	*p++ = ascii64[(l >> 18) & 0x3f];
+	*p++ = ascii64[(l >> 12) & 0x3f];
+	*p++ = ascii64[(l >> 6) & 0x3f];
+	*p++ = ascii64[l & 0x3f];
+
+	l = r1 << 2;
+	*p++ = ascii64[(l >> 12) & 0x3f];
+	*p++ = ascii64[(l >> 6) & 0x3f];
+	*p++ = ascii64[l & 0x3f];
+	*p = 0;
+
+	return((char *)output);
+}