changeset 125:adfa37e67084

Import Advanced Rogue 7.7 from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Fri, 08 May 2015 15:24:40 -0400
parents d10fc4a065ac
children b786053d2f37
files arogue7/LICENSE.TXT arogue7/Makefile arogue7/actions.c arogue7/aguide.mm arogue7/arogue77.doc arogue7/arogue77.html arogue7/arogue77.sln arogue7/arogue77.vcproj arogue7/chase.c arogue7/command.c arogue7/daemon.c arogue7/daemons.c arogue7/eat.c arogue7/effects.c arogue7/encumb.c arogue7/fight.c arogue7/init.c arogue7/io.c arogue7/list.c arogue7/mach_dep.h arogue7/main.c arogue7/maze.c arogue7/mdport.c arogue7/misc.c arogue7/monsters.c arogue7/move.c arogue7/network.h arogue7/new_level.c arogue7/options.c arogue7/outside.c arogue7/pack.c arogue7/passages.c arogue7/player.c arogue7/potions.c arogue7/rings.c arogue7/rip.c arogue7/rogue.c arogue7/rogue.h arogue7/rooms.c arogue7/save.c arogue7/scrolls.c arogue7/state.c arogue7/sticks.c arogue7/things.c arogue7/trader.c arogue7/util.c arogue7/vers.c arogue7/weapons.c arogue7/wear.c arogue7/wizard.c arogue7/xcrypt.c
diffstat 51 files changed, 37593 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/LICENSE.TXT	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,179 @@
+Copyright (C) 1984, 1985, 1986 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, 1986 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 (state.c, mdport.c) are based on the work 
+of Nicholas J. Kisseberth. Used under license:
+
+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.
+
+===========================================================================
+
+Portions of this software (xcrypt.c) are based on the work 
+of David Burren. Used under license:
+
+FreeSec: libcrypt
+
+Copyright (C) 1994 David Burren
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. Neither the name(s) of the author(s) nor the names of other contributors
+   may be used to endorse or promote products derived from this software
+   without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/Makefile	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,193 @@
+#
+# Makefile for rogue
+#
+# 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.
+#
+
+#
+# Makefile for rogue
+#
+
+
+DISTNAME=arogue7.7.1
+PROGRAM=arogue77
+
+O=o
+
+HDRS=	rogue.h mach_dep.h network.h
+
+OBJS1 =	vers.$(O) actions.$(O) chase.$(O) command.$(O) daemon.$(O) \
+	daemons.$(O) eat.$(O) effects.$(O) encumb.$(O) fight.$(O) init.$(O) \
+        io.$(O) list.$(O) main.$(O) maze.$(O) mdport.$(O) misc.$(O) \
+        monsters.$(O)
+OBJS2 = move.$(O) new_level.$(O) options.$(O) outside.$(O) 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) weapons.$(O) wear.$(O) wizard.$(O) xcrypt.$(O)
+OBJS  =	$(OBJS1) $(OBJS2)
+
+CFILES=	vers.c actions.c chase.c command.c daemon.c \
+	daemons.c eat.c effects.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_C=	
+DOCSRC= aguide.mm
+DOCS  = $(PROGRAM).doc $(PROGRAM).html
+MISC  =	Makefile $(MISC_C) LICENSE.TXT $(PROGRAM).sln $(PROGRAM).vcproj $(DOCS)\
+        $(DOCSRC)
+
+CC    = gcc
+ROPTS =
+COPTS = -O3
+CFLAGS= $(COPTS) $(ROPTS) 
+LIBS =	-lcurses
+RM    = rm -f
+
+.SUFFIXES: .obj
+
+.c.obj:
+	$(CC) $(CFLAGS) /c $*.c
+    
+$(PROGRAM): $(HDRS) $(OBJS)
+	$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o $@
+    
+clean:
+	$(RM) $(OBJS1)
+	$(RM) $(OBJS2)
+	$(RM) core a.exe a.out a.exe.stackdump $(PROGRAM) $(PROGRAM).exe $(PROGRAM).lck
+	$(RM) $(PROGRAM).tar $(PROGRAM).tar.gz $(PROGRAM).zip 
+    
+dist.src:
+	make clean
+	tar cf $(DISTNAME)-src.tar $(CFILES) $(HDRS) $(MISC)
+	gzip -f $(DISTNAME)-src.tar
+
+doc.nroff:
+	tbl aguide.mm | nroff -mm | colcrt - > arogue77.doc
+
+doc.groff:
+	groff -P-c -t -mm -Tascii aguide.mm | sed -e 's/.\x08//g' > arogue77.doc
+	groff -t -mm -Thtml aguide.mm > arogue77.ht
+
+dist.irix:
+	make clean
+	make CC=cc COPTS="-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 COPTS="-qmaxmem=16768 -O3 -qstrict" $(PROGRAM)
+	tar cf $(DISTNAME)-aix.tar $(PROGRAM) LICENSE.TXT $(DOCS)
+	gzip -f $(DISTNAME)-aix.tar
+
+dist.linux:
+	make clean
+	make $(PROGRAM)
+	tar cf $(DISTNAME)-linux.tar $(PROGRAM) LICENSE.TXT $(DOCS)
+	gzip -f $(DISTNAME)-linux.tar
+	
+dist.interix:
+	@$(MAKE) clean
+	@$(MAKE) COPTS="-ansi" $(PROGRAM)
+	tar cf $(DISTNAME)-interix.tar $(PROGRAM) LICENSE.TXT $(DOCS)
+	gzip -f $(DISTNAME)-interix.tar
+	
+dist.cygwin:
+	@$(MAKE) --no-print-directory clean
+	@$(MAKE) --no-print-directory $(PROGRAM)
+	tar cf $(DISTNAME)-cygwin.tar $(PROGRAM).exe LICENSE.TXT $(DOCS)
+	gzip -f $(DISTNAME)-cygwin.tar
+
+#
+# Use MINGW32-MAKE to build this target
+#
+dist.mingw32:
+	@$(MAKE) --no-print-directory RM="cmd /c del" clean
+	@$(MAKE) --no-print-directory LIBS="-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 LIBS="-lcurses" $(PROGRAM)
+	tar cf $(DISTNAME)-msys.tar $(PROGRAM).exe LICENSE.TXT $(DOCS)
+	gzip -f $(DISTNAME)-msys.tar
+	
+dist.djgpp:
+	@$(MAKE) --no-print-directory clean
+	@$(MAKE) --no-print-directory LDFLAGS="-L$(DJDIR)/LIB" \
+	LIBS="-lpdcurses" $(PROGRAM)
+	rm -f $(DISTNAME)-djgpp.zip
+	zip $(DISTNAME)-djgpp.zip $(PROGRAM).exe LICENSE.TXT $(DOCS)
+
+#
+# Use NMAKE to build this targer
+#
+dist.win32:
+	@$(MAKE) /NOLOGO O="obj" RM="-del" clean
+	@$(MAKE) /NOLOGO O="obj" CC="CL" \
+	    LIBS="..\pdcurses\pdcurses.lib shfolder.lib user32.lib Advapi32.lib" \
+	    COPTS="-nologo -I..\pdcurses \
+	    -Ox -wd4033 -wd4716" $(PROGRAM)
+	-del $(DISTNAME)-win32.zip
+	zip $(DISTNAME)-win32.zip $(PROGRAM).exe LICENSE.TXT $(DOCS)
+
+
+actions.o:	rogue.h
+chase.o:	rogue.h
+command.o:	rogue.h
+command.o:	mach_dep.h
+daemon.o:	rogue.h
+daemons.o:	rogue.h
+eat.o:		rogue.h
+edit.o:		mach_dep.h
+edit.o:		rogue.h
+effects.o:	rogue.h
+encumb.o:	rogue.h
+fight.o:	rogue.h
+init.o:		rogue.h
+init.o:		mach_dep.h
+io.o:		rogue.h
+list.o:		rogue.h
+main.o:		mach_dep.h
+main.o:		network.h
+main.o:		rogue.h
+maze.o:		rogue.h
+misc.o:		rogue.h
+monsters.o:	rogue.h
+move.o:		rogue.h
+new_level.o:	rogue.h
+options.o:	rogue.h
+outside.o:	rogue.h
+pack.o:		rogue.h
+passages.o:	rogue.h
+player.o:	rogue.h
+potions.o:	rogue.h
+rings.o:	rogue.h
+rip.o:		mach_dep.h
+rip.o:		network.h
+rip.o:		rogue.h
+rogue.o:	rogue.h
+rooms.o:	rogue.h
+save.o:		rogue.h
+save.o:		mach_dep.h
+scrolls.o:	rogue.h
+sticks.o:	rogue.h
+things.o:	rogue.h
+trader.o:	rogue.h
+util.o:		rogue.h
+weapons.o:	rogue.h
+wear.o:		rogue.h
+wizard.o:	rogue.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/actions.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,982 @@
+/*
+ * actions.c  -  functions for dealing with monster actions
+ *
+ * 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.
+ */
+
+#include <ctype.h>
+#include <limits.h>
+#include "curses.h"
+#include "rogue.h"
+#define	MAXINT	INT_MAX
+#define	MININT	INT_MIN
+/* 
+ * Did we disrupt a spell? 
+ */
+dsrpt_monster(tp, always, see_him)
+register struct thing *tp;
+bool always, see_him;
+{
+    switch (tp->t_action) {
+    case A_SUMMON:
+    case A_MISSILE:
+    case A_SLOW:
+	tp->t_action = A_NIL; /* Just make the old fellow start over again */
+	tp->t_no_move = movement(tp);
+	tp->t_using = NULL;/* Just to be on the safe side */
+	turn_on(*tp, WASDISRUPTED);
+	if (see_him)
+	    msg("%s's spell has been disrupted.",prname(monster_name(tp),TRUE));
+	/*
+	 * maybe choose something else to do next time since player
+	 * is disrupting us
+	 */
+	tp->t_summon *= 2;
+	tp->t_cast /= 2;
+	return;
+    }
+
+    /* We may want to disrupt other actions, too */
+    if (always) {
+	tp->t_action = A_NIL; /* Just make the old fellow start over again */
+	tp->t_no_move = movement(tp);
+	tp->t_using = NULL;/* Just to be on the safe side */
+    }
+}
+
+dsrpt_player()
+{
+    int which, action;
+    struct linked_list *item;
+    struct object *obj;
+    
+    action = player.t_action;
+    which = player.t_selection;
+
+    switch (action) {
+    case C_CAST: /* Did we disrupt a spell? */
+    case C_PRAY:
+    case C_CHANT:
+    {
+	msg("Your %s was disrupted!", action == C_CAST ? "spell" : "prayer");
+
+	/* Charge him anyway */
+	if (action == C_CAST)
+	    spell_power += magic_spells[which].s_cost;
+	else if (action == C_PRAY)
+	    pray_time += cleric_spells[which].s_cost;
+	else if (action == C_CHANT)
+	    chant_time += druid_spells[which].s_cost;
+    }
+    when C_COUNT: /* counting of gold? */
+    {
+	if (purse > 0) {
+	    msg("Your gold goes flying everywhere!");
+	    do {
+		item = spec_item(GOLD, NULL, NULL, NULL);
+		obj = OBJPTR(item);
+		obj->o_count = min(purse, rnd(10)+1);
+		purse -= obj->o_count;
+		obj->o_pos = hero;
+		fall(item, FALSE);
+	    } while (purse > 0 && rnd(10) != 1);
+	}
+    }
+    when C_EAT:
+	msg("You gag on your food for a moment.");
+	del_pack(player.t_using);
+	
+    when A_PICKUP:
+	msg("You drop what you are picking up!");
+
+    when C_SEARCH:	/* searching for traps and secret doors... */
+	msg("Oww....You decide to stop searching.");
+	count = 0;	/* don't search again */
+
+    when C_SETTRAP:
+	msg("Oww....You can't get a trap set.");
+
+    when A_NIL:
+    default:
+	return;
+    }
+    player.t_no_move = movement(&player); /* disoriented for a while */
+    player.t_action = A_NIL;
+    player.t_selection = 0;
+    player.t_using = NULL;
+}
+
+/*
+ * m_act:
+ *	If the critter isn't doing anything, choose an action for it.
+ *	Otherwise, let it perform its chosen action.
+ */
+
+m_act(tp)
+register struct thing *tp;
+{
+    struct object *obj;
+    bool flee;	/* Are we scared? */
+
+    /* What are we planning to do? */
+    switch (tp->t_action) {
+	default:
+	    /* An unknown action! */
+	    msg("Unknown monster action (%d)", tp->t_action);
+
+	    /* Fall through */
+
+	case A_NIL:
+	    /* If the monster is fairly intelligent and about to die, it
+	     * may turn tail and run.  But if we are a FRIENDLY creature
+	     * in the hero's service, don't run.
+	     */
+	    if (off(*tp, ISFLEE)					&&
+		tp->t_stats.s_hpt < tp->maxstats.s_hpt			&&
+		tp->t_stats.s_hpt < max(10, tp->maxstats.s_hpt/6)	&&
+		(off(*tp, ISFRIENDLY) || tp->t_dest != &hero)		&&
+		rnd(25) < tp->t_stats.s_intel) {
+		    turn_on(*tp, ISFLEE);
+
+		    /* It is okay to turn tail */
+		    tp->t_oldpos = tp->t_pos;
+		}
+
+	    /* Should the monster run away? */
+	    flee = on(*tp, ISFLEE) ||
+		((tp->t_dest == &hero) && on(player, ISINWALL) &&
+		 off(*tp, CANINWALL));
+
+	    m_select(tp, flee);	/* Select an action */
+	    return;
+
+	when A_ATTACK:
+	    /* 
+	     * We're trying to attack the player or monster at t_newpos 
+	     * if the prey moved, do nothing
+	     */
+	    obj = tp->t_using ? OBJPTR(tp->t_using) : NULL;
+	    if (ce(tp->t_newpos, hero)) {
+		attack(tp, obj, FALSE);
+	    }
+	    else if (mvwinch(mw, tp->t_newpos.y, tp->t_newpos.x) &&
+		     step_ok(tp->t_newpos.y, tp->t_newpos.x, FIGHTOK, tp)) {
+		skirmish(tp, &tp->t_newpos, obj, FALSE);
+	    }
+
+	when A_SELL:
+	    /* Is the player still next to us? */
+	    if (ce(tp->t_newpos, hero)) sell(tp);
+
+	    /* The darned player moved away */
+	    else if (off(player, ISBLIND) &&
+		cansee(unc(tp->t_pos)) &&
+		(off(*tp, ISINVIS)     || on(player, CANSEE)) &&
+		(off(*tp, ISSHADOW)    || on(player, CANSEE)) &&
+		(off(*tp, CANSURPRISE) || ISWEARING(R_ALERT)))
+		msg("%s grunts with frustration",prname(monster_name(tp),TRUE));
+
+	when A_MOVE:
+	    /* Let's try to move */
+	    do_chase(tp);
+
+	    /* If t_no_move > 0, we found that we have to fight! */
+	    if (tp->t_no_move > 0) return;
+
+	when A_BREATHE:
+	    /* Breathe on the critter */
+	    m_breathe(tp);
+
+	when A_SLOW:
+	    /* make him move slower */
+	    add_slow();
+	    turn_off(*tp, CANSLOW);
+
+	when A_MISSILE:
+	    /* Start up a magic missile spell */
+	    m_spell(tp);
+
+	when A_SONIC:
+	    /* Let out a sonic blast! */
+	    m_sonic(tp);
+
+	when A_THROW:
+	    /* We're throwing something (like an arrow) */
+	    missile(tp->t_newpos.y, tp->t_newpos.x, tp->t_using, tp);
+
+	when A_SUMMON:
+	    /* We're summoning help */
+	    m_summon(tp);
+
+	when A_USERELIC:
+	    /* Use our relic */
+	    m_use_relic(tp);
+
+	when A_USEWAND:
+	    /* use the wand we have */
+	    m_use_wand(tp);
+    }
+
+    /* No action now */
+    tp->t_action = A_NIL;
+    tp->t_using = NULL;
+}
+
+/*
+ * m_breathe:
+ *	Breathe in the chosen direction.
+ */
+
+m_breathe(tp)
+register struct thing *tp;
+{
+    register int damage;
+    register char *breath;
+
+    damage = tp->t_stats.s_hpt;
+    turn_off(*tp, CANSURPRISE);
+
+    /* 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 */
+    shoot_bolt(tp, tp->t_pos, tp->t_newpos, FALSE, 
+		    tp->t_index, breath, damage);
+
+    running = FALSE;
+    if (fight_flush) md_flushinp();
+}
+
+/*
+ * m_select:
+ *	Select an action for the monster.
+ */
+
+m_select(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 */
+    int dist = MININT;
+    int mindist = MAXINT, maxdist = MININT;
+    bool rundoor;			/* TRUE means run to a door */
+    char sch;
+    coord *last_door=0,			/* Door we just came from */
+	   this;			/* Temporary destination for chaser */
+
+    rer = roomin(&th->t_pos);	/* Find room of chaser */
+    ree = roomin(th->t_dest);	/* Find room of chasee */
+
+    /* First see if we want to use an ability or weapon */
+    if (m_use_it(th, flee, rer, ree)) return;
+
+    /*
+     * We don't count monsters on doors as inside rooms here because when
+     * a monster is in a room and the player is not in that room, the
+     * monster looks for the best door out.  If we counted doors as part
+     * of the room, the monster would already be on the best door out;
+     * so he would never move.
+     */
+    if ((sch = CCHAR( mvwinch(stdscr, th->t_pos.y, th->t_pos.x) )) == DOOR ||
+	sch == SECRETDOOR || sch == PASSAGE) {
+	rer = NULL;
+    }
+    this = *th->t_dest;
+
+    /*
+     * If we are in a room heading for the player and the player is not
+     * in the room with us, we run to the "best" door.
+     * If we are in a room fleeing from the player, then we run to the
+     * "best" door if he IS in the same room.
+     *
+     * Note:  We don't bother with doors in mazes or if we can walk
+     * through walls.
+     */
+    if (rer != NULL && levtype != MAZELEV && 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 */
+	      *entrance;			/* Place just inside doorway */
+	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, *th->t_dest))) { /* Prey should not
+						             * be at door if
+							     * we are running
+							     * away
+							     */
+	    /* Make sure the player is not in the doorway, either */
+	    entrance = doorway(rer, th->t_doorgoal);
+	    if (!flee || entrance == NULL || !ce(*entrance, *th->t_dest)) {
+		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 someone and
+		 * he is standing on it.  Also, don't count it if he is
+		 * standing in the doorway.
+		 */
+		if (flee) {
+		    if (ce(*exit, *th->t_dest)) continue;
+
+		    entrance = doorway(rer, exit);
+		    if (entrance != NULL && ce(*entrance, *th->t_dest))
+			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 */
+
+    /* Now select someplace to go and start the action */
+    chase(th, &this, rer, ree, flee);
+}
+
+/*
+ * m_sonic:
+ *	The monster is sounding a sonic blast.
+ */
+
+m_sonic(tp)
+register struct thing *tp;
+{
+    register int damage;
+    static struct object blast =
+    {
+	MISSILE, {0, 0}, "", 0, "", "150" , NULL, 0, 0, 0, 0
+    };
+
+    turn_off(*tp, CANSONIC);
+    turn_off(*tp, CANSURPRISE);
+    do_motion(&blast, tp->t_newpos.y, tp->t_newpos.x, tp);
+    damage = 150;
+    if (save(VS_BREATH, &player, -3))
+	damage /= 2;
+    msg ("%s's sonic blast hits you", prname(monster_name(tp), TRUE));
+    if ((pstats.s_hpt -= damage) <= 0)
+	death(tp->t_index);
+
+    running = FALSE;
+    if (fight_flush) md_flushinp();
+    dsrpt_player();
+}
+
+/*
+ * m_spell:
+ *	The monster casts a spell.  Currently this is limited to
+ *	magic missile.
+ */
+m_spell(tp)
+register struct thing *tp;
+{
+    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, tp->t_newpos.y, tp->t_newpos.x, tp);
+    hit_monster(unc(missile.o_pos), &missile, tp);
+    turn_off(*tp, CANMISSILE);
+    turn_off(*tp, CANSURPRISE);
+
+    running = FALSE;
+    if (fight_flush) md_flushinp();
+}
+
+/*
+ * m_summon:
+ *	Summon aid.
+ */
+
+m_summon(tp)
+register struct thing *tp;
+{
+    register char *helpname, *mname;
+    int fail, numsum;
+    register int which, i;
+
+    /* Let's make sure our prey is still here */
+    if (!cansee(unc(tp->t_pos)) || fallpos(&hero, FALSE, 2) == NULL) return;
+
+    /*
+     * Non-uniques can only summon once.  Uniques get fewer
+     * creatures with each successive summoning. Also, the
+     * probability of summoning goes down
+     */
+    if (off(*tp, ISUNIQUE))
+	    turn_off(*tp, CANSUMMON);
+
+    turn_off(*tp, CANSURPRISE);
+    mname = monster_name(tp);
+    helpname = monsters[tp->t_index].m_typesum;
+    which = findmindex(helpname);
+
+    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("%s appears dismayed", prname(mname, TRUE));
+	    monsters[tp->t_index].m_numsum = 0;
+	}
+	else {
+	    msg("%s summons %ss for help", prname(mname, TRUE), helpname);
+	}
+    }
+    else {
+	if (monsters[which].m_normal == FALSE) /* genocided? */
+	    monsters[tp->t_index].m_numsum = 0;
+	else {
+	    msg("%ss seem to appear from nowhere!", helpname);
+	}
+    }
+    numsum = monsters[tp->t_index].m_numsum;
+    if (numsum && on(*tp, ISUNIQUE)) {   /* UNIQUEs summon less each time */
+	monsters[tp->t_index].m_numsum--; 
+	tp->t_summon *= 2; /* cut probability in half */
+    }
+
+    /*
+     * try to make all the creatures around player but remember
+     * if unsuccessful
+     */
+    for (i=0, fail=0; i<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);
+    turn_on(*tp, HASSUMMONED);
+}
+
+/*
+ * m_use_it:
+ *	See if the monster (tp) has anything useful it can do
+ *	(ie. an ability or a weapon) other than just move.
+ */
+
+bool
+m_use_it(tp, flee, rer, ree)
+register struct thing *tp;
+bool flee;
+register struct room *rer, *ree;
+{
+    int dist;
+    register coord *ee = tp->t_dest, *er = &tp->t_pos; 
+    coord *shoot_dir;
+    struct linked_list *weapon;
+    struct thing *prey;
+    bool dest_player;	/* Are we after the player? */
+
+    /*
+     * If we are fleeing, there's a chance, depending on our
+     * intelligence, that we'll just run in terror.
+     */
+    if (flee && rnd(25) >= tp->t_stats.s_intel) return(FALSE);
+
+    /*
+     * Make sure that we have a living destination, and record whether
+     * it is the player.
+     */
+    if (ee != NULL) {
+        if (ce(*ee, hero)) {
+	    dest_player = TRUE;
+	    prey = &player;
+	}
+	else {
+	    struct linked_list *item;
+
+	    dest_player = FALSE;
+
+	    /* What is the monster we're chasing? */
+	    item = find_mons(ee->y, ee->x);
+	    if (item != NULL) prey = THINGPTR(item);
+	    else return(FALSE);
+	}
+    }
+    else return(FALSE);
+
+    /*
+     * If we are friendly to the hero, we don't do anything.
+     */
+    if (on(*tp, ISFRIENDLY) && dest_player) return(FALSE);
+
+    /*
+     * Also, for now, if our prey is in a wall, we won't do
+     * anything.  The prey must be in the same room as we are OR
+     * we must have a straight shot at him.  Note that
+     * shoot_dir must get set before rer is checked so
+     * that we get a valid value.
+     */
+    if (on(*prey, ISINWALL) ||
+	((shoot_dir = can_shoot(er, ee)) == NULL &&
+	(rer == NULL || rer != ree)))
+	return(FALSE);
+
+    /*
+     * If we can't see the prey then forget it
+     */
+    if (on(*prey, ISINVIS) && off(*tp, CANSEE))
+	return(FALSE);
+
+    /* How far are we from our prey? */
+    dist = DISTANCE(er->y, er->x, ee->y, ee->x);
+
+    /* 
+     * Shall we summon aid so we don't have to get our hands dirty? 
+     * For now, we will only summon aid against the player.
+     * We'll wait until he's within 2 dots of a missile length.
+     */
+    if (on(*tp, CANSUMMON) && dest_player 			&&
+	dist < (BOLT_LENGTH+2)*(BOLT_LENGTH+2)			&&
+	rnd(tp->t_summon) < tp->t_stats.s_lvl			&&
+	monsters[tp->t_index].m_numsum > 0			&&
+	fallpos(&hero, FALSE, 2) != NULL) {
+	tp->t_action = A_SUMMON;	/* We're going to summon help */
+	tp->t_no_move = movement(tp); /* It takes time! */
+	return(TRUE);
+    }
+
+    /*
+     * If the creature can cast a slow spell and if the prey is within
+     * 2 dots of a missile fire, then see whether we will cast it.
+     * if next to player, lessen chance because we don't like being
+     * disrupted
+     */
+    if (on(*tp, CANSLOW) && dest_player			&& 
+	dist < (BOLT_LENGTH+5)*(BOLT_LENGTH+5)		&&
+	rnd(100) < (dist > 3 ? tp->t_cast : tp->t_cast/2)) {
+	    tp->t_action = A_SLOW;		/* We're going to slow him */
+	    tp->t_no_move = 3 * movement(tp);	/* Takes time! */
+	    debug("casting slow spell!");
+	    return(TRUE);
+    }
+
+    /*
+     * If we have a special magic item, we might use it.  We will restrict
+     * this options to uniques with relics and creatures with wands for now.  
+     * Also check for the quartermaster. Don't want him shooting wands....
+     */
+    if ((on(*tp, ISUNIQUE) || on(*tp, CARRYSTICK)) && 
+	off(*tp, CANSELL) && dest_player	   &&
+	m_use_pack(tp, er, ee, dist, shoot_dir)) {
+	    return(TRUE);
+    }
+
+    /* From now on, we must have a direct shot at the prey */
+    if (shoot_dir == NULL) return(FALSE);
+
+    /* We may use a sonic blast if we can, only on the player */
+    if (on(*tp, CANSONIC)		&& 
+	dest_player			&&
+	(dist < BOLT_LENGTH*2)		&&
+	(rnd(100) < tp->t_breathe)) {
+	tp->t_newpos = *shoot_dir;	/* Save the direction */
+	tp->t_action = A_SONIC;	/* We're going to sonic blast */
+	tp->t_no_move = 2 * movement(tp); /* Takes 2 movement periods */
+    }
+
+    /* If we can breathe, we may do so */
+    else if (on(*tp, CANBREATHE)		&&
+	 (dist < BOLT_LENGTH*BOLT_LENGTH)	&&
+	 (rnd(100) < tp->t_breathe)) {
+	    tp->t_newpos = *shoot_dir;	/* Save the direction */
+	    tp->t_action = A_BREATHE;	/* We're going to breathe */
+	    tp->t_no_move = movement(tp); /* It takes 1 movement period */
+    }
+
+    /* 
+     * We may shoot missiles if we can 
+     * if next to player, lessen chance so we don't get disrupted as often
+     */
+    else if (on(*tp,CANMISSILE) && 
+	     rnd(100) < (dist > 3 ? tp->t_cast : tp->t_cast/2)){
+	    tp->t_newpos = *shoot_dir;	/* Save the direction */
+	    tp->t_action = A_MISSILE;	/* We're going to shoot MM's */
+	    tp->t_no_move = 3 * movement(tp); /* Takes time! */
+    }
+
+    /* 
+     * If we can shoot or throw something, we might do so.
+     * If next to player, then forget it
+     */
+    else if ((on(*tp,CANSHOOT)		|| on(*tp,CARRYWEAPON) || 
+	      on(*tp,CARRYDAGGER)	|| on(*tp, CARRYAXE))		&&
+	      dist > 3							&&
+	      off(*tp, CANSELL)						&&
+	     (weapon = get_hurl(tp))) {
+	    tp->t_newpos = *shoot_dir;	/* Save the direction */
+	    tp->t_action = A_THROW;	/* We're going to throw something */
+	    tp->t_using = weapon;	/* Save our weapon */
+	    tp->t_no_move = 2 * movement(tp); /* Takes 2 movement periods */
+    }
+    
+    /* We couldn't find anything to do */
+    else return(FALSE);
+
+    return(TRUE);
+
+}
+
+/*
+ * runners:
+ *	Make all the awake monsters try to do something.
+ */
+
+runners(segments)
+int segments;    /* Number of segments since last called */
+{
+    register struct linked_list *item;
+    register struct thing *tp;
+    register min_time = 20;	/* Minimum time until a monster can act */
+
+    /*
+     * 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 we are not awake, just skip us */
+	if (off(*tp, ISRUN) && off(*tp, ISHELD)) continue;
+
+	/* See if it's our turn */
+	tp->t_no_move -= segments;
+	if (tp->t_no_move > 0) {
+	    if (tp->t_no_move < min_time) min_time = tp->t_no_move;
+	    continue;
+	}
+
+	/* If we were frozen, we're moving now */
+	if (tp->t_action == A_FREEZE) tp->t_action = A_NIL;
+
+	if (on(*tp, ISHELD)) {
+	    /* Make sure the action and using are nil */
+	    tp->t_action = A_NIL;
+	    tp->t_using = NULL;
+
+	    /* Can we break free? */
+	    if (rnd(tp->t_stats.s_lvl) > 11) {
+		turn_off(*tp, ISHELD);
+		runto(tp, &hero);
+		if (cansee(tp->t_pos.y, tp->t_pos.x))
+		    msg("%s breaks free from the hold spell", 
+			prname(monster_name(tp), TRUE));
+	    }
+
+	    /* Too bad -- try again later */
+	    else tp->t_no_move = movement(tp);
+	}
+
+	/* Heal the creature if it's not in the middle of some action */
+	if (tp->t_action == A_NIL) doctor(tp);
+
+	while (off(*tp,ISELSEWHERE) &&
+	    off(*tp,ISDEAD) &&
+	       tp->t_no_move <= 0 && off(*tp, ISHELD) && on(*tp, ISRUN)) {
+	    /* Let's act (or choose an action if t_action = A_NIL) */
+	    m_act(tp);
+	}
+
+	if (off(*tp,ISELSEWHERE) && off(*tp,ISDEAD)) {
+	    if (tp->t_no_move < min_time) min_time = tp->t_no_move;
+	    if (tp->t_quiet < 0) tp->t_quiet = 0;
+	}
+    }
+    return(min_time);
+}
+
+/*
+ * See if a monster has some magic it can use.  Return TRUE if so.
+ * Only care about relics and wands for now.
+ */
+bool
+m_use_pack(monster, monst_pos, defend_pos, dist, shoot_dir)
+register struct thing *monster;
+register coord *monst_pos, *defend_pos;
+register int dist;
+register coord *shoot_dir;
+{
+    register struct object *obj;
+    register struct linked_list *pitem, *relic, *stick;
+    register int units = -1;
+
+    relic = stick = NULL;
+
+    for (pitem=monster->t_pack; pitem; pitem=next(pitem)) {
+	obj = OBJPTR(pitem);
+	if (obj->o_flags & ISCURSED) continue;
+	if (obj->o_type == RELIC) {
+	    switch (obj->o_which) {
+		case MING_STAFF:
+		    if (shoot_dir != NULL) {
+			units = 2;	/* Use 2 time units */
+			relic = pitem;
+		    }
+
+		when EMORI_CLOAK:
+		    if (obj->o_charges != 0	&& 
+			shoot_dir != NULL) {
+			    units = 2;	/* Use 2 time units */
+			    relic = pitem;
+		    }
+
+		when ASMO_ROD:
+		    /* The bolt must be able to reach the defendant */
+		    if (shoot_dir != NULL			&& 
+			dist < BOLT_LENGTH * BOLT_LENGTH) {
+			units = 2;	/* Use 2 time units */
+			relic = pitem;
+		    }
+
+		when BRIAN_MANDOLIN:
+		    /* The defendant must be the player and within 4 spaces */
+		    if (ce(*defend_pos, hero)		&& 
+			dist < 25			&&
+			player.t_action != A_FREEZE) {
+			units = 4;
+			relic = pitem;
+		    }
+
+		when GERYON_HORN:
+		    /* The defendant must be the player and within 5 spaces */
+		    if (ce(*defend_pos, hero)				     &&
+			dist < 25					     &&
+			(off(player,ISFLEE)|| player.t_dest!=&monster->t_pos)) {
+			units = 3;
+			relic = pitem;
+		    }
+	    }
+	}
+	if (obj->o_type == STICK) {
+	    if (obj->o_charges < 1) continue;
+	    switch(obj->o_which) {
+		case WS_ELECT:
+		case WS_FIRE:
+		case WS_COLD:
+		    /* The bolt must be able to reach the defendant */
+		    if (shoot_dir != NULL			&& 
+			dist < BOLT_LENGTH * BOLT_LENGTH) {
+			    units = 3;
+			    stick = pitem;
+		    }
+
+		when WS_MISSILE:
+		case WS_SLOW_M:
+		case WS_CONFMON:
+		case WS_PARALYZE:
+		case WS_MDEG:
+		case WS_FEAR:
+		    if (shoot_dir != NULL) {
+			units = 3;
+			stick = pitem;
+		    }
+		
+		otherwise:
+		    break;
+	    }
+	}
+    }
+
+    /* use relics in preference to all others */
+    if (relic) debug("chance to use relic = %d%%", monster->t_artifact);
+    if (stick) debug("chance to use stick = %d%%", monster->t_wand);
+    if (relic && rnd(100) < monster->t_artifact)  {
+	monster->t_action = A_USERELIC;
+	pitem = relic;
+    }
+    else if (stick && rnd(100) < monster->t_wand) {
+	/*
+	 * see if the monster will use the wand 
+	 */
+	pitem = stick;
+	monster->t_action = A_USEWAND;
+    }
+    else {
+	return(FALSE);
+    }
+
+    monster->t_no_move = units * movement(monster);
+    monster->t_using = pitem;
+    monster->t_newpos = *shoot_dir;
+    return(TRUE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/aguide.mm	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,799 @@
+.\"
+.\" aguide.mm
+.\"
+.\" 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.
+.\"
+.tr ~
+.nr Pt 1
+.ds HF 3 2 2 2 2 2 2
+.TL
+The Dungeons of Doom
+.AF Toolchest
+.AU " "
+.AS 1
+.P
+Rogue was introduced 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
+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.
+.AE
+.MT 4
+.H 1 INTRODUCTION
+Rogue is a screen-oriented fantasy game set in the ever-changing
+\fIDungeons of Doom\fR.
+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
+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
+\fIComplete Winner\fR.
+But even after finding the artifact, the player may wish to continue
+further to match wits with an \fIarch-devil\fR, \fIdemon prince\fR, or even a 
+\fIdeity\fR found far down in the dungeon.
+Defeating such a creature will gain the player many experience points,
+the basis for scoring in Rogue.
+.P
+It is very difficult to return from the \fIDungeons of Doom\fR.
+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.
+.H 1 "CHARACTER CLASSES"
+Before placing the player in the dungeon, the game requests the player
+to select what type of character they would like to be:~ a fighter, a magic user, a cleric, 
+a druid, a thief, a paladin, a ranger, a monk, or an assassin.
+.H 2 "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 \fIfighter\fR 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 12 extra hit points for every new experience
+level.
+.H 2 "The Magician"
+A Magician is able to "cast" spells.
+The number and variety of spells increases as
+the magician gains experience and intelligence.
+Magic users are not as hearty as fighters;
+they receive 1 to 6 extra hit
+points for every new experience level.
+.H 2 "The Cleric"
+A cleric is able to "pray" to his god for help.
+The number and variety of prayers which the gods are willing to grant to
+a cleric increase as the cleric gains experience and wisdom.
+.P
+Because of their religious nature, clerics can also affect the "undead"
+beings, like \fIzombies\fR and \fIghouls\fR, 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.
+.P
+Clerics can gain from 1 to 8 extra hit points on
+reaching a new experience level.
+.H 2 "The Druid"
+The druid is a cleric of sorts but worships nature rather than a god.
+The druid is able to "chant" and thereby recieve certain types
+of spells. Most of the chants are targeted more towards the
+elements and nature.
+.P
+Druids gain from 1 to 8 hit points when they gain an experience level.
+.H 2 "The Thief"
+A thief is exceptionally dextrous and has a good chance to
+set a trap or rob a monster.
+.P
+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 \fIthief\fR manages to sneak up on a creature without waking it, he
+will get a chance to \fIbackstab\fR the monster. When this is done,
+the damage done by the \fIthief\fR greatly increases based on his experience
+level.
+.P
+Thieves gain from 1 to 6 extra hit points from a new experience level.
+.H 2 "The Paladin"
+The paladin is a type of holy warrior. Somewhat of a cross between a 
+fighter and a cleric. He is able to pray and turn undead as a cleric,
+(but to a lesser degree) but fights as a fighter. He is on the side of
+all that is good and righteous. Therefore he would never attack a 
+creature that would not attack him first. If he does kill a non-violent
+creature inadvertantly he will feel "uneasy" and his god may retaliate
+by making him a mere fighter.
+.P
+Paladins gain 1 to 10 hit points per experience level.
+.H 2 "The Ranger"
+The ranger is somewhat of a cross between a druid and a fighter. He
+too is on the side of righteousness and good. Therefore, the same
+same restrictions apply to his as they do to a paladin. The ranger
+can "chant" and "cast" but to a lesser degree than the druid and
+magician.
+.P
+Rangers gain 1 to 8 hit points per experience level.
+.H 2 "The Monk"
+The Monk is a martial arts expert. He wears no armor but has
+an effective armor class based on his ability to dodge attacks.
+He does not need a weapon in combat for his hands and feet are
+a formidable weapon. His ability to dodge and use his hands
+as weapons increases as he gains in level. 
+.P
+Monks gain 1 to 6 hit points per experience level.
+.H 2 "The Assassin"
+The assassin is a person trained in the art of killing people
+by surprise. He has most of the abilities of the thief except
+the "backstab". Instead, the assassin has the chance to kill
+an opponent outright with one strike. He is also a ruthless
+character and trained in the use of poison. He can recognize
+poison on sight and can coat his weapon with it thereby making
+his next attack an exceptionally lethal one.
+.P
+Assassins gain 1 to 6 hit points per experience level.
+.H 1 "ATTRIBUTES"
+.H 2 "Intelligence"
+Intelligence is the primary attribute associated with casting
+spells. With higher intelligence comes the knowledge of more
+spells, the ability to cast more spells, and faster recovery
+of spells that have been cast.
+.H 2 "Strength"
+This is, of course, the measure of a character's physical strength.
+With higher strength a character can carry more, cause more damage
+when striking, have a better chance to strike an opponent, and
+move about more quickly when carrying a load.
+.H 2 "Wisdom"
+Wisdom is the primary attribute associated with Praying
+to a god. With higher wisdom comes the knowledge of more
+prayers, the ability to pray more often, and faster recovery
+of prayer ability.
+.H 2 "Dexterity"
+Dexterity is a measure of a character's agility. With higher dexterity
+a character is harder to hit, can hit a opponent more easily, and
+can move about more quickly when carrying a load.
+.H 2 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.
+.H 2 "Charisma"
+Charisma is a measure of a characters looks and general likeableness.
+It effects transactions when trying to purchase things.
+.H 2 "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.
+For example, magicians receive new spells, and clerics receive new prayers.
+.P
+.H 2 "Allocating Attributes"
+The player starts with 72 "attribute points" to create a character and
+can distribute them in any manner among the six attributes described
+above.
+When prompting the player for each attribute, the game displays the
+minimum and maximum allowable values for that attribute.
+The player can type a backspace (control-H) to go back and change
+a value; typing an escape (ESC) sets the remaining attributes to
+the maximum value possible given the remaining attribute points.
+.H 1 "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.
+.H 2 "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 '\(emMore\(em.'~
+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.
+.H 2 "The Dungeon Section"
+The large middle section of the screen displays the player's surroundings using
+the following symbols:
+.tr ~~
+.VL 10
+.LI |
+A wall of a room.
+.LI -
+A wall of a room.
+.LI *
+A pile of gold.
+.LI %
+A way to the next level.
+.LI +
+A doorway.
+.LI .
+The floor in a room.
+.LI @
+The player.
+.LI _
+The player, when invisible.
+.LI #
+The floor in a passageway.
+.LI !
+A flask containing a potion.
+.LI ?
+A sealed scroll.
+.LI :
+Some food.
+.LI )
+A weapon.
+.LI \ 
+Solid rock (denoted by a space).
+.LI ]
+Some armor.
+.LI ;
+A miscellaneous magic item
+.LI ,
+An artifact
+.LI =
+A ring.
+.LI /
+A wand or a staff.
+.LI ^
+The entrance to a trading post
+.LI >
+A trapdoor leading to the next level
+.LI {
+An arrow trap
+.LI $
+A sleeping gas trap
+.LI }
+A beartrap
+.LI ~
+A trap that teleports you somewhere else
+.LI \`
+A poison dart trap
+.LI \fR"\fR
+A shimmering magic pool
+.LI \'
+An entrance to a maze
+.LI $
+Any magical item. (During magic detection)
+.LI >
+A blessed magical item. (During magic detection)
+.LI <
+A cursed magical item. (During magic detection)
+.LI 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 ('\fB/\fR').
+.LE
+.tr ~
+.H 2 "The Status Section"
+The bottom two lines of the screen describe the player's current status.
+The first line gives the player's characteristics:
+.BL
+.LI
+Intelligence (\fBInt\fR)
+.LI
+Strength (\fBStr\fR)
+.LI
+Wisdom (\fBWis\fR)
+.LI
+Dexterity (\fBDxt\fR)
+.LI
+Constitution (\fBConst\fR)
+.LI
+Charisma (\fBChar\fR)
+.LI
+Encumberance (\fBCarry\fR)
+.LE
+.P
+Intelligence, strength, wisdom, dexterity, charisma, and constitution have a 
+normal maximum of 25, but can be higher when augmented by a ring.
+Encumberance 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
+The second status line provides the following information:
+.BL
+.LI
+The current level (\fBLvl\fR) in the dungeon.  This number increases as the
+player goes further down.
+.LI
+The player's current number of hit points (\fBHp\fR), 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.
+.LI
+The player's armor class (\fBAc\fR).
+This number describes the amount of protection provided by the armor, cloaks, 
+and/or rings currently worn by the player. 
+It is also affected by high or low dexterity.
+Wearing no armor is equivalent to an armor class of 10.
+The protection level increases as the armor class decreases.
+.LI
+The player's current experience level (\fBExp\fR) 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.
+.LI
+A description of the player's character.
+This description depends on the player's character type and experience
+level.
+.LE
+.H 1 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.
+.P
+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 \fBinventory\fR command.
+Typing a '*' at this point produces a list of the eligible items.
+.P
+Rogue understands the following commands:~
+.VL 4
+.LI ?
+Preceding a command by a '\fB?\fR' produces a brief explanation of the command.
+The command '\fB?*\fR' gives an explanation of all the commands.
+.LI /
+Preceding a symbol by a '\fB/\fR' identifies the symbol.
+.LI =
+Clarify.
+After typing an '\fB=\fR' sign, the player can use the movement keys to
+position the cursor anywhere on the current level.
+As long as the player can normally see the selected position, Rogue will
+identify whatever is at that space.
+Examples include a \fIsleeping giant rat\fR, a \fIblue potion\fR, and a \fIfood
+ration\fR.
+.LI h
+Move one position to the left.
+.LI j
+Move one position down.
+.LI k
+Move one position up.
+.LI l
+Move one position to the right.
+.LI y
+Move one position to the top left.
+.LI u
+Move one position to the top right.
+.LI b
+Move one position to the bottom left.
+.LI n
+Move one position to the bottom right.
+.LI H
+Run to the left until reaching something interesting.
+.LI J
+Run down until reaching something interesting.
+.LI K
+Run up until reaching something interesting.
+.LI L
+Run to the right until reaching something interesting.
+.LI Y
+Run to the top left until reaching something interesting.
+.LI U
+Run to the top right until reaching something interesting.
+.LI B
+Run to the bottom left until reaching something interesting.
+.LI N
+Run to the bottom right until reaching something interesting.
+.LI t
+This command prompts for an object from the players pack.
+The player then \fBt\fRhrows the object in the specified direction.
+.LI f
+When this command precedes a directional command, the player moves
+in the specified direction until passing something interesting.
+.LI z
+This command prompts for a wand or staff from the player's pack and
+\fBz\fRaps it in the specified direction.
+.LI >
+Go down to the next level.
+.LI <
+Go up to the next level.
+.LI s
+\fBS\fRearch for a secret door or a trap in the circle surrounding the player.
+.LI .
+This command (a dot) causes the player to rest a turn.
+.LI i
+Display an \fBi\fRnventory of the player's pack.
+.LI I
+This command prompts for an item from the player's pack and displays
+the \fBi\fRnventory information for that item.
+.LI q
+\fBQ\fRuaff a potion from the player's pack.
+.LI r
+\fBR\fRead a scroll from the player's pack.
+.LI e
+\fBE\fRat some food from the player's pack.
+.LI w
+\fBW\fRield a weapon from the player's pack.
+.LI W
+\fBW\fRear some armor, ring, or miscellaneous magic item from the player's pack.
+The player can wear a maximum of eight rings.
+.LI T
+\fBT\fRake off whatever the player is wearing.
+.LI ^U
+\fBU\fRse a magic item in the player's pack.
+.LI d
+\fBD\fRrop an item from the player's pack.
+.LI P
+\fBP\fRick up the items currently under the player.
+.LI ^N
+When the player types this command, Rogue prompts for a monster or an item
+from the player's pack and a one-line \fBn\fRame.
+For monsters, the player can use the movement keys to position the cursor
+over the desired monster, and Rogue will use the given \fBn\fRame to refer
+to that monster.
+For items, Rogue gives all similar items (such as all the blue potions)
+the specified \fBn\fRame.
+.LI m
+When the player types this command, Rogue prompts for an item from the
+player's pack and a one-line name.
+Rogue then \fBm\fRarks the specified item with the given name.
+.LI o
+Typing this command causes Rogue to display all the settable \fBo\fRptions.
+The player can then merely examine the options or change any or all of them.
+.LI C
+This command, restricted to magicians and rangers
+produces a listing of the current supply of spells.
+The player can select one of the displayed spells and, if the player's
+energy level is sufficiently high, \fBC\fRast it.
+The more complicated the spell, the more energy it takes.
+.LI c
+This command, restricted to druids and rangers
+produces a listing of the current supply of chants.
+The player can select one of the displayed chants and, if the player's
+energy level is sufficiently high, \fBc\fRhant it.
+The more complicated the spell, the more energy it takes.
+.LI p
+This command, restricted to clerics and paladins,
+produces a listing of the character's known \fBp\fRrayers.
+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.
+.LI a
+This command is restricted to clerics and paladins
+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 \fBa\fRffect the
+monster by causing it to flee or possibly even destroying it.
+.LI *
+Count the gold in the player's pack.
+.LI ^
+This command sets a trap and is limited to thieves and assassins.
+If the character is successful, Rogue prompts the player for a type of trap
+and sets it where the player is standing.
+.LI G
+This command is restricted to thieves and assassins.
+It causes Rogue to display all the gold on the current level.
+.LI D
+\fBD\fRip something into a magic pool.
+.LI ^T
+This command is restricted to thieves and assassins.
+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 \fBs\fRteal 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.
+.LI ^L
+Redraw the screen.
+.LI ^R
+\fBR\fRepeat the last message that was displayed on the top line of the screen.
+.LI ^[
+Typing an escape will usually cause Rogue to cancel the current command.
+.LI v
+Print the current Rogue \fBv\fRersion number.
+.LI !
+Escape to the shell.
+.LI S
+Quit and \fBs\fRave the game for resumption at a later time.
+.LI Q
+\fBQ\fRuit without saving the game.
+.LE
+.H 1 "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.
+.P
+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.
+.H 1 TIME
+All actions except for purely bookkeeping commands, such as taking an
+inventory, take time.
+The amount of time varies with the command.
+Swinging a weapon, for example, takes more time than simply moving;
+so a monster could move several spaces in the time it takes the player
+to make one attack.
+The time it takes to swing a weapon also varies based on the bulk of the
+weapon, and the time it takes to simply move a space varies with the type
+of armor worn.
+Movement is always faster when flying.
+.P
+Since actions take time, some of them can be disrupted.
+If the player is casting a spell, for example, and gets hit before finishing
+it, the spell is lost.
+Similarly, the player might choke if hit while trying to eat.
+Of course, the same rule applies when the player hits a monster.
+.P
+Magical hasting (or slowing) will decrease (or increase) the time it takes
+to perform an action.
+.H 1 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 \fIfire beetle\fR.
+.H 1 "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.
+.P
+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 weapon.
+The player cannot release a cursed weapon.
+.P
+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
+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
+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.
+This corrosive property can also apply to weapons when the player hits
+such a monster.
+.H 1 "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.
+.H 1 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.
+.H 1 "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.
+.H 1 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.
+.P
+Food comes in the form of standard rations and as a variety of berries.
+Some berries have side effects in addition to satisfying one's hunger.
+.H 1 GOLD
+Gold has one use in a dungeon:~ buying things.
+One can buy things in two ways, either in a \fItrading post\fR or from a
+\fIquartermaster\fR.
+A trading post is a place that sometimes occurs "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.
+.P
+The player starts the game in a trading post with a class-dependent allotment
+of gold.
+Although there are restrictions on the use of some items (eg. only fighters,
+paladins, and rangers can wield two-handed swords), the market will happily
+sell the player anything that he can afford.
+
+.H 1 "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.
+.H 1 "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.
+These items also can usually be used to the player's advantage. However,
+care must be taken when handling them for they are intelligent and will
+reject mishandling or abuse. These items consume food and merely carrying 
+them will result in increased food use.
+.H 1 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.
+.H 1 "THE MONSTERS"
+Each monster except for the merchant \fIquartermaster\fR appears in
+a limited range of dungeon levels.
+All monsters of the same type share the same abilities;
+all \fIgiant rats\fR, for example, can give the player a disease, and
+all \fIjackalweres\fR can put the player to sleep.
+Monsters of the same type can vary, however, such that one \fIkobold\fR
+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
+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.
+Some monsters even use magical items, such as wands.
+Monsters with distance weapons or magic can attack the player from across a room
+or down a corridor.
+.P
+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
+It is sometimes possible to enlist a monster's aid.
+Reading a \fIcharm monster\fR scroll, for example, or singing a \fIcharm
+monster\fR chant can make a monster believe the player is its friend.
+A charmed monster will fight hostile monsters for the player as long as they are
+not of its race.
+.P
+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.
+.H 1 OPTIONS
+Rogue has several options which may be set by the player:~
+.VL 7
+.LI \fBterse\fR
+Setting this Boolean option results in shorter messages appearing on
+the top line of the screen.
+.LI \fBjump\fR
+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.
+.LI \fBstep\fR
+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.
+.LI \fBflush\fR
+Setting this Boolean option results in flushing all typeahead (pending) commands
+when the player encounters a monster.
+.LI \fBaskme\fR
+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.
+.LI \fBpickup\fR
+This option specifys whether items should be picked up automatically as the
+rogue steps over them.
+In the non-automatic mode, the player may still pick up items via the
+pickup (P) command.
+The option defaults to true.
+.LI \fBname\fR
+This string is the player's name and defaults to the player's account name.
+.LI \fBfile\fR
+This string, which defaults to rogue.save, specifies the file to use for
+saving the game.
+.LI \fBscore\fR
+This string identifies the top-twenty score file to use for the game.
+.LI \fBclass\fR
+This option specifies the character class of the rogue.
+It can be set only in the ROGUEOPTS environment variable.
+.LI \fBquested~item\fR
+.br
+This option is set by the game at the start and cannot be reset by the player.
+It is merely listed to remind the player of his quest.
+.LE
+.P
+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"
+would set the \fIterse, jump, flush\fR, and \fIaskme\fR Boolean options,
+clear the \fIstep\fR Boolean option, set the player's
+\fIname\fR to "Ivan the Terrible," and use the defaults for
+the \fIsave file\fR and the \fIscore file\fR.
+.P
+The player may change an option at any time during the game
+via the \fBoption\fR 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.
+.H 1 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 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.
+.P
+Rogue maintains a list of the top twenty 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.
+As an installation option, the game may record only one entry per
+character type and login;
+this restriction encourages a greater number of different players
+in the scorechart.
+.H 1 ACKNOWLEDGEMENTS
+This version of Rogue is based on a version developed at the
+University of California.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/arogue77.doc	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,1122 @@
+       
+
+
+
+
+
+                           The Dungeons of Doom
+
+                                Toolchest
+
+
+
+
+
+
+       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
+
+            Before placing the player  in  the  dungeon,  the  game
+       requests  the  player  to select what type of character they
+       would like to be:  a fighter, a  magic  user,  a  cleric,  a
+       druid, a thief, a paladin, a ranger, a monk, or an assassin.
+
+       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
+
+
+
+
+
+
+
+
+                                   - 2 -
+
+
+
+       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 12  extra  hit  points  for
+       every new experience level.
+
+       2.2  The Magician
+
+            A  Magician  is  able to "cast" spells.  The number and
+       variety of spells increases as the magician gains experience
+       and   intelligence.   Magic  users  are  not  as  hearty  as
+       fighters; they receive 1 to 6 extra hit points for every new
+       experience level.
+
+       2.3  The Cleric
+
+            A  cleric  is  able to "pray" to his god for help.  The
+       number and variety of prayers which the gods are willing  to
+       grant  to  a  cleric increase as the cleric gains experience
+       and 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 Druid
+
+            The  druid  is  a  cleric  of sorts but worships nature
+       rather than a god.  The druid is able to "chant" and thereby
+       recieve  certain  types  of  spells.  Most of the chants are
+       targeted more towards the elements and nature.
+
+            Druids gain from 1 to 8 hit points when  they  gain  an
+       experience level.
+
+       2.5  The Thief
+
+            A thief is exceptionally dextrous and has a good chance
+       to set a trap or rob a monster.
+
+            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
+
+
+
+
+
+
+
+
+                                   - 3 -
+
+
+
+       greatly increases based on his experience level.
+
+            Thieves  gain  from  1 to 6 extra hit points from a new
+       experience level.
+
+       2.6  The Paladin
+
+            The paladin is a type of holy warrior.  Somewhat  of  a
+       cross between a fighter and a cleric. He is able to pray and
+       turn undead as a cleric, (but to a lesser degree) but fights
+       as  a  fighter.  He  is  on the side of all that is good and
+       righteous. Therefore he would never attack a  creature  that
+       would  not  attack  him first. If he does kill a non-violent
+       creature inadvertantly he will feel "uneasy" and his god may
+       retaliate by making him a mere fighter.
+
+            Paladins  gain 1 to 10 hit points per experience level.
+
+       2.7  The Ranger
+
+            The ranger is somewhat of a cross between a druid and a
+       fighter.  He  too  is on the side of righteousness and good.
+       Therefore, the same same restrictions apply to his  as  they
+       do  to a paladin. The ranger can "chant" and "cast" but to a
+       lesser degree than the druid and magician.
+
+            Rangers gain 1 to 8 hit points per experience level.
+
+       2.8  The Monk
+
+            The Monk is a martial arts expert. He  wears  no  armor
+       but  has  an  effective  armor class based on his ability to
+       dodge attacks.  He does not need a weapon in combat for  his
+       hands and feet are a formidable weapon. His ability to dodge
+       and use his hands as weapons increases as he gains in level.
+
+            Monks gain 1 to 6 hit points per experience level.
+
+       2.9  The Assassin
+
+            The  assassin is a person trained in the art of killing
+       people by surprise. He has most  of  the  abilities  of  the
+       thief  except  the "backstab". Instead, the assassin has the
+       chance to kill an opponent outright with one strike.  He  is
+       also  a ruthless character and trained in the use of poison.
+       He can recognize poison on sight and  can  coat  his  weapon
+       with  it  thereby  making  his  next attack an exceptionally
+       lethal one.
+
+            Assassins gain 1 to 6 hit points per experience  level.
+
+
+       3.  ATTRIBUTES
+
+
+
+
+
+
+
+
+
+                                   - 4 -
+
+
+
+       3.1  Intelligence
+
+            Intelligence  is  the primary attribute associated with
+       casting spells. With higher intelligence comes the knowledge
+       of  more spells, the ability to cast more spells, and faster
+       recovery of spells that have been cast.
+
+       3.2  Strength
+
+            This is,  of  course,  the  measure  of  a  character's
+       physical  strength.   With  higher  strength a character can
+       carry more, cause more damage when striking, have  a  better
+       chance  to  strike  an opponent, and move about more quickly
+       when carrying a load.
+
+       3.3  Wisdom
+
+            Wisdom is the primary attribute associated with Praying
+       to  a  god.  With  higher wisdom comes the knowledge of more
+       prayers, the ability to pray more often, and faster recovery
+       of prayer ability.
+
+       3.4  Dexterity
+
+            Dexterity  is  a measure of a character's agility. With
+       higher dexterity a character is harder to  hit,  can  hit  a
+       opponent  more  easily, and can move about more quickly when
+       carrying a load.
+
+       3.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.
+
+       3.6  Charisma
+
+            Charisma is a measure of a characters looks and general
+       likeableness.    It  effects  transactions  when  trying  to
+       purchase things.
+
+       3.7  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.    For
+       example,  magicians  receive new spells, and clerics receive
+
+
+
+
+
+
+
+
+                                   - 5 -
+
+
+
+       new prayers.
+
+       3.8  Allocating Attributes
+
+            The player starts with 72 "attribute points" to  create
+       a  character and can distribute them in any manner among the
+       six attributes described above.  When prompting  the  player
+       for  each  attribute,  the  game  displays  the  minimum and
+       maximum allowable values for that attribute.  The player can
+       type  a backspace (control-H) to go back and change a value;
+       typing an escape (ESC) sets the remaining attributes to  the
+       maximum value possible given the remaining attribute points.
+
+
+       4.  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.
+
+       4.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.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.
+
+
+
+
+
+
+
+
+
+                                   - 6 -
+
+
+
+       _         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
+
+       }         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 ('/').
+
+
+
+
+
+
+
+
+
+
+                                   - 7 -
+
+
+
+       4.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 Charisma (Char)
+
+          o Encumberance (Carry)
+
+            Intelligence,  strength,  wisdom,  dexterity, charisma,
+       and constitution have a normal maximum of  25,  but  can  be
+       higher   when  augmented  by  a  ring.   Encumberance  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.
+
+          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, cloaks,
+            and/or  rings currently worn by the player.  It is also
+            affected by high or low dexterity.  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
+
+
+
+
+
+
+
+
+                                   - 8 -
+
+
+
+            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.
+
+
+       5.  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:
+
+       ?   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.
+
+       =   Clarify.   After  typing an '=' sign, the player can use
+           the movement keys to position the cursor anywhere on the
+           current  level.   As long as the player can normally see
+           the selected position, Rogue will identify  whatever  is
+           at that space.  Examples include a sleeping giant rat, a
+           blue potion, and a food ration.
+
+       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.
+
+
+
+
+
+
+
+
+
+                                   - 9 -
+
+
+
+       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 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.
+
+       z   This command 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.
+
+
+
+
+
+
+
+
+
+
+                                  - 10 -
+
+
+
+       e   Eat some food from the player's pack.
+
+       w   Wield a weapon from the player's pack.
+
+       W   Wear  some armor, ring, or miscellaneous magic item from
+           the player's pack.  The player can  wear  a  maximum  of
+           eight rings.
+
+       T   Take off whatever the player is wearing.
+
+       ^U  Use a magic item in the player's pack.
+
+       d   Drop an item from the player's pack.
+
+       P   Pick up the items currently under the player.
+
+       ^N  When  the player types this command, Rogue prompts for a
+           monster or an item from the player's pack and a one-line
+           name.   For  monsters,  the  player can use the movement
+           keys to position the cursor over  the  desired  monster,
+           and  Rogue  will  use  the  given  name to refer to that
+           monster.  For items, Rogue gives all similar items (such
+           as all the blue potions) 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
+           the options or change any or all of them.
+
+       C   This   command,  restricted  to  magicians  and  rangers
+           produces a listing of the 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.
+
+       c   This command, restricted to druids and rangers  produces
+           a  listing  of the current supply of chants.  The player
+           can select one of  the  displayed  chants  and,  if  the
+           player's  energy  level  is sufficiently high, chant it.
+           The more complicated  the  spell,  the  more  energy  it
+           takes.
+
+       p   This   command,  restricted  to  clerics  and  paladins,
+           produces a listing of  the  character'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.
+
+
+
+
+
+
+
+
+
+
+                                  - 11 -
+
+
+
+       a   This command is restricted to clerics and paladins  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.
+
+       *   Count the gold in the player's pack.
+
+       ^   This  command  sets a trap and is limited to thieves and
+           assassins.   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 and assassins.  It
+           causes  Rogue  to  display  all  the gold on the current
+           level.
+
+       D   Dip something into a magic pool.
+
+       ^T  This command is restricted to thieves and assassins.  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.
+
+       ^[  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.
+
+
+       6.  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.
+
+
+
+
+
+
+
+
+
+                                  - 12 -
+
+
+
+            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.
+
+
+       7.  TIME
+
+            All actions except  for  purely  bookkeeping  commands,
+       such  as taking an inventory, take time.  The amount of time
+       varies with the command.  Swinging a  weapon,  for  example,
+       takes  more time than simply moving; so a monster could move
+       several spaces in the time it takes the player to  make  one
+       attack.   The  time  it  takes to swing a weapon also varies
+       based on the bulk of the weapon, and the time  it  takes  to
+       simply  move  a  space  varies  with the type of armor worn.
+       Movement is always faster when flying.
+
+            Since actions take time, some of them can be disrupted.
+       If  the player is casting a spell, for example, and gets hit
+       before finishing it, the  spell  is  lost.   Similarly,  the
+       player  might  choke if hit while trying to eat.  Of course,
+       the same rule applies when the player hits a monster.
+
+            Magical  hasting  (or  slowing)   will   decrease   (or
+       increase) the time it takes to perform an action.
+
+
+       8.  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.
+
+
+       9.  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
+       weapon.  The player cannot release a cursed weapon.
+
+
+
+
+
+
+
+
+                                  - 13 -
+
+
+
+            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.  This corrosive
+       property can also apply to weapons when the player hits such
+       a monster.
+
+
+       10.  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.
+
+
+       11.  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.
+
+
+       12.  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.
+
+
+
+
+
+
+
+
+
+
+
+                                  - 14 -
+
+
+
+       13.  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.
+
+            Food comes in the form of standard  rations  and  as  a
+       variety  of  berries.   Some  berries  have  side effects in
+       addition to satisfying one's hunger.
+
+
+       14.  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  that  sometimes
+       occurs "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.
+
+            The  player  starts  the  game in a trading post with a
+       class-dependent  allotment  of  gold.   Although  there  are
+       restrictions  on  the  use of some items (eg. only fighters,
+       paladins, and rangers  can  wield  two-handed  swords),  the
+       market  will  happily  sell  the player anything that he can
+       afford.
+
+
+
+       15.  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.
+
+
+       16.  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.  These items also can usually be used to the
+       player's  advantage.  However,  care  must  be  taken   when
+       handling  them  for  they  are  intelligent  and will reject
+
+
+
+
+
+
+
+
+                                  - 15 -
+
+
+
+       mishandling or abuse. These items consume  food  and  merely
+       carrying them will result in increased food use.
+
+
+       17.  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.
+
+
+       18.  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.  Some monsters even  use  magical  items,  such  as
+       wands.   Monsters  with distance weapons or magic 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.
+
+            It  is  sometimes  possible  to enlist a monster's aid.
+       Reading a charm monster scroll, for example,  or  singing  a
+       charm monster chant can make a monster believe the player is
+       its friend.  A charmed monster will fight  hostile  monsters
+       for the player as long as they are not of its race.
+
+            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.
+
+
+       19.  OPTIONS
+
+            Rogue  has  several  options  which  may  be set by the
+       player:
+
+
+
+
+
+
+
+
+                                  - 16 -
+
+
+
+       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
+              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.
+
+       pickup This option specifys whether items should  be  picked
+              up  automatically  as  the rogue steps over them.  In
+              the non-automatic mode, the player may still pick  up
+              items   via  the  pickup  (P)  command.   The  option
+              defaults to true.
+
+       name   This string is the player's name and defaults to  the
+              player's account name.
+
+       file   This  string, which defaults to rogue.save, specifies
+              the file to use for saving the game.
+
+       score  This string identifies the top-twenty 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.
+
+       quested item
+              This  option  is  set  by  the  game at the start and
+              cannot be reset by the player.  It is  merely  listed
+              to remind the player of his quest.
+
+            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"  would
+       set the terse, jump, flush, and askme Boolean options, clear
+       the step Boolean option, set the player's name to "Ivan  the
+
+
+
+
+
+
+
+
+                                  - 17 -
+
+
+
+       Terrible,"  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.
+
+
+       20.  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
+       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 twenty 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.   As  an  installation
+       option,  the  game  may  record only one entry per character
+       type and login; this restriction encourages a greater number
+       of different players in the scorechart.
+
+
+       21.  ACKNOWLEDGEMENTS
+
+            This  version  of Rogue is based on a version developed
+       at the University of California.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/arogue77.html	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,1328 @@
+<!-- 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">Toolchest</h2>
+<h3 align="center">http://roguelike.sourceforge.net/arogue77</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, 1986 Michael Morgan, Ken Dalka and AT&amp;T<br>
+		All rights reserved.
+	</td>
+</tr>
+<tr>
+	<td nowrap>
+		Based on &quot;Rogue: Exploring the Dungeons of Doom&quot;<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>
+
+<h2 align="justify">1. Introduction</h2>
+
+<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</h3>
+
+<p align="justify">
+       Before placing the player  in  the  dungeon,  the  game
+       requests  the  player  to select what type of character they
+       would like to be:  a fighter, a  magic  user,  a  cleric,  a
+       druid, a thief, a paladin, a ranger, a monk, or an assassin.
+</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 12  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  is  able to "cast" spells.  The number and
+       variety of spells increases as the magician gains experience
+       and   intelligence.   Magic  users  are  not  as  hearty  as
+       fighters; they receive 1 to 6 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  is  able to "pray" to his god for help.  The
+       number and variety of prayers which the gods are willing  to
+       grant  to  a  cleric increase as the cleric gains experience
+       and wisdom.
+       </p>
+       
+<p align=justify>
+       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.
+</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 Druid</span></strong></p>
+
+<p align="justify"> 
+       The  druid  is  a  cleric  of sorts but worships nature
+       rather than a god.  The druid is able to "chant" and thereby
+       recieve  certain  types  of  spells.  Most of the chants are
+       targeted more towards the elements and nature.
+</p>
+
+<p align=justify>            
+       Druids gain from 1 to 8 hit points when  they  gain  an
+       experience level.
+</p>
+       
+<p align="justify"><strong><span style="font-variant: small-caps">2.5 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.
+</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.6 The Paladin</span></strong></p>
+
+<p align="justify">
+       The paladin is a type of holy warrior.  Somewhat  of  a
+       cross between a fighter and a cleric. He is able to pray and
+       turn undead as a cleric, (but to a lesser degree) but fights
+       as  a  fighter.  He  is  on the side of all that is good and
+       righteous. Therefore he would never attack a  creature  that
+       would  not  attack  him first. If he does kill a non-violent
+       creature inadvertantly he will feel "uneasy" and his god may
+       retaliate by making him a mere fighter.
+</p>
+
+<p align=justify>
+            Paladins  gain 1 to 10 hit points per experience level.
+</p>
+
+<p align="justify"><strong><span style="font-variant: small-caps">2.7 The Ranger</span></strong></p>
+
+<p align="justify">
+       The ranger is somewhat of a cross between a druid and a
+       fighter.  He  too  is on the side of righteousness and good.
+       Therefore, the same same restrictions apply to his  as  they
+       do  to a paladin. The ranger can "chant" and "cast" but to a
+       lesser degree than the druid and magician.
+</p>
+
+<p align=justify>
+       Rangers gain 1 to 8 hit points per experience level.
+</p>
+
+<p align="justify"><strong><span style="font-variant: small-caps">2.8 The Monk</span></strong></p>
+
+<p align="justify">
+       The Monk is a martial arts expert. He  wears  no  armor
+       but  has  an  effective  armor class based on his ability to
+       dodge attacks.  He does not need a weapon in combat for  his
+       hands and feet are a formidable weapon. His ability to dodge
+       and use his hands as weapons increases as he gains in level.
+</p>
+
+<p align=justify>
+       Monks gain 1 to 6 hit points per experience level.
+</p>
+
+<p align="justify"><strong><span style="font-variant: small-caps">2.9 The Assassin</span></strong></p>
+
+<p align="justify">
+       The  assassin is a person trained in the art of killing
+       people by surprise. He has most  of  the  abilities  of  the
+       thief  except  the "backstab". Instead, the assassin has the
+       chance to kill an opponent outright with one strike.  He  is
+       also  a ruthless character and trained in the use of poison.
+       He can recognize poison on sight and  can  coat  his  weapon
+       with  it  thereby  making  his  next attack an exceptionally
+       lethal one.
+</p>
+
+<p align=justify>
+       Assassins gain 1 to 6 hit points per experience  level.
+</p>
+
+<h3 align="justify">3. ATTRIBUTES</h3>
+
+<p align="justify"><strong><span style="font-variant: small-caps">3.1 Intelligence</span></strong></p>
+
+<p align="justify">Intelligence  is  the primary attribute associated with
+       casting spells. With higher intelligence comes the knowledge
+       of  more spells, the ability to cast more spells, and faster
+       recovery of spells that have been cast.
+
+</p>
+
+<p align="justify"><strong><span style="font-variant: small-caps">3.2 Strength</span></strong></p>
+<p align="justify">This is,  of  course,  the  measure  of  a  character's
+       physical  strength.   With  higher  strength a character can
+       carry more, cause more damage when striking, have  a  better
+       chance  to  strike  an opponent, and move about more quickly
+       when carrying a load.
+
+       </p>
+<p align="justify"><strong><span style="font-variant: small-caps">3.3 Wisdom</span></strong></p>
+<p align="justify">Wisdom is the primary attribute associated with Praying
+       to  a  god.  With  higher wisdom comes the knowledge of more
+       prayers, the ability to pray more often, and faster recovery
+       of prayer ability.
+
+       </p>
+<p align="justify"><strong><span style="font-variant: small-caps">3.4 Dexterity</span></strong></p>
+<p align="justify">Dexterity  is  a measure of a character's agility. With
+       higher dexterity a character is harder to  hit,  can  hit  a
+       opponent  more  easily, and can move about more quickly when
+       carrying a load.
+
+       </p>
+<p align="justify"><strong><span style="font-variant: small-caps">3.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">3.6 Charisma</span></strong></p>
+<p align="justify">Charisma is a measure of a characters looks and general
+       likeableness.    It  effects  transactions  when  trying  to
+       purchase things. </p>
+
+<p align="justify"><strong><span style="font-variant: small-caps">3.7 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.    For
+example,  magicians  receive new spells, and clerics receive
+new prayers.
+</p>
+
+<p align="justify">
+
+<strong><span style="font-variant: small-caps">3.8 Allocating Attributes</span></strong>
+</p>
+<p align="justify">
+The player starts with 72 "attribute points" to  create
+a  character and can distribute them in any manner among the
+six attributes described above.  When prompting  the  player
+for  each  attribute,  the  game  displays  the  minimum and
+maximum allowable values for that attribute.  The player can
+type  a backspace (control-H) to go back and change a value;
+typing an escape (ESC) sets the remaining attributes to  the
+maximum value possible given the remaining attribute points.
+</p>
+
+<h3 align="justify">
+4.0
+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">4.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">4.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="center">|</td>
+		<td>&nbsp;&nbsp;&nbsp;&nbsp; </td>
+		<td>A wall of a room.</td>
+	</tr>
+	<tr>
+		<td align="center">-</td>
+		<td>&nbsp;</td>
+		<td>A wall of a room.</td>
+	</tr>
+	<tr>
+		<td align="center">*</td>
+		<td>&nbsp;</td>
+		<td>A pile of gold.</td>
+	</tr>
+	<tr>
+		<td align="center">%</td>
+		<td>&nbsp;</td>
+		<td>A way to another level.</td>
+	</tr>
+	<tr>
+		<td align="center">+</td>
+		<td>&nbsp;</td>
+		<td>A doorway.</td>
+	</tr>
+	<tr>
+		<td align="center">.</td>
+		<td>&nbsp;</td>
+		<td>The floor in a room</td>
+	</tr>
+	<tr>
+		<td align="center">@</td>
+		<td>&nbsp;</td>
+		<td>The player.</td>
+	</tr>
+	<tr>
+		<td align="center">_</td>
+		<td>&nbsp;</td>
+		<td>The player, when invisible.</td>
+	</tr>
+	<tr>
+		<td align="center">#</td>
+		<td>&nbsp;</td>
+		<td>The floor in a passageway</td>
+	</tr>
+	<tr>
+		<td align="center">!</td>
+		<td>&nbsp;</td>
+		<td>A flask containing a potion.</td>
+	</tr>
+	<tr>
+		<td align="center">?</td>
+		<td>&nbsp;</td>
+		<td>A sealed scroll.</td>
+	</tr>
+	<tr>
+		<td align="center">:</td>
+		<td>&nbsp;</td>
+		<td>Some food.</td>
+	</tr>
+	<tr>
+		<td align="center">)</td>
+		<td>&nbsp;</td>
+		<td>A weapon.</td>
+	</tr>
+	<tr>
+		<td align="center">&nbsp;</td>
+		<td nowrap>&nbsp;</td>
+		<td nowrap>Solid rock (denoted by a space)</td>
+	</tr>
+	<tr>
+		<td align="center">]</td>
+		<td>&nbsp;</td>
+		<td>Some armor.</td>
+	</tr>
+	<tr>
+		<td align="center">;</td>
+		<td>&nbsp;</td>
+		<td>A miscellaneous magic item.</td>
+	</tr>
+	<tr>
+		<td align="center">,</td>
+		<td>&nbsp;</td>
+		<td>An artifact.</td>
+	</tr>
+	<tr>
+		<td align="center">=</td>
+		<td>&nbsp;</td>
+		<td>A ring.</td>
+	</tr>
+	<tr>
+		<td align="center">/</td>
+		<td>&nbsp;</td>
+		<td>A wand or a staff.</td>
+	</tr>
+	<tr>
+		<td align="center">^</td>
+		<td>&nbsp;</td>
+		<td>The entrance to a trading post.</td>
+	</tr>
+	<tr>
+		<td align="center">&gt;</td>
+		<td>&nbsp;</td>
+		<td>A trapdoor leading to the next level.</td>
+	</tr>
+	<tr>
+		<td align="center">{</td>
+		<td>&nbsp;</td>
+		<td>An arrow trap.</td>
+	</tr>
+	<tr>
+		<td align="center">$</td>
+		<td>&nbsp;</td>
+		<td>A sleeping gas trap.</td>
+	</tr>
+	<tr>
+		<td align="center">}</td>
+		<td>&nbsp;</td>
+		<td>A beartrap.</td>
+	</tr>
+	<tr>
+		<td align="center">~</td>
+		<td>&nbsp;</td>
+		<td>A trap that teleports you somewhere else.</td>
+	</tr>
+	<tr>
+		<td align="center">`</td>
+		<td>&nbsp;</td>
+		<td>A poison dart trap.</td>
+	</tr>
+	<tr>
+		<td align="center">&quot;</td>
+		<td>&nbsp;</td>
+		<td>a shimmering magic pool.</td>
+	</tr>
+	<tr>
+		<td align="center">'</td>
+		<td>&nbsp;</td>
+		<td>An entrance to a maze.</td>
+	</tr>
+	<tr>
+		<td align="center">$</td>
+		<td>&nbsp;</td>
+		<td>Any magical item. (During magic detection)</td>
+	</tr>
+	<tr>
+		<td align="center">&gt;</td>
+		<td nowrap>&nbsp;</td>
+		<td nowrap>A blessed magical item. (Duriing magic detection)</td>
+	</tr>
+	<tr>
+		<td align="center">&lt;</td>
+		<td>&nbsp;</td>
+		<td>A cursed magical item. (During magic detection)</td>
+	</tr>
+	<tr>
+		<td align="center">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">4.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)</li>
+<li>
+<p align="justify">Strength (Str)</li>
+<li>
+<p align="justify">Wisdom (Wis)</li>
+<li>
+<p align="justify">Dexterity (Dxt)</li>
+<li>
+<p align="justify">Constitution (Const)</li>
+<li>
+<p align="justify">Charisma (Char)</li>
+<li>
+<p align="justify">Encumberance (Carry)</li>
+</ul>
+
+<p align=justify>
+Intelligence,  strength,  wisdom,  dexterity, charisma,
+and constitution have a normal maximum of  25,  but  can  be
+higher   when  augmented  by  a  ring.   Encumberance  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.
+</li>
+<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.
+</li>
+<li>
+<p align="justify">The  player's  armor class (Ac).  This number describes
+the amount of protection provided by the armor, cloaks,
+and/or  rings currently worn by the player.  It is also
+affected by high or low dexterity.  Wearing no armor is
+equivalent  to  an  armor  class of 10.  The protection
+level increases as the armor class decreases.
+</li>
+<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.
+</li>
+<li>
+<p align="justify">A   description   of   the  player's  character.   This
+description depends on the player's character type  and
+experience level.
+</li>
+</ul>
+
+<h3 align="justify">5.0 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="center" 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="center" valign="top">/</td>
+		<td>&nbsp;</td>
+		<td>Preceding a symbol by a '/' identifies the symbol.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">=</td>
+		<td>&nbsp;</td>
+		<td>Clarify. After typing an '=' sign, the player can use the movement 
+		keys to position the cursor anywhere on the current level. As long as 
+		the player can normally see the selected position, Rogue will identify 
+		whatever is at that space. Examples include a sleeping giant rat, a blue 
+		potion, and a food ration.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">h</td>
+		<td>&nbsp;</td>
+		<td>Move one position to the left.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">j</td>
+		<td>&nbsp;</td>
+		<td>Move one position down.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">k</td>
+		<td>&nbsp;</td>
+		<td>Move one position up.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">l</td>
+		<td>&nbsp;</td>
+		<td>Move one position to the right.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">y</td>
+		<td height="21">&nbsp;</td>
+		<td height="21">Move one position to the top left.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">u</td>
+		<td>&nbsp;</td>
+		<td>Move one position to the top right.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">b</td>
+		<td>&nbsp;</td>
+		<td>Move one position to the bottom left.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">n</td>
+		<td>&nbsp;</td>
+		<td>Move one position to the bottom right</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">H</td>
+		<td>&nbsp;</td>
+		<td>Run to the left until reaching something interesting.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">J</td>
+		<td>&nbsp;</td>
+		<td>Run down until reaching something interesting.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">K</td>
+		<td>&nbsp;</td>
+		<td>Run up until reaching something interesting.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">L</td>
+		<td>&nbsp;</td>
+		<td>Run to the right until reaching something interesting.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">Y</td>
+		<td>&nbsp;</td>
+		<td>Run to the top left until reaching something interesting.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">U</td>
+		<td>&nbsp;</td>
+		<td>Run to the top right until reaching something interesting.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">B</td>
+		<td>&nbsp;</td>
+		<td>Run to the bottom left until reaching something interesting.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">N</td>
+		<td>&nbsp;</td>
+		<td>Run to the bottom right until reaching something interesting</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">t</td>
+		<td>&nbsp;</td>
+		<td>This command prompts for an object from the players pack. The player
+then throws the object in the specified direction.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">f</td>
+		<td>&nbsp;</td>
+		<td>When this command is preceded with a directional command, the player 
+		moves in the specified direction until passing something interesting.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">z</td>
+		<td>&nbsp;</td>
+		<td>This command prompts for a wand or staff from the player's pack and 
+		zaps
+it in the specified direction.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">&gt;</td>
+		<td>&nbsp;</td>
+		<td>Go down to the next level.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">&lt;</td>
+		<td>&nbsp;</td>
+		<td>Go up to the next level.</td>
+	</tr>
+	<tr>
+		<td align="center" 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="center" valign="top">.</td>
+		<td>&nbsp;</td>
+		<td>This command (a dot) causes the player to rest a turn.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">i</td>
+		<td>&nbsp;</td>
+		<td>Display an inventory of the player's pack.</td>
+	</tr>
+	<tr>
+		<td align="center" 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="center" valign="top">q</td>
+		<td>&nbsp;</td>
+		<td>Quaff a potion from the player's pack.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">r</td>
+		<td>&nbsp;</td>
+		<td>Read a scroll from the player's pack.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">e</td>
+		<td>&nbsp;</td>
+		<td>Eat some food from the player's pack.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">w</td>
+		<td>&nbsp;</td>
+		<td>Wield a weapon from the player's pack.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">W</td>
+		<td>&nbsp;</td>
+		<td>Wear some armor, ring, or a miscellaneous magic item from the 
+		player's
+pack. The player can wear a maximum of 8 rings.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">T</td>
+		<td>&nbsp;</td>
+		<td>Take off whatever the player is wearing.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">^U</td>
+		<td>&nbsp;</td>
+		<td>Use a magic item in the player's pack.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">d</td>
+		<td>&nbsp;</td>
+		<td>Drop an item from the player's pack.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">P</td>
+		<td>&nbsp;</td>
+		<td>Pick up the items currently under the player.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">^N</td>
+		<td>&nbsp;</td>
+		<td>When the player types this command, Rogue prompts for a monster or 
+		an item from the player's pack and a one-line name. For monsters, the 
+		player can use the movement keys to position the cursor over the desired 
+		monster, and Rogue will use the given name to refer to that<br>
+		monster. For items, Rogue gives all similar items (such as all the blue 
+		potions) the specified name.</td>
+	</tr>
+	<tr>
+		<td align="center" 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="center" 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="center" valign="top">C</td>
+		<td>&nbsp;</td>
+		<td>This command, restricted to magicians and rangers produces a listing 
+		of the 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="center" valign="top">c</td>
+		<td>&nbsp;</td>
+		<td>This command, restricted to druids and rangers produces a listing of 
+		the current supply of chants. The player can select one of the displayed 
+		chants and, if the player's energy level is sufficiently high, chant it. 
+		The more complicated the spell, the more energy it takes.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">p</td>
+		<td>&nbsp;</td>
+		<td>This command, restricted to clerics and paladins, produces a listing 
+		of the character'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="center" valign="top">a</td>
+		<td>&nbsp;</td>
+		<td>This command is restricted to clerics and paladins 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="center" valign="top">*</td>
+		<td>&nbsp;</td>
+		<td>Count the gold in the player's pack.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">^</td>
+		<td>&nbsp;</td>
+		<td>This command sets a trap and is limited to thieves and assassins. 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="center" valign="top">G</td>
+		<td>&nbsp;</td>
+		<td>This command is restricted to thieves and assassins. It causes Rogue 
+		to display all the gold on the current level.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">D</td>
+		<td>&nbsp;</td>
+		<td>Dip something into a magic pool.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">^T</td>
+		<td height="22">&nbsp;</td>
+		<td height="22">This command is restricted to thieves and assassins. 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="center" valign="top">^L</td>
+		<td>&nbsp;</td>
+		<td>Redraw the screen.</td>
+	</tr>
+	<tr>
+		<td align="center" 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="center" 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="center" valign="top">v</td>
+		<td>&nbsp;</td>
+		<td>Print the current Rogue version number.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">!</td>
+		<td>&nbsp;</td>
+		<td>Escape to the shell level.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">S</td>
+		<td>&nbsp;</td>
+		<td>Quit and save the game for resumption at a later time.</td>
+	</tr>
+	<tr>
+		<td align="center" valign="top">Q</td>
+		<td>&nbsp;</td>
+		<td>Quit without saving the game.</td>
+	</tr>
+	</table>
+</p>
+
+<h3 align="justify">6. IMPLICIT COMMANDS</h3>
+
+<p align="justify">
+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.
+</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">7. TIME</h3>
+
+<p align="justify">
+All actions except  for  purely  bookkeeping  commands,
+such  as taking an inventory, take time.  The amount of time
+varies with the command.  Swinging a  weapon,  for  example,
+takes  more time than simply moving; so a monster could move
+several spaces in the time it takes the player to  make  one
+attack.   The  time  it  takes to swing a weapon also varies
+based on the bulk of the weapon, and the time  it  takes  to
+simply  move  a  space  varies  with the type of armor worn.
+Movement is always faster when flying.
+</p>
+
+<p align=justify>
+Since actions take time, some of them can be disrupted.
+If  the player is casting a spell, for example, and gets hit
+before finishing it, the  spell  is  lost.   Similarly,  the
+player  might  choke if hit while trying to eat.  Of course,
+the same rule applies when the player hits a monster.
+</p>
+
+<p align=justify>
+Magical  hasting  (or  slowing)   will   decrease   (or
+increase) the time it takes to perform an action.
+</p>
+
+<h3 align="justify">8.0 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">9. 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 "throw" 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 "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
+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.  This corrosive
+property can also apply to weapons when the player hits such
+a monster.
+</p>
+
+
+<h3 align="justify">10. 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">11. 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">12. 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">13.  FOOD</h3>
+
+<p align=justify>
+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>
+
+<p align=justify>
+Food comes in the form of standard  rations  and  as  a
+variety  of  berries.   Some  berries  have  side effects in
+addition to satisfying one's hunger.
+</p>
+
+<h3 align="justify">14.  GOLD</h3>
+
+<p align=justify>
+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  that  sometimes
+occurs "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.
+</p>
+
+<p align=justify>
+The  player  starts  the  game in a trading post with a
+class-dependent  allotment  of  gold.   Although  there  are
+restrictions  on  the  use of some items (eg. only fighters,
+paladins, and rangers  can  wield  two-handed  swords),  the
+market  will  happily  sell  the player anything that he can
+afford.
+</p>
+
+<h3 align="justify">15.  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">16.  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.  These items also can usually be used to the
+player's  advantage.  However,  care  must  be  taken   when
+handling  them  for  they  are  intelligent  and will reject
+mishandling or abuse. These items consume  food  and  merely
+carrying them will result in increased food use.
+</p>
+
+<h3 align="justify">17.  TRAPS</h3>
+
+<p align=justify>
+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">18.  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.  Some monsters even  use  magical  items,  such  as
+wands.   Monsters  with distance weapons or magic 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>
+It  is  sometimes  possible  to enlist a monster's aid.
+Reading a charm monster scroll, for example,  or  singing  a
+charm monster chant can make a monster believe the player is
+its friend.  A charmed monster will fight  hostile  monsters
+for the player as long as they are not of its race.
+</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 "unique  monster"  is  killed,  the
+player will not find another in the current dungeon. 
+</p>
+
+
+<h3 align="justify">19. 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 typeahead 
+		(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">pickup</td>
+		<td>&nbsp;</td>
+		<td>This option specifies whether items should be picked up automatically 
+		as the rogue steps over them. In the non-automatic mode, the player may 
+		still pick up items via the pickup (P) command. The option defaults to 
+		true.</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">file</td>
+		<td>&nbsp;</td>
+		<td>This string, which defaults to arogue77.sav, 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-twenty 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<br>
+		environment variable.</td>
+	</tr>
+	<tr>
+		<td nowrap valign="top">quested item</td>
+		<td>&nbsp;</td>
+		<td>This option is set by the game at the start and cannot be reset by 
+		the player. It is merely listed<br>
+		to remind the player of his quest.</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&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; 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">20. SCORING</h3>
+
+<p align="justify">
+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.
+</p>
+
+<p align="justify">
+Rogue maintains a list of the top twenty 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. As an installation option, the game may record only one entry per character type and login; this 
+restriction encourages a greater number of different players in the scorechart.
+</p>
+
+<h3 align="justify">21. ACKNOWLEDGEMENTS</h3>
+
+<p align="justify">
+This version of Rogue is based on a version developed
+at the University of California.
+</p>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/arogue77.sln	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,21 @@
+Microsoft Visual Studio Solution File, Format Version 7.00
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "arogue77", "arogue77.vcproj", "{D95CFDAC-E66E-47D3-87B7-F76149F6A51D}"
+EndProject
+Global
+	GlobalSection(SolutionConfiguration) = preSolution
+		ConfigName.0 = Debug
+		ConfigName.1 = Release
+	EndGlobalSection
+	GlobalSection(ProjectDependencies) = postSolution
+	EndGlobalSection
+	GlobalSection(ProjectConfiguration) = postSolution
+		{D95CFDAC-E66E-47D3-87B7-F76149F6A51D}.Debug.ActiveCfg = Debug|Win32
+		{D95CFDAC-E66E-47D3-87B7-F76149F6A51D}.Debug.Build.0 = Debug|Win32
+		{D95CFDAC-E66E-47D3-87B7-F76149F6A51D}.Release.ActiveCfg = Release|Win32
+		{D95CFDAC-E66E-47D3-87B7-F76149F6A51D}.Release.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+	EndGlobalSection
+	GlobalSection(ExtensibilityAddIns) = postSolution
+	EndGlobalSection
+EndGlobal
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/arogue77.vcproj	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,270 @@
+<?xml version="1.0" encoding = "Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.00"
+	Name="arogue77"
+	ProjectGUID="{D95CFDAC-E66E-47D3-87B7-F76149F6A51D}"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="Debug"
+			IntermediateDirectory="Debug"
+			ConfigurationType="1"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../pdcurses"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;DUMP"
+				MinimalRebuild="TRUE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="5"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="4"
+				DisableSpecificWarnings="4013;4033;4716"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="shfolder.lib pdcurses.lib"
+				OutputFile="$(OutDir)/arogue77.exe"
+				LinkIncremental="2"
+				AdditionalLibraryDirectories="../pdcurses"
+				IgnoreAllDefaultLibraries="FALSE"
+				IgnoreDefaultLibraryNames="LIBC.LIB"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/arogue77.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;_CONSOLE"
+				StringPooling="TRUE"
+				RuntimeLibrary="4"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="TRUE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)/arogue77.exe"
+				LinkIncremental="1"
+				GenerateDebugInformation="TRUE"
+				SubSystem="1"
+				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>
+	</Configurations>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
+			<File
+				RelativePath="actions.c">
+			</File>
+			<File
+				RelativePath="chase.c">
+			</File>
+			<File
+				RelativePath="command.c">
+			</File>
+			<File
+				RelativePath="daemon.c">
+			</File>
+			<File
+				RelativePath="daemons.c">
+			</File>
+			<File
+				RelativePath="eat.c">
+			</File>
+			<File
+				RelativePath="effects.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="aguide.mm">
+		</File>
+		<File
+			RelativePath="arogue77.doc">
+		</File>
+		<File
+			RelativePath="arogue77.html">
+		</File>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/chase.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,928 @@
+/*
+ * chase.c  -  Code for one object to chase another
+ *
+ * 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.
+ */
+
+/*
+ * Code for one object to chase another
+ *
+ */
+
+#include <ctype.h>
+#include <limits.h>
+#include "curses.h"
+#include "rogue.h"
+#define	MAXINT	INT_MAX
+#define	MININT	INT_MIN
+
+
+/*
+ * 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) ||
+	tp->t_action == A_FREEZE ||
+	(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 prey (ee).  If so, it returns the direction in which to shoot.
+ */
+
+coord *
+can_shoot(er, ee)
+register coord *er, *ee;
+{
+    static coord shoot_dir;
+
+    /* 
+     * They must be in the same room or very close (at door)
+     */
+    if (roomin(er) != roomin(ee) && 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).  Rer is the room of the chaser, and ree is the
+ *	room of the creature being chased (chasee).
+ */
+
+chase(tp, ee, rer, ree, flee)
+register struct thing *tp;
+register coord *ee;
+register struct room *rer, *ree;
+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
+	    */
+{
+    int dist, thisdist, monst_dist = MAXINT; 
+    register coord *er = &tp->t_pos; 
+    struct thing *prey;			/* What we are chasing */
+    coord ch_ret;			/* Where chasing takes you */
+    char ch, mch;
+    bool next_player = FALSE;
+
+    /* 
+     * 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);
+
+    /*
+     * See if our destination is a monster or player.  If so, make "prey" point
+     * to it.
+     */
+    if (ce(hero, *ee)) prey = &player;	/* Is it the player? */
+    else if (tp->t_dest && ce(*(tp->t_dest), *ee)) {	/* Is it a monster? */
+	struct linked_list *item;
+
+	/* What is the monster we're chasing? */
+	item = find_mons(ee->y, ee->x);
+	if (item != NULL) prey = THINGPTR(item);
+	else prey = NULL;
+    }
+    else prey = NULL;
+
+    /* We will use at least one movement period */
+    tp->t_no_move = movement(tp);
+    if (on(*tp, ISFLY)) /* If the creature is flying, speed it up */
+	tp->t_no_move /= 2;
+
+    /*
+     * If the thing is confused or it can't see the player,
+     * let it move randomly. 
+     */
+    if ((on(*tp, ISHUH) && rnd(10) < 8) ||
+	(prey && on(*prey, ISINVIS) && off(*tp, CANSEE))) { /* invisible prey */
+	/*
+	 * get a valid random move
+	 */
+	tp->t_newpos = *rndmove(tp);
+	dist = DISTANCE(tp->t_newpos.y, tp->t_newpos.x, ee->y, ee->x);
+    }
+
+    /*
+     * Otherwise, find the empty spot next to the chaser that is
+     * closest to the chasee.
+     */
+    else {
+	register int ey, ex, x, y;
+	int dist_to_old = MININT; /* Dist from goal to old position */
+
+	/*
+	 * 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)) {
+	    turn_off(*tp, ISRUN);	/* So stop running! */
+	    return;
+	}
+
+	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) || on(*tp, ISFRIENDLY)) &&
+		    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 we are friendly to the player and there is a monster
+		 * in the way that is not of our race, it is okay to move
+		 * there.
+		 */
+		if (step_ok(y, x, FIGHTOK, 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 &&
+			prey != NULL) {
+			/* 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 or are friendly).  next_player
+	 * being TRUE -> we are next to the player but don't want to hit him.
+	 *
+	 * If we are friendly to the player, following him, and standing next
+	 * to him, we will try to help him out in battle.
+	 */
+	if (next_player && off(*tp, WASTURNED)) {
+	    if (off(*tp, ISFRIENDLY) &&
+		((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 */
+		debug("Switching to hero.");
+		tp->t_newpos = hero;
+		tp->t_action = A_MOVE;
+		return;
+	    }
+	    else if (on(*tp, ISFRIENDLY) && !flee && ce(*ee, hero)) {
+		/*
+		 * Look all around the player.  If there is a fightable
+		 * creature next to both of us, hit it.  Otherwise, if
+		 * there is a fightable creature next to the player, try
+		 * to move next to it.
+		 */
+		dist = MAXINT;
+		for (x = hero.x - 1; x <= hero.x + 1; x++) {
+		    if (x < 0 || x >= cols) /* Don't try off the board */
+			continue;
+		    for (y = hero.y - 1; y <= hero.y + 1; y++) {
+			if ((y < 1) || (y >= lines - 2)) /* Stay on the board */
+			    continue;
+
+			/* Is there a fightable monster here? */
+			if (isalpha(mvwinch(mw, y, x)) &&
+			    step_ok(y, x, FIGHTOK, tp) &&
+			    off(*tp, ISSTONE)) {
+			    thisdist = DISTANCE(er->y, er->x, y, x);
+			    if (thisdist < dist) {
+				dist = thisdist;
+				ch_ret.y = y;
+				ch_ret.x = x;
+			    }
+			}
+		    }
+		}
+
+		/* Are we next to a bad guy? */
+		if (dist <= 2) {	/* Get him! */
+		    tp->t_newpos = ch_ret;
+		    tp->t_action = A_MOVE;
+		}
+
+		/* Try to move to the bad guy */
+		else if (dist < MAXINT)
+		    chase(tp, &ch_ret,
+			  roomin(&tp->t_pos), roomin(&ch_ret), FALSE);
+
+		else tp->t_action = A_NIL;
+
+		return;
+	    }
+	}
+
+
+	/*
+	 * If we have decided that we can move onto a monster (we are
+	 * friendly to the player, go to it.
+	 */
+	if (!ce(ch_ret, *er) && isalpha(mvwinch(mw, ch_ret.y, ch_ret.x))) {
+	    debug("Attack monster");
+	    tp->t_newpos = ch_ret;
+	    tp->t_action = A_MOVE;
+	    return;
+	}
+
+	/* 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) {
+		tp->t_action = A_NIL; /* do nothing for awhile */
+		return;
+	}
+
+	/* 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;
+	}
+
+	/* Record the new destination */
+	tp->t_newpos = ch_ret;
+    }
+
+    /*
+     * Do we want to fight or move?  If our selected destination (ch_ret)
+     * is our hero, then we want to fight.  Otherwise, we want to move.
+     */
+    if (ce(tp->t_newpos, hero)) {
+	/* Fight! (or sell) */
+	if (on(*tp, CANSELL)) {
+	    tp->t_action = A_SELL;
+	    tp->t_no_move += movement(tp); /* takes a little time to sell */
+	}
+	else {
+	    tp->t_action = A_ATTACK;
+
+	    /*
+	     * 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 (the case here), it will try to find
+	     * a suitable weapon.
+	     *
+	     * 		Add in rest of time. Fight is 
+	     * 		movement() + weap_move() + FIGHTBASE
+	     */
+	    tp->t_using = wield_weap(NULL, tp);
+	    if (tp->t_using == NULL)
+		tp->t_no_move += weap_move(tp, NULL);
+	    else
+		tp->t_no_move += weap_move(tp, OBJPTR(tp->t_using));
+
+	    if (on(*tp, ISHASTE))
+		    tp->t_no_move += FIGHTBASE/2;
+	    else if (on(*tp, ISSLOW))
+		    tp->t_no_move += FIGHTBASE*2;
+	    else
+		    tp->t_no_move += FIGHTBASE;
+	}
+    }
+    else {
+	/* Move */
+	tp->t_action = A_MOVE;
+
+	/*
+	 * Check if the creature is not next to the player.  If it
+	 * is not and has held or suffocated the player, then stop it!
+	 * Note that this code should more appropriately appear in
+	 * the area that actually moves the monster, but for now it
+	 * is okay here because the player can't move while held or
+	 * suffocating.
+	 */
+	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);
+		msg("You can breathe again.....Whew!");
+	    }
+	}
+    }
+}
+
+/*
+ * do_chase:
+ *	Make one thing chase another.
+ */
+
+do_chase(th)
+register struct thing *th;
+{
+    register struct room *orig_rer,	/* Original room of chaser */
+			 *new_room;	/* new room of monster */
+    char floor, rch, sch;
+    coord old_pos,			/* Old position of monster */
+	  ch_ret;			/* Where we want to go */
+
+    if (on(*th, NOMOVE)) return;
+
+    ch_ret = th->t_newpos;	/* Record our desired new position */
+
+    /*
+     * Make sure we have an open spot (no other monster's gotten in our way,
+     * someone didn't just drop a scare monster there, our prey didn't just
+     * get there, etc.)
+     */
+    if (!step_ok(th->t_newpos.y, th->t_newpos.x, FIGHTOK, th)) {
+	/*
+	 * Most monsters get upset now.  Guardians are all friends,
+	 * and we don't want to see 50 messages in a row!
+	 */
+	if (th->t_stats.s_intel > 4	&&
+	    off(*th, ISUNDEAD)		&&
+	    off(*th, ISGUARDIAN)	&&
+	    off(*th, AREMANY)		&&
+	    off(*th, ISHUH)		&&
+	    off(player, ISBLIND)	&&
+	    cansee(unc(th->t_pos))	&&
+	    !invisible(th))
+	    msg("%s motions angrily.", prname(monster_name(th), TRUE));
+	return;
+    }
+    else if (ce(th->t_newpos, hero) ||	/* Player just got in our way */
+	     isalpha(mvwinch(mw, th->t_newpos.y, th->t_newpos.x))) {
+	bool fightplayer = ce(th->t_newpos, hero);
+
+	/* If we were turned or are friendly, we just have to sit here! */
+	if (fightplayer && (on(*th, WASTURNED) || on(*th, ISFRIENDLY))) return;
+
+	/* Do we want to sell something? */
+	if (fightplayer && on(*th, CANSELL)) {
+	    th->t_action = A_SELL;
+	    th->t_no_move += movement(th); /* takes a little time to sell */
+	    return;
+	}
+
+	/* Let's hit him */
+	th->t_action = A_ATTACK;
+
+	/*
+	 * 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 (the case here), it will try to find
+	 * a suitable weapon.
+	 */
+	th->t_using = wield_weap(NULL, th);
+	/*
+	 * add in rest of time
+	 */
+	if (th->t_using == NULL)
+	    th->t_no_move += weap_move(th, NULL);
+	else
+	    th->t_no_move += weap_move(th, OBJPTR(th->t_using));
+	if (on(*th, ISHASTE))
+		th->t_no_move += FIGHTBASE/2;
+	else if (on(*th, ISSLOW))
+		th->t_no_move += FIGHTBASE*2;
+	else
+		th->t_no_move += FIGHTBASE;
+	return;
+    }
+
+    /*
+     * 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);
+
+    /* Get new and old rooms of monster */
+    new_room = roomin(&ch_ret);
+    orig_rer = roomin(&th->t_pos);
+
+    /* Store the critter's old position and update the current one */
+    old_pos = th->t_pos;
+    th->t_pos = ch_ret;
+    floor = (roomin(&ch_ret) == NULL) ? PASSAGE : FLOOR;
+
+    /* If we have a scavenger, it can pick something up */
+    if (off(*th, ISGUARDIAN)) {
+	register struct linked_list *n_item, *o_item;
+	register int item_count = 0;
+	bool want_something = FALSE;
+
+	while ((n_item = find_obj(ch_ret.y, ch_ret.x)) != NULL) {
+	    register struct object *n_obj, *o_obj;
+	    bool wants_it;
+
+	    /* Does this monster want anything? */
+	    if (want_something == FALSE) {
+		if (on(*th, ISSCAVENGE)  || on(*th, CARRYFOOD)   ||
+		    on(*th, CARRYGOLD)   || on(*th, CARRYSCROLL) ||
+		    on(*th, CARRYPOTION) || on(*th, CARRYRING)   ||
+		    on(*th, CARRYSTICK)  || on(*th, CARRYMISC)   ||
+		    on(*th, CARRYWEAPON) || on(*th, CARRYARMOR)	 ||
+		    on(*th, CARRYDAGGER))  {
+			want_something = TRUE;
+
+			/*
+			 * Blank the area.  We have to do it only before the
+			 * first item in case an item gets dropped in same
+			 * place.  We don't want to blank it out after it get
+			 * dropped.
+			 */
+			mvaddch(ch_ret.y, ch_ret.x, floor);
+
+			/* Were we specifically after something here? */
+			if (ce(*th->t_dest, ch_ret)) {
+			    /* If we're mean, we go after the hero */
+			    if (on(*th, ISMEAN)) runto(th, &hero);
+
+			    /* Otherwise just go back to sleep */
+			    else {
+				turn_off(*th, ISRUN);
+				th->t_dest = NULL;
+			    }
+			}
+		}
+		else break;
+	    }
+
+	    item_count++;	/* Count the number of items */
+
+	    /*
+	     * see if he's got one of this group already
+	     */
+	    o_item = NULL;
+	    n_obj = OBJPTR(n_item);
+	    detach(lvl_obj, n_item);
+
+	    /* See if he wants it */
+	    if (n_obj->o_type == SCROLL && n_obj->o_which == S_SCARE &&
+		th->t_stats.s_intel < 16)
+		wants_it = FALSE; /* Most monsters don't want a scare monster */
+	    else if (on(*th, ISSCAVENGE)) wants_it = TRUE;
+	    else {
+		wants_it = FALSE;	/* Default case */
+		switch (n_obj->o_type) {
+		    case FOOD:	if(on(*th, CARRYFOOD))   wants_it = TRUE;
+		    when GOLD:	if(on(*th, CARRYGOLD))   wants_it = TRUE;
+		    when SCROLL:if(on(*th, CARRYSCROLL)) wants_it = TRUE;
+		    when POTION:if(on(*th, CARRYPOTION)) wants_it = TRUE;
+		    when RING:	if(on(*th, CARRYRING))   wants_it = TRUE;
+		    when STICK:	if(on(*th, CARRYSTICK))  wants_it = TRUE;
+		    when MM:	if(on(*th, CARRYMISC))   wants_it = TRUE;
+		    when ARMOR:	if(on(*th, CARRYARMOR))  wants_it = TRUE;
+		    when WEAPON:if(on(*th, CARRYWEAPON)	||
+				  (on(*th,CARRYDAGGER)&&n_obj->o_which==DAGGER))
+					wants_it = TRUE;
+		}
+	    }
+	    /*
+	     * The quartermaster doesn't sell cursed stuff so he won't
+	     * pick it up
+	     */
+	    if (on(*th, CANSELL) && (n_obj->o_flags & ISCURSED))
+		wants_it = FALSE;
+
+	    /* If he doesn't want it, throw it away */
+	    if (wants_it == FALSE) {
+		fall(n_item, FALSE);
+		continue;
+	    }
+
+	    /* Otherwise, let's pick it up */
+	    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 there was anything here, we may have to update the screen */
+	if (item_count) {
+	    if (cansee(ch_ret.y, ch_ret.x))
+		mvwaddch(cw, ch_ret.y, ch_ret.x, mvinch(ch_ret.y, ch_ret.x));
+	    updpack(TRUE, th); /* Update the monster's encumberance, too */
+	}
+    }
+
+
+    rch = CCHAR( mvwinch(stdscr, old_pos.y, old_pos.x) ); 
+    if (th->t_oldch == floor && rch != floor && !isatrap(rch))
+	mvwaddch(cw, old_pos.y, old_pos.x, rch);
+    else
+	mvwaddch(cw, old_pos.y, old_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 */
+
+    /* 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(old_pos.y, old_pos.x))
+			    light(&old_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 == roomin(th->t_dest) && 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 (fight_flush) md_flushinp();
+    }
+
+    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);
+
+    /* Record monster's last position (if new one is different) */
+    if (!ce(ch_ret, old_pos)) th->t_oldpos = old_pos;
+
+    /* 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);
+    }
+}
+
+
+/* 
+ * 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=NULL, *bolt=NULL, *rock=NULL,
+	*spear = NULL, *dagger=NULL, *dart=NULL, *aklad=NULL;
+    register struct linked_list *pitem;
+    register struct object *obj;
+    bool bow=FALSE, crossbow=FALSE, sling=FALSE;
+
+    for (pitem=tp->t_pack; pitem; pitem=next(pitem)) {
+	obj = OBJPTR(pitem);
+	if (obj->o_type == WEAPON)
+	    switch (obj->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;
+		when SPEAR:	spear = pitem;
+		when DAGGER:
+		    /* Don't throw the dagger if it's our last one */
+		    if (obj->o_count > 1) dagger = pitem;
+		when DART:	dart = pitem;
+	    }
+	else if (obj->o_type == RELIC &&
+		 obj->o_which == AXE_AKLAD)
+		    aklad = pitem;
+    }
+    
+    /* Do we have that all-powerful Aklad Axe? */
+    if (aklad) return(aklad);
+
+    /* Use crossbow bolt if possible */
+    if (crossbow && bolt) return(bolt);
+    if (bow && arrow) return(arrow);
+    if (spear) return(spear);
+    if (dagger) return(dagger);
+    if (sling && rock) return(rock);
+    if (dart) return(dart);
+    return(NULL);
+}
+
+/*
+ * runto:
+ *	Set a monster running after something
+ */
+
+runto(runner, spot)
+register struct thing *runner;
+coord *spot;
+{
+    if (on(*runner, ISSTONE))
+	return;
+
+    /* If we are chasing a new creature, forget about thrown weapons */
+    if (runner->t_dest && !ce(*runner->t_dest, *spot)) runner->t_wasshot=FALSE;
+
+    /*
+     * 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 prey */
+    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/arogue7/command.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,1220 @@
+/*
+ * command.c  -  Read and execute the user commands
+ *
+ * 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.
+ */
+
+/*
+ * Read and execute the user commands
+ *
+ */
+
+#include "curses.h"
+#include <ctype.h>
+#include <signal.h>
+#include "mach_dep.h"
+#include "rogue.h"
+#ifdef PC7300
+#include "sys/window.h"
+extern struct uwdata wdata;
+#endif
+
+/*
+ * command:
+ *	Process the user commands
+ */
+
+command()
+{
+    unsigned char ch;
+    struct linked_list *item;
+    unsigned char countch, direction, newcount = FALSE;
+    int segment = 1;
+    int monst_limit, monst_current;
+
+    monst_limit = monst_current = 1;
+    while (playing) {
+	/*
+	 * Let the daemons start up, but only do them once a round
+	 * (round = 10 segments).
+	 */
+	if (segment >= 10) {
+	    do_daemons(BEFORE);
+	    do_fuses(BEFORE);
+	}
+
+	after = TRUE;
+	do {
+	    /* One more tick of the clock. */
+	    if (segment >= 10 && after && (++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);
+	    }
+
+	    /*
+	     * Don't bother with these updates unless the player's going
+	     * to do something.
+	     */
+	    if (player.t_action == A_NIL && player.t_no_move <= 1) {
+		look(after, FALSE);
+		lastscore = purse;
+		wmove(cw, hero.y, hero.x);
+		if (!((running || count) && jump)) {
+		    status(FALSE);
+		}
+	    }
+
+	    /* Draw the screen */
+	    if (!((running || count) && jump)) {
+		wmove(cw, hero.y, hero.x);
+		draw(cw);
+	    }
+
+	    after = TRUE;
+
+	    /*
+	     * Read command or continue run
+	     */
+	    if (--player.t_no_move <= 0) {
+		take = 0;		/* Nothing here to start with */
+		player.t_no_move = 0;	/* Be sure we don't go too negative */
+		if (!running) door_stop = FALSE;
+
+		/* Was the player being held? */
+		if (player.t_action == A_FREEZE) {
+		    player.t_action = A_NIL;
+		    msg("You can move again.");
+		}
+
+		if (player.t_action != A_NIL) ch = (char) player.t_action;
+		else if (running) {
+		    char scratch;
+
+		    /* If in a corridor or maze, if we are at a turn with
+		     * only one way to go, turn that way.
+		     */
+		    scratch = CCHAR( winat(hero.y, hero.x) );
+		    if ((scratch==PASSAGE||scratch==DOOR||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("");
+		}
+
+		/*
+		 * 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 C_SEARCH: case '.':
+			    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 A_PICKUP:
+			player.t_action = A_NIL;
+			if (add_pack(NULL, FALSE, NULL)) {
+			    char tch;
+
+			    tch = CCHAR( mvwinch(stdscr, hero.y, hero.x) );
+			    if (tch != FLOOR && tch != PASSAGE) {
+			        player.t_action = A_PICKUP; /*get more */
+			        player.t_no_move += 2 * movement(&player);
+			    }
+			}
+		    when A_ATTACK:
+			/* Is our attackee still there? */
+			if (isalpha(winat(player.t_newpos.y,
+					  player.t_newpos.x))) {
+			    /* Our friend is still here */
+			    player.t_action = A_NIL;
+			    fight(&player.t_newpos, cur_weapon, FALSE);
+			}
+			else {	/* Our monster has moved */
+			    player.t_action = A_NIL;
+			}
+		    when A_THROW:
+			if (player.t_action == A_NIL) {
+			    item = get_item(pack, "throw", ALL, FALSE, FALSE);
+			    if (item != NULL && get_dir(&player.t_newpos)) {
+				player.t_action = A_THROW;
+				player.t_using = item;
+				player.t_no_move = 2 * movement(&player);
+			    }
+			    else
+				after = FALSE;
+			}
+			else {
+			    missile(player.t_newpos.y, player.t_newpos.x, 
+				    player.t_using, &player);
+			    player.t_action = A_NIL;
+			    player.t_using = 0;
+			}
+		    when 'Q' : after = FALSE; quit(0);
+		    when 'i' : after = FALSE; inventory(pack, ALL);
+		    when 'I' : after = FALSE; picky_inven();
+		    when C_DROP : player.t_action = C_DROP; drop(NULL);
+		    when 'P' :
+			if (levtype != POSTLEV) {
+			    /* We charge 2 movement units per item */
+			    player.t_no_move =
+				2 * grab(hero.y, hero.x) * movement(&player);
+			}
+			else {
+			    /* Let's quote the wise guy a price */
+			    buy_it();
+			    after = FALSE;
+			}
+		    when C_COUNT : count_gold();
+		    when C_QUAFF : quaff(-1, NULL, NULL, TRUE);
+		    when C_READ : read_scroll(-1, NULL, TRUE);
+		    when C_EAT : eat();
+		    when C_WIELD : wield();
+		    when C_WEAR : wear();
+		    when C_TAKEOFF : take_off();
+		    when 'o' : option();
+		    when CTRL('N') : nameit();
+		    when '=' : after = FALSE; display();
+		    when 'm' : nameitem(NULL, TRUE);
+		    when '>' : after = FALSE; d_level();
+		    when '<' : after = FALSE; u_level();
+		    when '?' : after = FALSE; help();
+		    when '/' : after = FALSE; identify(NULL);
+		    when C_USE : use_mm(-1);
+		    when CTRL('T') :
+			if (player.t_action == A_NIL) {
+			    if (get_dir(&player.t_newpos)) {
+				player.t_action = CTRL('T');
+				player.t_no_move = 2 * movement(&player);
+			    }
+			    else
+				after = FALSE;
+			}
+			else {
+			    steal();
+			    player.t_action = A_NIL;
+			}
+		    when C_DIP : dip_it();
+		    when 'G' :
+			if (player.t_action == A_NIL) {
+			    player.t_action = 'G';
+			    player.t_no_move = movement(&player);
+			}
+			else {
+			    gsense();
+			    player.t_action = A_NIL;
+			}
+		    when C_SETTRAP : set_trap(&player, hero.y, hero.x);
+		    when C_SEARCH :
+			if (player.t_action == A_NIL) {
+			    player.t_action = C_SEARCH;
+			    player.t_no_move = 5 * movement(&player);
+			}
+			else {
+			    search(FALSE, FALSE);
+			    player.t_action = A_NIL;
+			}
+		    when C_ZAP : if (!player_zap(NULL, FALSE))
+				    after=FALSE;
+		    when C_PRAY : pray();
+		    when C_CHANT : chant();
+		    when C_CAST : cast();
+		    when 'a' :
+			if (player.t_action == A_NIL) {
+			    if (get_dir(&player.t_newpos)) {
+				player.t_action = 'a';
+				player.t_no_move = 2 * movement(&player);
+			    }
+			    else
+				after = FALSE;
+			}
+			else {
+			    affect();
+			    player.t_action = A_NIL;
+			}
+		    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();
+#ifdef PC7300
+			    endhardwin();
+#endif
+			    exit(0);
+			}
+		    when '.' :
+			player.t_no_move = movement(&player);  /* Rest */
+			player.t_action = A_NIL;
+		    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') : msg("food left: %d\tfood level: %d", 
+						    food_left, foodlev);
+			    when CTRL('A') : activity();
+			    when CTRL('C') : 
+			    {
+				int tlev;
+				prbuf[0] = 0;
+				msg("Which level? ");
+				if(get_str(prbuf,msgw) == 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('G') :
+			    {
+				item=get_item(pack,"charge",STICK,FALSE,FALSE);
+				if (item != NULL) {
+				    (OBJPTR(item))->o_charges=10000;
+				}
+			    }
+			    when CTRL('H') :
+			    {
+				register int i;
+				register struct object *obj;
+
+				for (i = 0; i < 9; i++)
+				    raise_level();
+				/*
+				 * 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);
+				    (OBJPTR(item))->o_flags |= (ISKNOW|ISPROT);
+				}
+				/*
+				 * And his suit of armor
+				 */
+				if (player.t_ctype != C_MONK) {
+				    item = spec_item(ARMOR, PLATE_ARMOR, 10, 0);
+				    obj = OBJPTR(item);
+				    if (player.t_ctype == C_THIEF)
+				        obj->o_which = STUDDED_LEATHER;
+				    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;
+			}
+		}
+
+		/*
+		 * If he ran into something to take, let him pick it up.
+		 * unless it's a trading post
+		 */
+		if (auto_pickup && take != 0 && levtype != POSTLEV) {
+		    /* get ready to pick it up */
+		    player.t_action = A_PICKUP;
+		    player.t_no_move += 2 * movement(&player);
+		}
+	    }
+
+	    /* If he was fighting, let's stop (for now) */
+	    if (player.t_quiet < 0) player.t_quiet = 0;
+
+	    if (!running)
+		door_stop = FALSE;
+
+	    if (after && segment >= 10) {
+		/*
+		 * Kick off the rest if the daemons and fuses
+		 */
+
+		/* 
+		 * If player is infested, take off a hit point 
+		 */
+		if (on(player, HASINFEST)) {
+		    if ((pstats.s_hpt -= infest_dam) <= 0) death(D_INFESTATION);
+		}
+
+		/*
+		 * The eye of Vecna is a constant drain on the player
+		 */
+		if (cur_relic[EYE_VECNA]) {
+		    if ((--pstats.s_hpt) <= 0) death(D_RELIC);
+		}
+
+		/* 
+		 * 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);
+	    }
+	} while (after == FALSE);
+
+	/* Make the monsters go */
+	if (--monst_current <= 0)
+	    monst_current = monst_limit = runners(monst_limit);
+
+#ifdef NEEDLOOK
+	/* Shall we take a look? */
+	if (player.t_no_move <= 1 &&
+	    !((running || count) && jump))
+	    look(FALSE, FALSE);
+#endif
+
+	if (++segment > 10) segment = 1;
+	t_free_list(monst_dead);
+    }
+}
+
+/*
+ * display
+ * 	tell the player what is at a certain coordinates assuming
+ *	it can be seen.
+ */
+display()
+{
+    coord c;
+    struct linked_list *item;
+    struct thing *tp;
+    int what;
+
+    msg("What do you want to display (* for help)?");
+    c = get_coordinates();
+    mpos = 0;
+    if (!cansee(c.y, c.x)) {
+	msg("You can't see what is there.");
+	return;
+    }
+    what = mvwinch(cw, c.y, c.x);
+    if (isalpha(what)) {
+	item = find_mons(c.y, c.x);
+	tp = THINGPTR(item);
+	msg("%s", monster_name(tp));
+	return;
+    }
+    if ((item = find_obj(c.y, c.x)) != NULL) {
+	msg("%s", inv_name(OBJPTR(item), FALSE));
+	return;
+    }
+    identify(what);
+}
+
+/*
+ * quit:
+ *	Have player make certain, then exit.
+ */
+
+void
+quit(sig)
+int sig;
+{
+    /*
+     * Reset the signal in case we got here via an interrupt
+     */
+    if (signal(SIGINT, quit) != quit)
+	mpos = 0;
+    msg("Really quit? <yes or no> ");
+    draw(cw);
+    prbuf[0] = '\0';
+    if ((get_str(prbuf, msgw) == NORM) && strcmp(prbuf, "yes") == 0) {
+	clear();
+	move(lines-1, 0);
+	draw(stdscr);
+	score(pstats.s_exp + (long) purse, CHICKEN, 0);
+#ifdef PC7300
+	endhardwin();
+#endif
+	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 && mvwinch(cw, y, x) == mch)
+			mp->t_oldch = ch; /* Will change when monst moves */
+		    else mvwaddch(cw, y, x, ch);
+
+		    count = 0;
+		    running = FALSE;
+
+		    /* Stop what we were doing */
+		    player.t_no_move = movement(&player);
+		    player.t_action = A_NIL;
+		    player.t_using = NULL;
+
+		    if (fight_flush) md_flushinp();
+		    msg(tr_name(tp->tr_type));
+	    }
+	    else if (ch == SECRETDOOR) {
+		if (door_chime == TRUE || (!is_thief && rnd(100) < 20)) {
+		    struct room *rp;
+		    coord cp;
+
+		    /* 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;
+		    /*
+		     * if its the entrance to a treasure room, wake it up
+		     */
+		    cp.y = y;
+		    cp.x = x;
+		    rp = roomin(&cp);
+		    if (rp->r_flags & ISTREAS)
+			wake_room(rp);
+
+		    /* Make sure we don't shoot into the room */
+		    if (door_chime == FALSE) {
+			count = 0;
+			running = FALSE;
+
+			/* Stop what we were doing */
+			player.t_no_move = movement(&player);
+			player.t_action = A_NIL;
+			player.t_using = NULL;
+		    }
+		}
+	    }
+	}
+}
+
+
+/*
+ * 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(msgw, 0, 0);
+	while (strp->h_ch) {
+	    if (strp->h_ch == helpch) {
+		msg("%s%s", unctrl(strp->h_ch), strp->h_desc);
+		return;
+	    }
+	    strp++;
+	}
+#ifdef WIZARD
+	if (wizard) {
+	    while (wizp->h_ch) {
+		if (wizp->h_ch == helpch) {
+		    msg("%s%s", unctrl(wizp->h_ch), wizp->h_desc);
+		    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(' ');
+	    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(' ');
+		wclear(hw);
+		cnt = 0;
+	    }
+	}
+    }
+#endif
+    wmove(hw, lines-1, 0);
+    wprintw(hw, spacemsg);
+    draw(hw);
+    wait_for(' ');
+    wclear(hw);
+    draw(hw);
+    wmove(cw, 0, 0);
+    wclrtoeol(cw);
+    status(FALSE);
+    touchwin(cw);
+}
+/*
+ * identify:
+ *	Tell the player what a certain thing is.
+ */
+
+identify(ch)
+register char ch;
+{
+    register char *str;
+
+    if (ch == 0) {
+	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";
+    }
+    msg("'%s' : %s", unctrl(ch), str);
+}
+
+/*
+ * d_level:
+ *	He wants to go down a level
+ */
+
+d_level()
+{
+    bool no_phase=FALSE;
+    char position = CCHAR( winat(hero.y, hero.x) );
+
+
+    /* If we are on a trading post, go to a trading post level. */
+    if (position == POST) {
+	new_level(POSTLEV);
+	return;
+    }
+
+    /* If we are at a top-level trading post, we probably can't go down */
+    if (levtype == POSTLEV && level == 0 && position != STAIRS) {
+	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()
+{
+    register char *sh;
+
+    /*
+     * Set the terminal back to original mode
+     */
+    sh = getenv("SHELL");
+    wclear(hw);
+    wmove(hw, lines-1, 0);
+    draw(hw);
+    endwin();
+    in_shell = TRUE;
+    fflush(stdout);
+    /*
+     * Fork and do a shell
+     */
+    
+    md_shellescape();
+
+	printf(retstr);
+	noecho();
+	raw();
+	keypad(cw,1);
+	keypad(msgw,1);
+	in_shell = FALSE;
+	wait_for('\n');
+	clearok(cw, TRUE);
+	touchwin(cw);
+}
+
+/*
+ * see what we want to name -- an item or a monster.
+ */
+nameit()
+{
+    char answer;
+
+    msg("Name monster or item (m or i)? ");
+    answer = readchar();
+    mpos = 0;
+
+    while (answer != 'm' && answer != 'i' && answer != ESCAPE) {
+	mpos = 0;
+	msg("Please specify m or i, for monster or item - ");
+	answer = readchar();
+    }
+
+    switch (answer) {
+	case 'm': namemonst();
+	when 'i': nameitem(NULL, FALSE);
+    }
+}
+
+/*
+ * allow a user to call a potion, scroll, or ring something
+ */
+nameitem(item, mark)
+struct linked_list *item;
+bool mark;
+{
+    register struct object *obj;
+    register char **guess, *elsewise;
+    register bool *know;
+
+    if (item == NULL) {
+	if (mark) item = get_item(pack, "mark", ALL, FALSE, FALSE);
+	else	  item = get_item(pack, "name", CALLABLE, FALSE, FALSE);
+	if (item == NULL) return;
+    }
+    /*
+     * Make certain that it is somethings that we want to wear
+     */
+    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 {
+	if (elsewise) {
+	    addmsg(terse ? "N" : "Was n");
+	    msg("amed \"%s\"", elsewise);
+	    strcpy(prbuf, elsewise);
+	}
+	else prbuf[0] = '\0';
+	msg(terse ? "Name it: " : "What do you want to name it? ");
+    }
+    if (get_str(prbuf, msgw) == NORM) {
+	if (mark) {
+	    strncpy(obj->o_mark, prbuf, MARKLEN-1);
+	    obj->o_mark[MARKLEN-1] = '\0';
+	}
+	else if (prbuf[0] != '\0') {
+	    if (guess[obj->o_which] != NULL)
+		free(guess[obj->o_which]);
+	    guess[obj->o_which] = new((unsigned int) strlen(prbuf) + 1);
+	    strcpy(guess[obj->o_which], prbuf);
+	}
+    }
+}
+
+/* Name a monster */
+
+namemonst()
+{
+    register struct thing *tp;
+    struct linked_list *item;
+    coord c;
+
+    /* Find the monster */
+    msg("Choose the monster (* for help)");
+    c = get_coordinates();
+
+    /* Make sure we can see it and that it is a monster. */
+    mpos = 0;
+    if (!cansee(c.y, c.x)) {
+	msg("You can't see what is there.");
+	return;
+    }
+    
+    if (isalpha(mvwinch(cw, c.y, c.x))) {
+	item = find_mons(c.y, c.x);
+	if (item != NULL) {
+	    tp = THINGPTR(item);
+	    if (tp->t_name == NULL)
+		strcpy(prbuf, monsters[tp->t_index].m_name);
+	    else
+		strcpy(prbuf, tp->t_name);
+
+	    addmsg(terse ? "N" : "Was n");
+	    msg("amed \"%s\"", prbuf);
+	    msg(terse ? "Name it: " : "What do you want to name it? ");
+
+	    if (get_str(prbuf, msgw) == NORM) {
+		if (prbuf[0] != '\0') {
+		    if (tp->t_name != NULL)
+			free(tp->t_name);
+		    tp->t_name = new((unsigned int) strlen(prbuf) + 1);
+		    strcpy(tp->t_name, prbuf);
+		}
+	    }
+	    return;
+	}
+    }
+
+    msg("There is no monster there to name.");
+}
+
+count_gold()
+{
+	if (player.t_action != C_COUNT) {
+	    msg("You take a break to count your money...");
+	    player.t_using = NULL;
+	    player.t_action = C_COUNT;	/* We are counting */
+	    player.t_no_move = (purse/300 + 1) * movement(&player);
+	    return;
+	}
+	if (purse > 100)
+		msg("You think you have about %d gold pieces.", purse);
+	else
+		msg("You have %d gold pieces.", purse);
+	player.t_action = A_NIL;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/daemon.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,252 @@
+/*
+ * daemon.c  -  functions for dealing with things that happen in the future.
+ *
+ * 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.
+ */
+
+/*
+ * Contains functions for dealing with things that happen in the
+ * future.
+ *
+ */
+
+#include "curses.h"
+#include "rogue.h"
+
+#define EMPTY		0
+#define DAEMON		-1
+#define MAXDAEMONS	10
+#define MAXFUSES	20
+
+#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_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()
+{
+	msg("Daemons = %d : Fuses = %d : Memory Items = %d : Memory Used = %d",
+	    demoncnt,fusecnt,total,md_memused(0));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/daemons.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,663 @@
+/*
+ * daemon.c  -  All the daemon and fuse functions are in here
+ *
+ * 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.
+ */
+
+/*
+ * All the daemon and fuse functions are in here
+ *
+ */
+
+#include "curses.h"
+#include "rogue.h"
+
+/*
+ * 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:
+	case C_ASSASIN:
+	case C_MONK:
+	    limit = 8 - curp->s_lvl;
+	    new_points = curp->s_lvl - 2;
+	when C_CLERIC:
+	case C_DRUID:
+	    limit = 8 - curp->s_lvl;
+	    new_points = curp->s_lvl - 3;
+	when C_FIGHTER:
+	case C_RANGER:
+	case C_PALADIN:
+	    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
+ */
+
+int between = 0;
+
+rollwand()
+{
+
+    if (++between >= 4)
+    {
+	/* Theives may not awaken a monster */
+	if ((roll(1, 6) == 4) &&
+	   ((player.t_ctype != C_THIEF && player.t_ctype != C_ASSASIN) || 
+	    (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
+ */
+
+void
+res_strength(howmuch)
+int howmuch;
+{
+
+    /* 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;
+    }
+
+    /* Now, add in the restoral, but no greater than maximum strength */
+    if (howmuch > 0)
+	pstats.s_str =
+    	    min(pstats.s_str + howmuch, max_stats.s_str + ring_value(R_ADDSTR));
+
+    updpack(TRUE, &player);
+}
+
+/*
+ * 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;
+
+    /* 
+     * avoid problems of fainting while eating by just not saying it
+     * takes food to eat food
+     */
+    if (player.t_action == C_EAT) 
+	return;
+
+    old_hunger = hungry_state;
+    if (food_left <= 0)
+    {
+	/*
+	 * the hero is fainting
+	 */
+	if (player.t_action == A_FREEZE)
+		return;
+	if (rnd(100) > 20)
+	    return;
+	if (hungry_state == F_FAINT && rnd(20) == 7) /*must have fainted once*/
+		death(D_STARVATION);
+	player.t_action = A_FREEZE;
+	player.t_no_move = movement(&player) * (rnd(8) + 4);
+	if (!terse)
+	    addmsg("You feel too weak from lack of food. ");
+	msg("You faint");
+	running = FALSE;
+	if (fight_flush) md_flushinp();
+	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;
+	    if (fight_flush) md_flushinp();
+	    count = 0;
+	    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;
+	}
+	else if(food_left<STOMACHSIZE-MORETIME && oldfood>=STOMACHSIZE-MORETIME)
+	{
+	    hungry_state = F_OKAY;
+	}
+    }
+    if (old_hunger != hungry_state)  {
+	updpack(TRUE, &player);
+	status(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");
+}
+
+/*
+ * 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;
+    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(11)) {
+	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;
+	when 9: tobj->o_ac = P_SKILL;
+	when 10:tobj->o_ac = P_FFIND;
+    }
+}
+/*
+ * 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_flags & ISCURSED)	&&
+	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) {
+	    switch(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:
+		drop(item);
+		running = FALSE;
+		break;
+	    default:
+		break;
+	    }
+	}
+    }
+}
+/*
+ * 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();
+}
+/* 
+ * this is called to charge up the quill of Nagrom
+ */
+quill_charge()
+{
+    register struct object *tobj;
+    register struct linked_list *item;
+
+    /*
+     * find the Quill of Nagrom in the hero's pack. It should still be there
+     * because it can't be dropped. If its not then don't do anything.
+     */
+    for (item = pack; item != NULL; item = next(item)) {
+	tobj = OBJPTR(item);
+	if (tobj->o_type == RELIC && tobj->o_which == QUILL_NAGROM)
+		break;
+    }
+    if (item == NULL)
+	return;
+    if (tobj->o_charges < QUILLCHARGES)
+	tobj->o_charges++;
+    fuse (quill_charge, 0, player.t_ctype == C_MAGICIAN ? 4 : 8, AFTER);
+}
+/*
+ * take the skills away gained (or lost) by the potion of skills
+ */
+unskill()
+{
+    if (pstats.s_lvladj != 0) {
+	pstats.s_lvl -= pstats.s_lvladj;
+	pstats.s_lvladj = 0;
+	msg("You feel your normal skill level return.");
+	status(TRUE);
+    }
+}
+/*
+ * charge up the cloak of Emori
+ */
+
+cloak_charge(obj)
+register struct object *obj;
+{
+	if (obj->o_charges < 1)
+		obj->o_charges = 1;
+}
+
+/*
+ * nofire:
+ *	He lost his fire resistance
+ */
+nofire()
+{
+    if (!ISWEARING(R_FIRE)) {
+	turn_off(player, NOFIRE);
+	msg("Your feeling of fire resistance leaves you");
+    }
+}
+
+/*
+ * nocold:
+ *	He lost his cold resistance
+ */
+nocold()
+{
+    if (!ISWEARING(R_WARMTH)) {
+	turn_off(player, NOCOLD);
+	msg("Your feeling of warmth leaves you");
+    }
+}
+
+/*
+ * nobolt:
+ *	He lost his protection from lightning
+ */
+nobolt()
+{
+    turn_off(player, NOBOLT);
+    msg("Your skin looses its bluish tint");
+}
+/*
+ * eat_gold:
+ *	an artifact eats gold 
+ */
+eat_gold(obj)
+register struct object *obj;
+{
+    if (purse == 1)
+	msg("%s demand you find more gold", inv_name(obj, FALSE));
+    if (purse == 0) {
+	if (--pstats.s_hpt <= 0)
+	    death(D_RELIC);
+    }
+    else
+	purse--;
+}
+/*
+ * give the hero back some spell points
+ */
+spell_recovery()
+{
+    int time;
+
+    time = SPELLTIME - max(17-pstats.s_intel, 0);
+    time = max(time, 5);
+    if (spell_power > 0) spell_power--;
+    fuse(spell_recovery, NULL, time, AFTER);
+}
+/*
+ * give the hero back some prayer points
+ */
+prayer_recovery()
+{
+    int time;
+
+    time = SPELLTIME - max(17-pstats.s_wisdom, 0);
+    time = max(time, 5);
+    if (pray_time > 0) pray_time--;
+    fuse(prayer_recovery, NULL, time, AFTER);
+}
+/*
+ * give the hero back some chant points
+ */
+chant_recovery()
+{
+    int time;
+
+    time = SPELLTIME - max(17-pstats.s_wisdom, 0);
+    time = max(time, 5);
+    if (chant_time > 0) chant_time--;
+    fuse(chant_recovery, NULL, time, AFTER);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/eat.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,130 @@
+/*
+ * eat.c  -  Functions for dealing with digestion
+ *
+ * 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.
+ */
+
+#include "curses.h"
+#include "rogue.h"
+
+/*
+ * eat:
+ *	He wants to eat something, so let him try
+ */
+
+eat()
+{
+    register struct linked_list *item;
+    int which;
+    unsigned long temp;
+
+    if (player.t_action != C_EAT) {
+	if ((item = get_item(pack, "eat", FOOD, FALSE, FALSE)) == NULL)
+	    return;
+
+	player.t_using = item;	/* Remember what it is */
+	player.t_action = C_EAT;	/* We are eating */
+	which = (OBJPTR(item))->o_which;
+	player.t_no_move = max(foods[which].mi_food/100, 1) * movement(&player);
+	return;
+    }
+
+    /* We have waited our time, let's eat the food */
+    item = player.t_using;
+    player.t_using = NULL;
+    player.t_action = A_NIL;
+
+    which = (OBJPTR(item))->o_which;
+    if ((food_left += foods[which].mi_food) > STOMACHSIZE)
+	food_left = STOMACHSIZE;
+    del_pack(item);
+    if (hungry_state == F_SATIATED && food_left == STOMACHSIZE && rnd(4) == 1) {
+	pstats.s_hpt = 0;
+	msg ("You choke on all that food and die! -- More --");
+	wait_for(' ');
+	death(D_FOOD_CHOKE);
+    }
+    if (food_left >= STOMACHSIZE-MORETIME) {
+	hungry_state = F_SATIATED;
+	msg ("You have trouble getting all that food down.");
+	msg ("Your stomach feels like its about to burst!");
+    }
+    else {
+	hungry_state = F_OKAY;
+	switch (rnd(3)) {
+	case 0: msg("My, that was a yummy %s", foods[which].mi_name);
+	when 1: msg("Mmmm, that was a tasty %s", foods[which].mi_name);
+	when 2: msg("Wow, that was a scrumptious %s", foods[which].mi_name);
+	}
+    }
+    updpack(TRUE, &player);
+    switch(which) {
+    case E_WHORTLEBERRY:
+	add_abil[A_INTELLIGENCE](1);
+
+    when E_SWEETSOP:
+	add_abil[A_DEXTERITY](1);
+
+    when E_SOURSOP:
+	add_abil[A_STRENGTH](1);
+
+    when E_SAPODILLA:
+	add_abil[A_WISDOM](1);
+
+    when E_RAMBUTAN:
+	add_abil[A_CONSTITUTION](1);
+
+    when E_PEACH:
+	add_abil[A_CHARISMA](1);
+
+    when E_STRAWBERRY:
+	temp = pstats.s_exp/100;
+	pstats.s_exp += temp;
+	if (temp > 0)
+	    msg("You feel slightly more experienced now");
+	check_level();
+
+    when E_PITANGA:
+	max_stats.s_hpt++;
+	pstats.s_hpt++;
+	if (terse)
+	    msg("You feel a bit tougher now");
+	else
+	    msg("You feel a bit tougher now. Go get 'em!");
+    
+    when E_HAGBERRY:
+	pstats.s_arm--;
+	msg("Your skin feels more resilient now");
+
+    when E_DEWBERRY:
+	if (chant_time > 0) {
+	    chant_time -= 50;
+	    if (chant_time < 0)
+		chant_time = 0;
+	    msg("You feel you have more chant ability");
+	}
+	if (pray_time > 0) {
+	    pray_time -= 50;
+	    if (pray_time < 0)
+		pray_time = 0;
+	    msg("You feel you have more prayer ability");
+	}
+	if (spell_power > 0) {
+	    spell_power -= 50;
+	    if (spell_power < 0)
+		spell_power = 0;
+	    msg("You feel you have more spell casting ability");
+	}
+
+    otherwise: /* all the foods don't have to do something */
+	break;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/effects.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,699 @@
+/*
+ * effects.c  -  functions for dealing with appllying effects to monsters
+ *
+ * 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.
+ */
+
+#include "curses.h"
+#include "rogue.h"
+
+/*
+ * effect:
+ *	Check for effects of one thing hitting another thing.  Return
+ *	the reason code if the defender is killed.  Otherwise return 0.
+ */
+effect(att, def, weap, thrown, see_att, see_def)
+register struct thing *att, *def;
+struct object *weap;
+bool thrown;
+register bool see_att, see_def;
+{
+    register bool att_player, def_player;
+    char attname[LINELEN+1], defname[LINELEN+1];
+
+    /* See if the attacker or defender is the player */
+    att_player = (att == &player);
+    def_player = (def == &player);
+
+    /*
+     * If the player could see the attacker or defender, they can't
+     * surprise anymore (don't bother checking if they could).
+     */
+    if (see_att) turn_off(*att, CANSURPRISE);
+    if (see_def) turn_off(*def, CANSURPRISE);
+
+    /* What are the attacker and defender names? */
+    if (att_player) strcpy(attname, "you");
+    else {
+	if (see_att) strcpy(attname, monster_name(att));
+	else strcpy(attname, "something");
+    }
+
+    if (def_player) strcpy(defname, "you");
+    else {
+	if (see_def) strcpy(defname, monster_name(def));
+	else strcpy(defname, "something");
+    }
+
+    /*
+     * See what happens to the attacker first.  We can skip this
+     * whole section, however, if the defender is the player.
+     * Nothing happens (yet) to anyone just for hitting the player.
+     */
+    if (!def_player) {
+	if (!thrown) {	/* Some things require a direct hit. */
+	    /*
+	     * If the attacker hits a rusting monster, The weapon
+	     * may be damaged
+	     */
+	    if (on(*def, CANRUST)	&& weap				&&
+		weap->o_type != RELIC	&& (weap->o_flags & ISMETAL)	&&
+		!(weap->o_flags & ISPROT)) {
+		    if ((weap->o_hplus < 1 && weap->o_dplus < 1) ||
+			roll(1,20) < weap->o_hplus+weap->o_dplus+10) {
+			    if (rnd(100) < 50) weap->o_hplus--;
+			    else               weap->o_dplus--;
+			    if (att_player)
+				msg(terse ? "Your %s weakens!"
+					  : "Your %s appears to be weaker now!",
+				    weaps[weap->o_which].w_name);
+		    }
+	    }
+	}
+		
+	/* If the attacker hit something that shrieks, wake the dungeon */
+	if (on(*def, CANSHRIEK)) {
+	    turn_off(*def, CANSHRIEK);
+	    if (see_def)
+		msg("%s emits a piercing shriek.", prname(defname, TRUE));
+	    else msg("You hear a piercing shriek.");
+	    aggravate(TRUE, TRUE);
+	}
+
+	/*
+	 * does the creature explode when hit?
+	 */
+	if (on(*def, CANEXPLODE)) {
+	    if (see_def) msg("%s explodes!", prname(defname, TRUE));
+	    else msg("You hear a tremendous explosion!");
+	    explode(def);
+	    if (pstats.s_hpt <= 0)
+	        death(def->t_index);
+	}
+    }
+
+    /*
+     * Now let's see what happens to the defender.  Start out with
+     * the things that everyone can do.  Then exit if the attacker
+     * is the player.
+     */
+    if (!thrown) {
+	/* 
+	 * Can the player confuse? 
+	 */
+	if (on(*att, CANHUH) && att_player) {
+	    msg("Your hands stop glowing red.");
+	    if (off(*def, ISCLEAR) && 
+	       (off(*def, ISUNIQUE) || !save(VS_MAGIC, def, 0))) {
+		if (see_def) msg("%s appears confused.", prname(defname, TRUE));
+		turn_on(*def, ISHUH);
+	    }
+	    turn_off(*att, CANHUH);
+	}
+
+	/* Return now if the attacker is the player. */
+	if (att_player) return(0);
+
+	/*
+	 * Some monsters may take half your hit points
+	 */
+	if (on(*att, CANSUCK) && !save(VS_MAGIC, def, 0)) {
+	    if (def->t_stats.s_hpt == 1) return(att->t_index); /* Killed! */
+	    else {
+	        def->t_stats.s_hpt /= 2;
+	        if (def_player)
+		    msg("You feel your life force being drawn from you.");
+	    }
+	}
+
+	/*
+	 * If a hugging monster hits, it may SQUEEEEEEEZE.
+	 */
+	if (on(*att, CANHUG)) {
+	    if (roll(1,20) >= 18 || roll(1,20) >= 18) {
+		if (def_player)
+		    msg("%s squeezes you against itself.",
+				prname(attname, TRUE));
+		else if (see_att)
+		    msg("%s squeezes hard.", prname(attname, TRUE));
+
+		if ((def->t_stats.s_hpt -= roll(2,8)) <= 0)
+		    return(att->t_index);
+	    }
+	}
+
+	/*
+	 * Some monsters have poisonous bites.
+	 */
+	if (on(*att, CANPOISON) && !save(VS_POISON, def, 0)) {
+	    if (def_player) {
+		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");
+		}
+	    }
+	    else {
+		/* Subtract a strength point and see if it kills it */
+		if (--def->t_stats.s_str <= 0) return(D_STRENGTH);
+	    }
+	}
+
+	/*
+	 * Turning to stone:
+	 */
+	if (on(*att, TOUCHSTONE)) {
+	    if (def_player) turn_off(*att, TOUCHSTONE);
+	    if (on(*def, CANINWALL)) {
+		if (def_player)
+		    msg("%s's touch has no effect.", prname(attname, TRUE));
+	    }
+	    else {
+		if (!save(VS_PETRIFICATION, def, 0) && rnd(100) < 10) {
+		    if (def_player) {
+			msg("Your body begins to solidify.");
+			msg("You are turned to stone !!! --More--");
+			wait_for(' ');
+			return(D_PETRIFY);
+		    }
+		    else {
+			/* The monster got stoned! */
+			turn_on(*def, ISSTONE);
+			turn_off(*def, ISRUN);
+			turn_off(*def, ISINVIS);
+			turn_off(*def, ISDISGUISE);
+			if (see_def)
+			    msg("%s turns to stone.", prname(defname, TRUE));
+			else if (cansee(unc(def->t_pos)))
+			    msg("A new statue appears!");
+		    }
+		}
+		else if (def->t_action != A_FREEZE) {
+		    if (def_player)
+			msg("%s's touch stiffens your limbs.",
+					prname(attname, TRUE));
+		    else if (see_def)
+			msg("%s appears to freeze.", prname(defname, TRUE));
+
+		    def->t_no_move += movement(def) * STONETIME;
+		    def->t_action = A_FREEZE;
+		}
+	    }
+	}
+
+	/*
+	 * Wraiths might drain energy levels
+	 */
+	if ((on(*att, CANDRAIN) || on(*att, DOUBLEDRAIN)) && 
+	    !save(VS_POISON, def, 3-(att->t_stats.s_lvl/5))) {
+	    if (def_player) {
+		lower_level(att->t_index);
+		if (on(*att, DOUBLEDRAIN)) lower_level(att->t_index);
+		turn_on(*att, DIDDRAIN);  
+	    }
+	    else {
+		def->t_stats.s_hpt -= roll(1, 8);
+		def->t_stats.s_lvl--;
+		if (on(*att, DOUBLEDRAIN)) {
+		    def->t_stats.s_hpt -= roll(1, 8);
+		    def->t_stats.s_lvl--;
+		}
+		if (see_def)
+		    msg("%s appears less skillfull.", prname(defname, TRUE));
+
+		/* Did it kill it? */
+		if (def->t_stats.s_hpt <= 0 ||
+		    def->t_stats.s_lvl <= 0)
+		    return(att->t_index);
+	    }
+	}
+
+	/*
+	 * Paralyzation:
+	 */
+	if (on(*att, CANPARALYZE) && def->t_action != A_FREEZE) {
+	    if (def_player) turn_off(*att, CANPARALYZE);
+	    if (!save(VS_PARALYZATION, def, 0)) {
+		if (on(*def, CANINWALL)) {
+		    if (def_player)
+			msg("%s's touch has no effect.", prname(attname, TRUE));
+		}
+		else {
+		    if (def_player)
+			msg("%s's touch paralyzes you.", prname(attname, TRUE));
+		    else if (see_def)
+			msg("%s appears to freeze.", prname(defname, TRUE));
+
+		    def->t_no_move += movement(def) * FREEZETIME;
+		    def->t_action = A_FREEZE;
+		}
+	    }
+	}
+
+	/*
+	 * Painful wounds make the defendant faint
+	 */
+	 if (on(*att, CANPAIN) && def->t_action != A_FREEZE) {
+	    if (def_player) turn_off(*att, CANPAIN);
+	    if (!ISWEARING(R_ALERT) && !save(VS_POISON, def, 0)) {
+		    if (def_player)
+			msg("You faint from the painful wound");
+		    else if (see_def)
+			msg("%s appears to faint.", prname(defname, TRUE));
+
+		    def->t_no_move += movement(def) * PAINTIME;
+		    def->t_action = A_FREEZE;
+	    }
+	}
+
+	/*
+	 * Some things currently affect only the player.  Let's make
+	 * a check here so we don't have to check for each thing.
+	 */
+	if (def_player) {
+	/*
+	 * Stinking monsters make the defender weaker (to hit).  For now
+	 * this will only affect the player.  We may later add the HASSTINK
+	 * effect to monsters, too.
+	 */
+	    if (on(*att, CANSTINK)) {
+		turn_off(*att, CANSTINK);
+		if (!save(VS_POISON, def, 0)) {
+		    msg("The stench of %s sickens you.",
+				prname(attname, FALSE));
+		    if (on(player, HASSTINK)) lengthen(unstink, STINKTIME);
+		    else {
+			turn_on(player, HASSTINK);
+			fuse(unstink, 0, STINKTIME, AFTER);
+		    }
+		}
+	    }
+
+	    /*
+	     * Chilling monster reduces strength each time.  This only
+	     * affects the player for now because of its temporary nature.
+	     */
+	    if (on(*att, CANCHILL)) {
+		if (!ISWEARING(R_SUSABILITY) && !save(VS_POISON, def, 0)) {
+		    msg("You cringe at %s's chilling touch.",
+				prname(attname, FALSE));
+		    chg_str(-1);
+		    if (lost_str++ == 0)
+			fuse(res_strength, 0, CHILLTIME, AFTER);
+		    else lengthen(res_strength, CHILLTIME);
+		}
+	    }
+
+	    /*
+	     * Itching monsters reduce dexterity (temporarily).  This only
+	     * affects the player for now because of its temporary nature.
+	     */
+	    if (on(*att, CANITCH) && !save(VS_POISON, def, 0)) {
+		msg("The claws of %s scratch you.", prname(attname, FALSE));
+		if (ISWEARING(R_SUSABILITY)) {
+		    msg("The scratch has no effect");
+		}
+		else {
+		    add_abil[A_DEXTERITY](-1);
+		}
+	    }
+
+
+	    /*
+	     * If a disease-carrying monster hits, there is a chance the
+	     * defender will catch the disease.  This only applies to the
+	     * player for now because of the temporary nature.
+	     */
+	    if (on(*att, CANDISEASE) &&
+		(rnd(def->t_stats.s_const) < att->t_stats.s_lvl) &&
+		off(*def, HASDISEASE)) {
+		    if (ISWEARING(R_HEALTH)		||
+			player.t_ctype == C_PALADIN	||
+			player.t_ctype == C_MONK) {
+			    msg("The wound heals quickly.");
+		    }
+		    else {
+			turn_on(*def, HASDISEASE);
+			fuse(cure_disease, 0, roll(HEALTIME,SICKTIME), AFTER);
+			msg(terse ? "You have been diseased."
+			    : "You have contracted a disease!");
+		    }
+	    }
+
+	    /*
+	     * If a rusting monster hits, you lose armor.  This only applies to
+	     * the player because monsters don't wear armor (for now).
+	     */
+	    if (on(*att, 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 < def->t_stats.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.  This
+	     * also only applies to the player for now because of the
+	     * armor.
+	     */
+	    if (on(*att, 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 < def->t_stats.s_arm+1) {
+		msg(terse ? "Your armor dissolves"
+		    : "Your armor appears to dissolve. Oh my!");
+		cur_armor->o_ac++;
+	    }
+
+	    /*
+	     * If an infesting monster hits you, you get a parasite or rot.
+	     * This will only affect the player until we figure out how to
+	     * make it affect monsters.
+	     */
+	    if (on(*att, CANINFEST) &&
+		rnd(def->t_stats.s_const) < att->t_stats.s_lvl) {
+		if (ISWEARING(R_HEALTH)		||
+		    player.t_ctype == C_PALADIN	||
+		    player.t_ctype == C_MONK) {
+			msg("The wound heals quickly.");
+		}
+		else {
+		    turn_off(*att, CANINFEST);
+		    msg(terse ? "You have been infested."
+			: "You have contracted a parasitic infestation!");
+		    infest_dam++;
+		    turn_on(*def, HASINFEST);
+		}
+	    }
+
+	    /*
+	     * Does it take wisdom away?  This currently affects only
+	     * the player because of its temporary nature.
+	     */
+	    if (on(*att, TAKEWISDOM)		&& 
+		!save(VS_MAGIC, def, 0)	&&
+		!ISWEARING(R_SUSABILITY)) {
+			add_abil[A_WISDOM](-1);
+	    }
+
+	    /*
+	     * Does it take intelligence away?  This currently affects
+	     * only the player because of its temporary nature.
+	     */
+	    if (on(*att, TAKEINTEL)		&& 
+		!save(VS_MAGIC, &player, 0)	&&
+		!ISWEARING(R_SUSABILITY)) {
+			add_abil[A_INTELLIGENCE](-1);
+	    }
+
+	    /*
+	     * Cause fear by touching.  This currently affects only
+	     * the player until we figure out how we want it to
+	     * affect monsters.
+	     */
+	    if (on(*att, TOUCHFEAR)) {
+		turn_off(*att, TOUCHFEAR);
+		if (!ISWEARING(R_HEROISM)	&&
+		    !save(VS_WAND, def, 0)	&&
+		    !(on(*def, ISFLEE) && (def->t_dest == &att->t_pos))) {
+			turn_on(*def, ISFLEE);
+			def->t_dest = &att->t_pos;
+			msg("%s's touch terrifies you.", prname(attname, TRUE));
+
+			/* It is okay to turn tail */
+			if (!def_player) def->t_oldpos = def->t_pos;
+		}
+	    }
+
+	    /*
+	     * Make the hero dance (as in otto's irresistable dance)
+	     * This should be fairly easy to do to monsters, but
+	     * we'll restrict it to players until we decide what to
+	     * do about the temporary nature.
+	     */
+	    if (on(*att, CANDANCE) 		&& 
+		!on(*def, ISDANCE)		&&
+		def->t_action != A_FREEZE	&&
+		!save(VS_MAGIC, def, -4)) {
+		    turn_off(*att, CANDANCE);
+		    turn_on(*def, ISDANCE);
+		    msg("You begin to dance uncontrollably!");
+		    fuse(undance, 0, roll(2,4), AFTER);
+	    }
+
+	    /*
+	     * Suffocating our hero.  Monsters don't get suffocated.
+	     * That's too hard for now.
+	     */
+	    if (on(*att, CANSUFFOCATE)		&& 
+		!ISWEARING(R_FREEDOM)		&& 
+		rnd(100) < 25			&&
+		(find_slot(suffocate) == 0)) {
+		turn_on(*att, DIDSUFFOCATE);
+		msg("%s is beginning to suffocate you.", prname(attname, TRUE));
+		fuse(suffocate, 0, roll(9,3), AFTER);
+	    }
+
+	    /*
+	     * some creatures stops the poor guy from moving.
+	     * How can we do this to a monster?
+	     */
+	    if (on(*att,CANHOLD) && off(*att,DIDHOLD) && !ISWEARING(R_FREEDOM)){
+		turn_on(*def, ISHELD);
+		turn_on(*att, DIDHOLD);
+		hold_count++;
+	    }
+
+	    /*
+	     * Sucker will suck blood and run.  This
+	     * should be easy to have happen to a monster,
+	     * but we have to decide how to handle the fleeing.
+	     */
+	    if (on(*att, CANDRAW)) {
+		turn_off(*att, CANDRAW);
+		turn_on(*att, ISFLEE);
+		msg("%s sates itself with your blood.", prname(attname, TRUE));
+		if ((def->t_stats.s_hpt -= 12) <= 0) return(att->t_index);
+
+		/* It is okay to turn tail */
+		att->t_oldpos = att->t_pos;
+	    }
+
+	    /*
+	     * Bad smell will force a reduction in strength.
+	     * This will happen only to the player because of
+	     * the temporary nature.
+	     */
+	    if (on(*att, CANSMELL)) {
+		turn_off(*att, CANSMELL);
+		if (save(VS_MAGIC, def, 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);
+		}
+	    }
+
+	    /*
+	     * The monsters touch slows the defendant down.
+	     */
+	     if (on(*att, TOUCHSLOW)) {
+		turn_off(*att, TOUCHSLOW);
+		if (!save(VS_PARALYZATION, def, 0)) 
+			add_slow();
+	    }
+
+	    /*
+	     * Rotting only affects the player.
+	     */
+	    if (on(*att, CANROT)) {
+		if (!ISWEARING(R_HEALTH)	&& 
+		    player.t_ctype != C_PALADIN	&&
+		    player.t_ctype != C_MONK	&&
+		    !save(VS_POISON, def, 0)    && 
+		    off(*def, DOROT)) {
+		    turn_on(*def, DOROT);
+		    msg("You feel your skin starting to rot away!");
+		}
+	    }
+
+	    /*
+	     * Monsters should be able to steal gold from anyone,
+	     * but until this is rewritten, they will only steal
+	     * from the player (tough break).
+	     */
+	    if (on(*att, 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, def, att->t_stats.s_lvl/10)) {
+		    if (on(*att, 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=att->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;
+			strncpy(obj->o_damage, "0d0", sizeof(obj->o_damage));
+			strncpy(obj->o_hurldmg, "0d0", sizeof(obj->o_hurldmg));
+			obj->o_ac = 11;
+			obj->contents = NULL;
+			obj->o_group = 0;
+			obj->o_flags = 0;
+			obj->o_mark[0] = '\0';
+			obj->o_pos = att->t_pos;
+
+			attach(att->t_pack, item);
+		    }
+		}
+
+		turn_on(*att, ISFLEE);
+		turn_on(*att, ISINVIS);
+
+		/* It is okay to turn tail */
+		att->t_oldpos = att->t_pos;
+	    }
+	}
+
+	/*
+	 * Stealing happens last since the monster disappears
+	 * after the act.
+	 */
+	if (on(*att, 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 = def->t_pack; list != NULL; list = next(list))
+	    {
+		obj = OBJPTR(list);
+		if (!is_current(obj)	 &&
+		    list != def->t_using &&
+		    obj->o_type != RELIC &&
+		    is_magic(obj)	 && 
+		    rnd(++nobj) == 0)
+			steal = list;
+	    }
+	    if (steal != NULL)
+	    {
+		register struct object *obj;
+		struct linked_list *item;
+
+		obj = OBJPTR(steal);
+		if (on(*att, ISUNIQUE))
+		    monsters[att->t_index].m_normal = TRUE;
+		item = find_mons(att->t_pos.y, att->t_pos.x);
+
+		killed(item, FALSE, FALSE, FALSE); /* Remove the attacker */
+
+		if (obj->o_count > 1 && obj->o_group == 0) {
+		    register int oc;
+
+		    oc = --(obj->o_count);
+		    obj->o_count = 1;
+		    if (def_player)
+			msg("%s stole %s!", prname(attname, TRUE),
+					inv_name(obj, TRUE));
+		    obj->o_count = oc;
+		}
+		else {
+		    if (def_player) {
+			msg("%s stole %s!", prname(attname, TRUE),
+					inv_name(obj, TRUE));
+
+			/* If this is a relic, clear its holding field */
+			if (obj->o_type == RELIC)
+			    cur_relic[obj->o_which] = 0;
+
+			inpack--;
+		    }
+
+		    detach(def->t_pack, steal);
+		    o_discard(steal);
+		}
+
+		updpack(FALSE, def);
+	    }
+	}
+    }
+
+    /* Didn't kill the defender */
+    return(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/encumb.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,207 @@
+/*
+ * encumb.c  -  Stuff to do with encumberence
+ *
+ * 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.
+ */
+
+/*
+ * Stuff to do with encumberence
+ *
+ */
+
+#include "curses.h"
+#include "rogue.h"
+
+/*
+ * updpack:
+ *	Update his pack weight and adjust fooduse accordingly
+ */
+updpack(getmax, tp)
+int getmax;
+struct thing *tp;
+{
+
+	reg int topcarry, curcarry;
+
+	if (getmax)
+	    tp->t_stats.s_carry = totalenc(tp);	/* get total encumb */
+	curcarry = packweight(tp);		/* get pack weight */
+
+	/* Only update food use for the player (for now) */
+	if (tp == &player) {
+	    topcarry = tp->t_stats.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 */
+	}
+	tp->t_stats.s_pack = curcarry;		/* update pack weight */
+}
+
+
+/*
+ * packweight:
+ *	Get the total weight of the hero's pack
+ */
+packweight(tp)
+register struct thing *tp;
+{
+	reg struct object *obj;
+	reg struct linked_list *pc;
+	reg int weight;
+
+	weight = 0;
+	for (pc = tp->t_pack ; pc != NULL ; pc = next(pc)) {
+	    obj = OBJPTR(pc);
+	    weight += itemweight(obj);
+	}
+	if (weight < 0)		/* in case of amulet */
+	     weight = 0;
+
+	/* If this is the player, is he wearing a ring of carrying? */
+	if (tp == &player && ISWEARING(R_CARRY)) {
+	    register int temp, i;
+
+	    temp = 0;
+	    for (i=0; i<NUM_FINGERS; i++) {
+		if (cur_ring[i]->o_which == R_CARRY) {
+		    if (cur_ring[i]->o_flags & ISCURSED) temp--;
+		    else temp++;
+		}
+	    }
+	    weight -= (temp * 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(tp)
+register struct thing *tp;
+{
+	register int strength;
+
+	if (tp == &player) strength = str_compute();
+	else strength = tp->t_stats.s_str;
+
+	return ((strength-8)*50);
+}
+
+
+/*
+ * totalenc:
+ *	Get total weight that the hero can carry
+ */
+totalenc(tp)
+register struct thing *tp;
+{
+	reg int wtotal;
+
+	wtotal = NORMENCB + playenc(tp);
+	if (tp == &player) switch(hungry_state) {
+		case F_SATIATED:
+		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 == 0) {
+		    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/arogue7/fight.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,1495 @@
+/*
+ * fight.c  -  All the fighting gets done here
+ *
+ * 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.
+ */
+
+/*
+ * All the fighting gets done here
+ *
+ */
+
+#include "curses.h"
+#include <ctype.h>
+#include "rogue.h"
+
+int hit(struct object *weapon, bool see_att, bool see_def, char *er, char *ee, bool back_stab, bool thrown, bool short_msg);
+#define CONF_DAMAGE	-1
+#define PARAL_DAMAGE	-2
+#define DEST_DAMAGE	-3
+#define DRAIN_DAMAGE	-4
+
+/*
+ * returns true if player has a any chance to hit the monster
+ */
+player_can_hit(tp, weap)
+register struct thing *tp;
+register struct object *weap;
+{
+    if (off(*tp, CMAGICHIT) && off(*tp, BMAGICHIT) && off(*tp, MAGICHIT))
+	return(TRUE);
+    if (weap && weap->o_type == RELIC)
+	return(TRUE);
+    if (on(*tp, CMAGICHIT) && weap && (weap->o_hplus>2 || weap->o_dplus>2))
+	return(TRUE);
+    if (on(*tp, BMAGICHIT) && weap && (weap->o_hplus>1 || weap->o_dplus>1))
+	return(TRUE);
+    if (on(*tp,  MAGICHIT) && weap && (weap->o_hplus>0 || weap->o_dplus>0))
+	return(TRUE);
+    if (player.t_ctype == C_MONK) {
+	if (on(*tp, CMAGICHIT) && pstats.s_lvl > 15)
+	    return(TRUE);
+	if (on(*tp, BMAGICHIT) && pstats.s_lvl > 10)
+	    return(TRUE);
+	if (on(*tp,  MAGICHIT) && pstats.s_lvl > 5)
+	    return(TRUE);
+    }
+    return(FALSE);
+}
+
+/*
+ * 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 see_def, back_stab = FALSE;
+    register char *mname;
+
+    /*
+     * 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.  The -1 also tells us that we are in a fight.
+     */
+    player.t_quiet = -1;
+    tp->t_quiet = -1;
+
+    see_def = ((off(*tp, ISINVIS)     || on(player, CANSEE)) &&
+	       (off(*tp, ISSHADOW)    || on(player, CANSEE)) &&
+	       (!thrown || cansee(unc(tp->t_pos))));
+
+    mname = see_def ? monster_name(tp) : "something";
+
+    /*
+     * if its in the wall, we can't hit it
+     */
+    if (on(*tp, ISINWALL) && off(player, CANINWALL))
+	return(FALSE);
+
+    if (on(*tp, ISSTONE)) {
+	killed(item, FALSE, FALSE, FALSE);
+	if (see_def) 
+	    msg("%s shatters into a million pieces!", prname(mname, TRUE));
+	count = 0;
+	return (TRUE);
+    }
+    /*
+     * 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))
+    {
+	if (see_def) {
+	    msg("Wait! That's a %s!", mname);
+	    turn_off(*tp, ISDISGUISE);
+	}
+	did_hit = thrown;
+    }
+    if (on(*tp, CANSURPRISE) && off(player, ISBLIND) && !ISWEARING(R_ALERT)) {
+	if (see_def) {
+	    msg("Wait! There's a %s!", mname);
+	    turn_off(*tp, CANSURPRISE);
+	}
+	did_hit = thrown;
+    }
+
+    /*
+     * if he's a thief or assassin and the creature is asleep then he gets 
+     * a chance for a backstab
+     */
+    if ((player.t_ctype == C_THIEF || player.t_ctype == C_ASSASIN)	&&
+	!thrown								&&
+	!on(*tp, NOSTAB)						&&
+	!invisible(tp)							&&
+	(!on(*tp, ISRUN) || on(*tp, ISHELD) || tp->t_action == A_FREEZE))
+	    back_stab = TRUE;
+
+    /*
+     * assassins get an assassination chance, if it fails then its normal
+     * damage
+     */
+    if (back_stab && player.t_ctype == C_ASSASIN) {
+	int chance;
+
+	chance = 50 + (pstats.s_lvl - tp->t_stats.s_lvl) * 5;
+	if (cur_weapon && (cur_weapon->o_flags & ISPOISON))
+	    chance += 20;
+	if (roll(1,100) > chance || on(*tp, ISUNIQUE))
+	    back_stab = FALSE;
+    }
+
+    runto(tp, &hero);
+
+    /* Let the monster know that the player has missiles! */
+    if (thrown) tp->t_wasshot = TRUE;
+
+    if (did_hit)
+    {
+
+	did_hit = FALSE;
+	if (!can_blink(tp)		&& 
+	    player_can_hit(tp, weap)	&&
+	    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) {
+		msg("Your %s passes right through %s!",
+		    weaps[weap->o_which].w_name, prname(mname, FALSE));
+	    }
+	    else if (weap != NULL && weap->o_type == MISSILE && on(*tp, CARRYBAMULET)) {
+		    msg("The magic missile has no affect on %s",
+			prname(mname, FALSE));
+	    }
+	    else {
+		hit(thrown ? NULL : weap,
+		    TRUE, see_def,
+		    thrown ? weap_name(weap) : NULL,
+		    mname, back_stab, thrown, terse);
+
+	        /* See if there are any special effects */
+	        if (effect(&player, tp, weap, thrown, TRUE, see_def) != 0)
+		    killed(item, FALSE, FALSE, TRUE);
+    
+	        /* 
+	         * Merchants just disappear if hit 
+	         */
+	        else if (on(*tp, CANSELL)) {
+		    if (see_def)
+		        msg("%s disappears with his wares in a flash.",
+			    prname(mname, FALSE));
+		    killed(item, FALSE, FALSE, FALSE);
+	        }
+    
+	        else if (tp->t_stats.s_hpt <= 0)
+		    killed(item, TRUE, TRUE, TRUE);
+    
+	        else {
+		    /* If the victim was charmed, it now gets a saving throw! */
+		    if (on(*tp, ISCHARMED) && save(VS_MAGIC, tp, 0)) {
+			msg("The eyes of %s turn clear.", prname(mname, FALSE));
+			turn_off(*tp, ISCHARMED);
+		    }
+
+		    dsrpt_monster(tp, FALSE, see_def); /* Disrupt a spell? */
+	        }
+	    }
+	}
+	else {
+	    miss(thrown ? NULL : weap,
+		 TRUE, see_def,
+		 thrown ? weap_name(weap) : NULL,
+		 mname, thrown, terse);
+	}
+    }
+    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 char *mname;
+    register bool see_att, did_hit = FALSE;
+    register struct object *wielded;	/* The wielded weapon */
+    struct linked_list *get_wield;	/* Linked list header for wielded */
+
+    /*
+     * Since this is an attack, stop running and any healing that was
+     * going on at the time.  The -1 also tells us that we're fighting.
+     */
+    running = FALSE;
+    player.t_quiet = -1;
+    mp->t_quiet = -1;
+
+    if (on(*mp, ISDISGUISE) && off(player, ISBLIND))
+	turn_off(*mp, ISDISGUISE);
+
+    see_att = ((off(*mp, ISINVIS)     || on(player, CANSEE)) &&
+	       (off(*mp, ISSHADOW)    || on(player, CANSEE)) &&
+	       (!thrown || cansee(unc(mp->t_pos))));
+
+    mname = see_att ? monster_name(mp) : "something";
+
+    /*
+     * 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.
+     */
+    get_wield = wield_weap(weapon, mp);
+    if (get_wield) wielded = OBJPTR(get_wield);
+    else wielded = NULL;
+
+    /* If we aren't wielding a weapon, wield what we found (could be NULL) */
+    if (weapon == NULL) weapon = wielded;
+
+    if (roll_em(mp, &player, weapon, thrown, wielded, FALSE)) {
+	int death_type;	/* From one of the effects of getting hit */
+
+	did_hit = TRUE;
+
+	if (weapon != NULL && weapon->o_type == MISSILE && cur_relic[STONEBONES_AMULET]) {
+	    hit(weapon, see_att, TRUE, mname, NULL, FALSE, thrown, terse);
+	    msg("Your amulet seems to absorb the magic missile");
+	}
+	else {
+	    hit(weapon, see_att, TRUE, mname, NULL, FALSE, thrown, terse);
+	    dsrpt_player();	/* see if we disrupted some activity */
+	    if (pstats.s_hpt <= 0)
+		death(mp->t_index);	/* Bye bye life ... */
+	    death_type = effect(mp, &player, weapon, thrown, see_att, TRUE);
+	    if (death_type != 0) death(death_type);
+	}
+
+    }
+    else {
+	/* If the thing was trying to surprise, no good */
+	if (on(*mp, CANSURPRISE)) turn_off(*mp, CANSURPRISE);
+
+	/* If it couldn't surprise, let's tell the player. */
+	else miss(weapon, see_att, TRUE, mname, NULL, thrown, terse);
+    }
+    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 = char_class[class].base -
+	   char_class[class].factor *
+	   ((min(at_lvl, char_class[class].max_lvl) -
+	    char_class[class].offset)/char_class[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;
+    register int ndice, nsides, nplus, def_arm;
+    bool did_hit = FALSE;
+    int prop_hplus, prop_dplus;
+    int vampiric_damage;
+    char *strchr();
+
+    /* Get statistics */
+    att = &att_er->t_stats;
+    def = &def_er->t_stats;
+
+    prop_hplus = prop_dplus = 0;
+    if (weap == NULL) {
+	static char dmgbuf[20];
+
+	/*
+	 * monks damage grows with level
+	 */
+	if (att == &pstats && player.t_ctype == C_MONK) {
+	    sprintf(dmgbuf, "%dd4", att->s_lvl/3+1);
+	    cp = dmgbuf;
+	}
+	else
+	    cp = att->s_dmg;
+    }
+    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";
+	    when AXE_AKLAD:		if (hurl) cp = "1d6/drain";
+				        else	  cp = "3d6/drain";
+	}
+    }
+    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 {
+	cp = weap->o_damage;
+	/*
+	 * Drain a staff of striking
+	 */
+	if(weap->o_type==STICK && weap->o_which==WS_HIT && weap->o_charges==0)
+	{
+	    strncpy(weap->o_damage, "1d6", sizeof(weap->o_damage));
+	    weap->o_hplus = weap->o_dplus = 0;
+	}
+    }
+    /*
+     * If defender is wearing a cloak of displacement -- no damage
+     * the first time. (unless its a hurled magic missile or the
+     * attacker is very smart and can see thru the illusion)
+     */
+    if ((weap == NULL || weap->o_type != MISSILE)	&&
+	def == &pstats					&&	
+	off(*att_er, MISSEDDISP)			&&
+	att->s_intel < 22				&&
+	((cur_misc[WEAR_CLOAK]!=NULL && 
+	  cur_misc[WEAR_CLOAK]->o_which==MM_DISP) ||
+	  cur_relic[EMORI_CLOAK])) {
+	turn_on(*att_er, MISSEDDISP);
+	if (cansee(att_er->t_pos.y, att_er->t_pos.x) && !invisible(att_er))
+	    msg("%s looks amazed", prname(monster_name(att_er), TRUE));
+	return (FALSE);
+    }
+    if (on(*def_er, CARRYCLOAK)	&& def != &pstats		&& 
+        (weap == NULL || weap->o_type != MISSILE) && off(*att_er, MISSEDDISP) &&
+	pstats.s_intel < 22) {
+	turn_on(*att_er, MISSEDDISP);
+	msg("You feel amazed");
+	return(FALSE);
+    }
+    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;
+		when AXE_AKLAD:
+		    hplus += 5;
+		    dplus += 5;
+	    }
+	}
+	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 if (strncmp(cp, "drain", 5) == 0) ndice = DRAIN_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 */
+	    if (on(*att_er, NOMETAL))
+		def_arm = ac_compute(TRUE) - dext_prot(dex_compute());
+	    else
+		def_arm = ac_compute(FALSE) - dext_prot(dex_compute());
+	    hplus += str_plus(att->s_str)+dext_plus(att->s_dext);
+	}
+	else if (att == &pstats) {	/* Player attacks monster */
+	    def_arm = def->s_arm - dext_prot(def->s_dext);
+	    if (player.t_ctype == C_MONK) /* no strength bonus for monk */
+	        if (weap == NULL) 
+		    hplus += att->s_lvl/5; /* monks hplus varies with level */
+	    else
+		hplus += str_plus(str_compute())+dext_plus(dex_compute());
+	}
+	else {	/* Monster attacks monster */
+	    def_arm = def->s_arm - dext_prot(def->s_dext);
+	    hplus += str_plus(att->s_str)+dext_plus(att->s_dext);
+	}
+
+	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, HUHDURATION);
+			else
+			    fuse(unconfuse, 0, HUHDURATION, AFTER);
+			turn_on(player, ISHUH);
+		    }
+		    else msg("You feel dizzy, but it quickly passes.");
+		}
+		/* Player or monster hits monster */
+		else if (!save(VS_MAGIC, def_er, 0) && off(*def_er, ISCLEAR)) { 
+		    if (att == &pstats)
+			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.");
+			player.t_no_move += movement(&player) * FREEZETIME;
+			player.t_action = A_FREEZE;
+		    }
+		}
+		else if (!save(VS_MAGIC, def_er, 0)) { /* Player hits monster */
+		    if (att == &pstats) 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)) {
+		    if (att == &pstats)
+			msg("The artifact draws energy.");
+
+		    /* Give the attacker 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;
+	    when DRAIN_DAMAGE:
+		if (def == &pstats) { /* Monster attacks player */
+		    if (!save(VS_MAGIC, &player, -4)) {
+			lower_level(att_er->t_index);
+		    }
+		}
+		/* Player hits monster */
+		else if (!save(VS_MAGIC, def_er, -4)) {
+		    def->s_hpt -= roll(1, 8);
+		    def->s_lvl--;
+		    if (def->s_lvl <= 0)
+			def->s_hpt = 0; /* he's dead */
+		    if (att == &pstats) 
+			msg("The artifact cackles with laughter");
+		}
+		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 (att == &pstats) {
+		    /*
+		     * Monks do not get strength bonus on damage.  Instead,
+		     * if they are wielding a weapon, they get at extra
+		     * 1/2 point per level of damage.
+		     */
+		    if(player.t_ctype == C_MONK) {
+			/* Bonus does not apply for hands. */
+			if (weap != NULL) damage += att->s_lvl / 2;
+		    }
+		    else
+			damage += add_dam(str_compute());
+		}
+		else
+		    damage += add_dam(att->s_str);
+
+		/* 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)
+			mult = 5;
+		    if (weap->o_type == RELIC && weap->o_which == MUSTY_DAGGER)
+			mult++;
+		    damage *= mult;
+		}
+		if (att == &pstats) {
+		    if (cur_weapon && (cur_weapon->o_flags & ISPOISON)) {
+			cur_weapon->o_flags &= ~ISPOISON;
+			if (save(VS_POISON, def_er, -2))
+			    damage += def->s_hpt/4;
+			else
+			    damage += def->s_hpt/2;
+		    }
+		    if (back_stab && player.t_ctype == C_ASSASIN)
+		        damage = def->s_hpt + 1;
+		}
+		/* Check for no-damage and division */
+		if (on(*def_er, BLOWDIVIDE)) {
+		    damage = 0;
+		    creat_mons(def_er, def_er->t_index, FALSE);
+		    if (cansee(unc(def_er->t_pos))) 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 (weap != NULL && weap->o_type == MISSILE) {
+		    if ((def == &pstats && cur_relic[STONEBONES_AMULET]) ||
+		        (att == &pstats && on(*def_er, CARRYBAMULET))) {
+			damage = 0;
+		    }
+		}
+
+
+		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) || strcmp(who, "something") == 0)
+	strcpy(tbuf, "something");
+    else
+    {
+	/* If we have a name (starts with a capital), don't use a "the" */
+	if (islower(*who)) strcpy(tbuf, "the ");
+	strcat(tbuf, who);
+    }
+    if (upper)
+	*tbuf = toupper(*tbuf);
+    return tbuf;
+}
+
+/*
+ * hit:
+ *	Print a message to indicate a succesful hit
+ */
+
+hit(weapon, see_att, see_def, er, ee, back_stab, thrown, short_msg)
+register struct object *weapon;
+bool see_att, see_def;
+register char *er, *ee;
+bool back_stab, thrown, short_msg;
+{
+    register char *s;
+    char          att_name[LINELEN],	/* Name of attacker */
+		  def_name[LINELEN]; /* Name of defender */
+
+    /* If we can't see either the attacker or defender, don't say anything */
+    if (!see_att && !see_def) return;
+
+    /* What do we call the attacker? */
+    strcpy(att_name, see_att ? prname(er, TRUE) : "Something");
+    if (er) {	/* A monster is attacking */
+
+	/* If the monster is using a weapon and we can see it, report it */
+	if (weapon != NULL && (see_att || thrown)) {
+	    strcat(att_name, "'s ");
+	    strcat(att_name, weap_name(weapon));
+	}
+    }
+
+    /* What do we call the defender? */
+    strcpy(def_name, see_def ? prname(ee, FALSE) : "something");
+
+    addmsg(att_name);
+    if (short_msg) {
+	if (back_stab) {
+	    if (player.t_ctype == C_ASSASIN)
+	        s = (er == 0 ? " assassinate!" : " assassinates!");
+	    else
+	        s = (er == 0 ? " backstab!" : " backstabs!");
+	}
+	else
+	    s = " hit.";
+    }
+    else {
+	if (back_stab) {
+	    if (player.t_ctype == C_ASSASIN)
+	        s = (er == 0 ? " have assassinated " : " has assassinated ");
+	    else
+	        s = (er == 0 ? " have backstabbed " : " has backstabbed ");
+	}
+	else {
+	    switch (rnd(thrown ? 2 : 3))
+	    {
+		case 0: s = " hit ";
+		when 1: s = " injured ";
+		when 2: s = " smacked ";
+	    }
+	}
+    }
+    if (short_msg) addmsg(s);
+    else addmsg("%s%s.", s, def_name);
+    endmsg();
+}
+
+/*
+ * miss:
+ *	Print a message to indicate a poor swing
+ */
+
+miss(weapon, see_att, see_def, er, ee, thrown, short_msg)
+register struct object *weapon;
+bool see_att, see_def;
+register char *er, *ee;
+bool thrown, short_msg;
+{
+    register char *s;
+    char
+    	          att_name[LINELEN],	/* Name of attacker */
+		  def_name[LINELEN]; /* Name of defender */
+
+    /* If we can't see either the attacker or defender, don't say anything */
+    if (!see_att && !see_def) return;
+
+    /* What do we call the attacker? */
+    strcpy(att_name, see_att ? prname(er, TRUE) : "Something");
+    if (er) {	/* A monster is attacking */
+
+	/* If the monster is using a weapon and we can see it, report it */
+	if (weapon != NULL && (see_att || thrown)) {
+	    strcat(att_name, "'s ");
+	    strcat(att_name, weap_name(weapon));
+	}
+    }
+
+    /* What do we call the defender? */
+    strcpy(def_name, see_def ? prname(ee, FALSE) : "something");
+
+    addmsg(att_name);
+    switch (short_msg ? 0 : rnd(thrown ? 3 : 2))
+    {
+	case 0: s = (er == 0 ? " miss" : " misses");
+	when 1: s = (er == 0 ? " don't hit" : " doesn't hit");
+	when 2: s = (" whizzes by");
+    }
+    if (short_msg) addmsg("%s.", s);
+    else addmsg("%s %s.", 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;
+
+	switch(hungry_state) {
+		case F_SATIATED:
+		case F_OKAY:
+		case F_HUNGRY:	howmuch = 0;
+		when F_WEAK:	howmuch = -1;
+		when F_FAINT:	howmuch = -2;
+	}
+	return howmuch;
+}
+
+#ifdef THUNK
+/*
+ * 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)
+	msg("The %s hits %s.", weaps[weap->o_which].w_name, def_name);
+    else if (weap->o_type == MISSILE)
+	msg("The %s hits %s.",ws_magic[weap->o_which].mi_name, def_name);
+    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)
+	msg("%s's %s hits you.", att_name, weaps[weap->o_which].w_name);
+    else if (weap->o_type == MISSILE)
+	msg("%s's %s hits you.", att_name, ws_magic[weap->o_which].mi_name);
+    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)
+	msg("The %s misses %s.",weaps[weap->o_which].w_name, def_name);
+    else if (weap->o_type == MISSILE)
+	msg("The %s misses %s.",ws_magic[weap->o_which].mi_name, def_name);
+    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)
+	msg("%s's %s misses you.", att_name, weaps[weap->o_which].w_name);
+    else if (weap->o_type == MISSILE)
+	msg("%s's %s misses you.", att_name, ws_magic[weap->o_which].mi_name);
+    else
+	msg("%s misses you.", att_name);
+}
+#endif
+
+
+/*
+ * 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
+ */
+
+int chance = 0;/* cumulative chance for goodies to loose it */
+
+killed(item, pr, points, treasure)
+register struct linked_list *item;
+bool pr, points, treasure;
+{
+    register struct thing *tp, *mp;
+    register struct linked_list *pitem, *nexti, *mitem;
+    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 = monster_name(tp);
+	    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);
+
+    /* Make sure that no one is still chasing us */
+    for (mitem = mlist; mitem != NULL; mitem = next(mitem)) {
+	mp = THINGPTR(mitem);
+	if (mp->t_dest == &tp->t_pos) {
+	    mp->t_dest = &hero;
+	    mp->t_wasshot = FALSE;
+	    turn_off(*mp, ISFLEE);	/* Be sure we aren't running away! */
+	}
+    }
+
+    if (points) {
+	if ((off(*tp, ISMEAN) || on(*tp, ISFRIENDLY)) &&
+	    (player.t_ctype == C_RANGER || player.t_ctype == C_PALADIN)) {
+		if (tp->t_stats.s_exp > pstats.s_exp)
+			pstats.s_exp = 0;
+		else
+			pstats.s_exp -= tp->t_stats.s_exp;
+		if (roll(1,100) < chance++)
+			changeclass(C_FIGHTER);
+		else
+			msg("You feel uneasy for a moment");
+	}
+	else {
+		unsigned long test;	/* For overflow check */
+		/* 
+		 * Do an overflow check before increasing experience 
+		 */
+		test = pstats.s_exp + tp->t_stats.s_exp;
+		if (test > pstats.s_exp) 
+			pstats.s_exp = test;
+	}
+
+	/*
+	 * Do adjustments if he went up a level
+	 */
+	check_level();
+    }
+
+    /*
+     * 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);
+    if (on(*tp, AREMANY) && levtype == NORMLEV) /* AREMANYs stick together */
+	wake_room(roomin(&tp->t_pos));
+    /*
+     * empty his pack
+     */
+    while (pitem != NULL)
+    {
+	nexti = next(tp->t_pack);
+	(OBJPTR(pitem))->o_pos = tp->t_pos;
+	detach(tp->t_pack, pitem);
+	if (treasure) 
+	    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 linked_list *
+wield_weap(thrown, mp)
+struct object *thrown;
+struct thing *mp;
+{
+    int look_for,	/* 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, *candidate = NULL;
+    register struct object *obj;
+
+    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(pitem);
+
+	/* 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 AXE_AKLAD:
+		case MING_STAFF:
+		case ASMO_ROD:
+		case ORCUS_WAND:
+		    return(pitem);
+	    }
+	}
+
+	/* 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:
+		case SPEAR:
+		    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 = pitem;
+	    }
+	}
+    }
+
+    return(candidate);
+}
+explode(tp)
+register struct thing *tp;
+{
+
+    register int x,y, damage;
+    struct linked_list *item;
+    struct thing *th;
+
+    /*
+     * check to see if it got the hero
+     */
+     if (off(player, ISINWALL) &&
+	 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;
+	pstats.s_hpt -= damage;
+    }
+
+    /*
+     * 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 */
+			on(*th, ISINWALL)) /* Don't count monsters in wall */
+			continue;
+		    damage = roll(6, 6);
+		    if (save(VS_WAND, th, 0))
+			damage /= 2;
+		    runto(th, &hero);
+		    if ((th->t_stats.s_hpt -= damage) <= 0) {
+			msg("The explosion kills %s", 
+			    prname(monster_name(th), FALSE));
+			killed(item, FALSE, FALSE, TRUE);
+		    }
+		}
+	    }
+	}
+    }
+}
+
+/*
+ * skirmish:
+ *	Called when one monster attacks another monster.
+ */
+
+skirmish(attacker, mp, weap, thrown)
+register struct thing *attacker;
+register coord *mp;
+struct object *weap;
+bool thrown;
+{
+    register struct thing *defender;
+    register struct linked_list *item;
+    register bool did_hit = TRUE, see_att, see_def;
+    char attname[LINELEN+1], defname[LINELEN+1];
+    struct object *wielded;	/* The wielded weapon */
+    struct linked_list *get_wield;	/* Linked list header for wielded */
+
+    /*
+     * Find the monster we want to fight
+     */
+    if ((item = find_mons(mp->y, mp->x)) == NULL) {
+	return(FALSE); /* must have killed him already */
+    }
+    defender = THINGPTR(item);
+
+    /* Can the player see either of the fighters? */
+    see_att = (cansee(unc(attacker->t_pos)) &&
+	       (off(*attacker, ISINVIS)     || on(player, CANSEE)) &&
+	       (off(*attacker, ISSHADOW)    || on(player, CANSEE)));
+    see_def = (cansee(unc(defender->t_pos)) &&
+	       (off(*defender, ISINVIS)     || on(player, CANSEE)) &&
+	       (off(*defender, ISSHADOW)    || on(player, CANSEE)));
+
+    /*
+     * Since we are fighting, things are not quiet so no healing takes
+     * place.  The -1 also tells us that we are in a fight.
+     */
+    attacker->t_quiet = -1;
+    defender->t_quiet = -1;
+
+    if (see_att) strcpy(attname, monster_name(attacker));
+    else strcpy(attname, "something");
+
+    if (see_def) strcpy(defname, monster_name(defender));
+    else strcpy(defname, "something");
+
+    /*
+     * if its in the wall, we can't hit it
+     */
+    if (on(*defender, ISINWALL) && off(*attacker, CANINWALL))
+	return(FALSE);
+
+    if (on(*defender, ISSTONE)) {
+	killed(item, FALSE, FALSE, FALSE);
+	if (see_def)
+	    msg("%s shatters into a million pieces!", prname(defname, TRUE));
+	return (TRUE);
+    }
+
+    /*
+     * Let him know it was really a mimic (if it was one).
+     */
+    if (see_def && on(*defender, ISDISGUISE) &&
+	(defender->t_type != defender->t_disguise)) {
+	msg("Wait! There's a %s!", defname);
+	turn_off(*defender, ISDISGUISE);
+	did_hit = thrown;
+    }
+
+    if (see_def && on(*defender, CANSURPRISE) && !ISWEARING(R_ALERT)) {
+	msg("Wait! There's a %s!", defname);
+	turn_off(*defender, CANSURPRISE);
+	did_hit = thrown;
+    }
+
+    if (did_hit) {
+
+	did_hit = FALSE;
+
+	/*
+	 * 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.
+	 */
+	get_wield = wield_weap(weap, attacker);
+	if (get_wield) wielded = OBJPTR(get_wield);
+	else wielded = NULL;
+
+#ifdef DOBLINK
+	/*
+	 * For now Blink Dogs will not blink away from monsters.  We
+	 * have to fix can_blink so it isn't dependant on the player
+	 * before we can add it.
+	 */
+	if (!can_blink(defender) &&
+#endif
+	if (((weap && weap->o_type == RELIC) ||
+	     ((off(*defender, MAGICHIT) ||
+	       attacker->t_stats.s_lvl > 4 ||
+	       (weap && (weap->o_hplus > 0 || weap->o_dplus > 0))) &&
+	      (off(*defender, BMAGICHIT) ||
+	       attacker->t_stats.s_lvl > 6 ||
+	       (weap && (weap->o_hplus > 1 || weap->o_dplus > 1))) &&
+	      (off(*defender, CMAGICHIT) ||
+	       attacker->t_stats.s_lvl > 8 ||
+	       (weap && (weap->o_hplus > 2 || weap->o_dplus > 2)))))
+	    && roll_em(attacker, defender, weap, thrown, wielded, FALSE))
+	{
+	    did_hit = TRUE;
+
+	    /* Should we start to chase this creature? */
+	    if (attacker->t_index != defender->t_index	&&
+		(off(*defender, ISRUN) || rnd(100) < 50)) {
+		/*
+		 * If we're intelligent enough to realize that this
+		 * is a friendly monster, we will attack the hero instead.
+		 */
+		if (on(*attacker, ISFRIENDLY) &&
+		    roll(3,6) < defender->t_stats.s_intel) {
+		    runto(defender, &hero);
+		    debug("%s attacking %s's hero", defname, attname);
+		}
+
+		/* Otherwise, let's chase the monster */
+		else {
+		    runto(defender, &attacker->t_pos);
+		    debug("%s now attacking %s", defname, attname);
+		}
+	    }
+	    else if (off(*defender, ISRUN)) runto(defender, &hero);
+
+	    /* Let the defender know that the attacker has missiles! */
+	    if ((defender->t_dest == &attacker->t_pos) && thrown)
+		defender->t_wasshot = TRUE;
+
+	    if (on(*defender, NOMETAL) && weap != NULL &&
+		weap->o_type != RELIC && weap->o_flags & ISMETAL) {
+		if (see_def && see_att)
+		    msg("The %s passes right through %s!",
+			weaps[weap->o_which].w_name, prname(defname, FALSE));
+	    }
+	    else {
+		hit(weap, see_att, see_def,
+		    attname, defname, FALSE, thrown, FALSE);
+	    }
+
+	    /* See if there are any special effects */
+	    if (effect(attacker, defender,
+		       weap, thrown, see_att, see_def) != 0) {
+		killed(item, FALSE, FALSE, TRUE);
+		if (see_def) msg("%s dies.", prname(defname, TRUE));
+		else msg("You hear a blood-curdling scream.");
+	    }
+
+	    /* 
+	     * Merchants just disappear if hit 
+	     */
+	    else if (on(*defender, CANSELL)) {
+		if (see_def)
+		    msg("%s disappears with his wares in a flash.",
+			    prname(defname, TRUE));
+		killed(item, FALSE, FALSE, FALSE);
+	    }
+
+	    else if (defender->t_stats.s_hpt <= 0) {
+		killed(item, FALSE, FALSE, TRUE);
+		if (see_def) msg("%s dies.", prname(defname, TRUE));
+		else msg("You hear a blood-curdling scream.");
+	    }
+
+	    else {
+		/* Did we disrupt a spell?				*/
+		/* Don't turn on WASDISRUPTED since player didn't do it */
+		if (defender->t_action == A_SUMMON ||
+		    defender->t_action == A_MISSILE) {
+		    /* Just make the old fellow start over again */
+		    defender->t_action = A_NIL;
+		    defender->t_no_move = movement(defender);
+		    defender->t_using = NULL;
+
+		    if (see_def)
+			msg("%s was disrupted.", prname(defname, TRUE));
+		}
+
+#ifdef FLEEMONST
+		/*
+		 * If the monster is fairly intelligent and about to die, it
+		 * may turn tail and run.  WE STILL NEED TO FIGURE OUT HOW
+		 * WE WANT THIS TO WORK.
+		 */
+		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);
+
+		    /* It is okay to turn tail */
+		    tp->t_oldpos = tp->t_pos;
+		}
+#endif
+	    }
+	}
+	else {
+	    /* If the thing was trying to surprise, no good */
+	    if (on(*attacker, CANSURPRISE)) {
+		/* If we can't see it, it keeps surprise (from us) */
+	        if (see_att) turn_off(*attacker, CANSURPRISE);
+	    }
+
+	    miss(weap, see_att, see_def, attname, defname, thrown, FALSE);
+	}
+    }
+    return did_hit;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/init.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,624 @@
+/*
+ * init.c  -  global variable initializaton
+ *
+ * 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.
+ */
+
+/*
+ * global variable initializaton
+ *
+ */
+
+#include "curses.h"
+#include <ctype.h>
+#include "rogue.h"
+#include "mach_dep.h"
+
+
+/*
+ * If there is any news, put it in a character string and assign it to
+ * rogue_news.  Otherwise, assign NULL to rogue_news.
+ */
+static char *rogue_news = "You no longer fall into trading posts. They are \
+now entered like going down the stairs.";
+
+char *rainbow[] = {
+
+"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",
+};
+#define NCOLORS (sizeof rainbow / sizeof(char *))
+int cNCOLORS = NCOLORS;
+
+static char *sylls[] = {
+    "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", "net", "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[] = {
+	"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",
+};
+#define NSTONES (sizeof stones / sizeof(char *))
+int cNSTONES = NSTONES;
+
+char *wood[] = {
+	"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",
+};
+#define NWOOD (sizeof wood / sizeof(char *))
+int cNWOOD = NWOOD;
+
+char *metal[] = {
+	"aluminium",	"bone",		"brass",	"bronze",
+	"copper",	"chromium",	"iron",		"lead",
+	"magnesium",	"pewter",	"platinum",	"silver",
+	"steel",	"tin",		"titanium",	"zinc",
+};
+#define NMETAL (sizeof metal / sizeof(char *))
+int cNMETAL = NMETAL;
+#define MAX3(a,b,c)     (a > b ? (a > c ? a : c) : (b > c ? b : c))
+
+static bool used[MAX3(NCOLORS, NSTONES, NWOOD)];
+
+
+/*
+ * 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;
+
+    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);
+}
+
+/*
+ * do any initialization for food
+ */
+
+init_foods()
+{
+    register int i;
+
+    for (i=0; i < MAXFOODS; i++) {
+	if (i > 0)
+	    foods[i].mi_prob += foods[i-1].mi_prob;
+    }
+    badcheck("foods", foods, MAXFOODS);
+}
+
+/*
+ * init_materials:
+ *	Initialize the construction materials for wands and staffs
+ */
+
+init_materials()
+{
+    register int i, j;
+    register char *str;
+    static bool metused[NMETAL];
+
+    for (i = 0; i < NWOOD; i++)
+	used[i] = FALSE;
+    for (i = 0; i < NMETAL; i++)
+	metused[i] = FALSE;
+
+    for (i = 0 ; i < MAXSTICKS ; i++)
+    {
+	for (;;)
+	    if (rnd(100) > 50)
+	    {
+		j = rnd(NMETAL);
+		if (!metused[j])
+		{
+		    ws_type[i] = "wand";
+		    str = metal[j];
+		    metused[j] = TRUE;
+		    break;
+		}
+	    }
+	    else
+	    {
+		j = rnd(NWOOD);
+		if (!used[j])
+		{
+		    ws_type[i] = "staff";
+		    str = wood[j];
+		    used[j] = TRUE;
+		    break;
+		}
+	    }
+
+	ws_made[i] = str;
+	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, round, minimum, maximum, ch, i, j;
+    short do_escape, *our_stats[NUMABILITIES-1];
+    struct linked_list	*weap_item, *armor_item;
+    struct object *obj;
+
+    weap_item = armor_item = NULL;
+
+    if (char_type == -1) {
+	/* See what type character will be */
+	wclear(hw);
+	touchwin(hw);
+	wmove(hw,2,0);
+	for(i=1; i<=NUM_CHARTYPES-1; i++) {
+	    wprintw(hw,"[%d] %s\n",i,char_class[i-1].name);
+	}
+	mvwaddstr(hw, 0, 0, "What character class do you desire? ");
+	draw(hw);
+	char_type = (wgetch(hw) - '0');
+	while (char_type < 1 || char_type > NUM_CHARTYPES-1) {
+	    wmove(hw,0,0);
+	    wprintw(hw,"Please enter a character type between 1 and %d: ",
+		    NUM_CHARTYPES-1);
+	    draw(hw);
+	    char_type = (wgetch(hw) - '0');
+	}
+	char_type--;
+    }
+    player.t_ctype = char_type;
+    player.t_quiet = 0;
+    pack = NULL;
+
+    /* Select the gold */
+    purse = 2700;
+    switch (player.t_ctype) {
+	case C_FIGHTER:
+	    purse += 1800;
+	when C_THIEF:
+	case C_ASSASIN:
+	    purse += 600;
+    }
+#ifdef WIZARD
+    /* 
+     * allow me to describe a super character 
+     */
+    if (wizard && 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 = 10000000L;
+	    pstats.s_lvladj = 0;
+	    pstats.s_lvl = 1;
+	    pstats.s_hpt = 500;
+	    pstats.s_carry = totalenc(&player);
+	    strncpy(pstats.s_dmg, "3d4", sizeof(pstats.s_dmg));
+	    check_level();
+	    mpos = 0;
+	    if (player.t_ctype == C_FIGHTER ||
+	        player.t_ctype == C_RANGER  ||
+	        player.t_ctype == C_PALADIN)
+		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;
+	    if (player.t_ctype != C_MONK) {
+		j = PLATE_ARMOR;
+		if (player.t_ctype == C_THIEF || player.t_ctype == C_ASSASIN)
+		    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
+
+    {
+	switch(player.t_ctype) {
+	    case C_MAGICIAN:round = A_INTELLIGENCE;
+	    when C_FIGHTER:	round = A_STRENGTH;
+	    when C_RANGER:	round = A_STRENGTH;
+	    when C_PALADIN:	round = A_STRENGTH;
+	    when C_CLERIC:	round = A_WISDOM;
+	    when C_DRUID:	round = A_WISDOM;
+	    when C_THIEF:	round = A_DEXTERITY;
+	    when C_ASSASIN:	round = A_DEXTERITY;
+	    when C_MONK:	round = A_DEXTERITY;
+	}
+
+	do {
+	    wclear(hw);
+
+	    /* If there is any news, display it */
+	    if (rogue_news) {
+		register int i;
+
+		/* Print a separator line */
+		wmove(hw, 12, 0);
+		for (i=0; i<cols; i++) waddch(hw, '-');
+
+		/* Print the news */
+		mvwaddstr(hw, 14, 0, rogue_news);
+	    }
+
+	    stat_total = MAXSTATS;
+	    do_escape = FALSE;	/* No escape seen yet */
+
+	    /* Initialize abilities */
+	    pstats.s_intel = 0;
+	    pstats.s_str = 0;
+	    pstats.s_wisdom = 0;
+	    pstats.s_dext = 0;
+	    pstats.s_const = 0;
+	    pstats.s_charisma = 0;
+
+	    /* Initialize pointer into abilities */
+	    our_stats[A_INTELLIGENCE] = &pstats.s_intel;
+	    our_stats[A_STRENGTH] = &pstats.s_str;
+	    our_stats[A_WISDOM] = &pstats.s_wisdom;
+	    our_stats[A_DEXTERITY] = &pstats.s_dext;
+	    our_stats[A_CONSTITUTION] = &pstats.s_const;
+
+	    /* Let player distribute attributes */
+	    for (i=0; i<NUMABILITIES-1; i++) {
+		wmove(hw, 2, 0);
+		wprintw(hw, "You are creating a %s with %2d attribute points.",
+				char_class[player.t_ctype].name, stat_total);
+
+		/*
+		 * Player must have a minimum of 7 in any attribute and 11 in
+		 * the player's primary attribute.
+		 */
+		minimum = (round == i ? 11 : 7);
+
+		/* Subtract out remaining minimums */
+		maximum = stat_total - (7 * (NUMABILITIES-1 - i));
+
+		/* Subtract out remainder of profession minimum (11 - 7) */
+		if (round > i) maximum -= 4;
+
+		/* Maximum can't be greater than 18 */
+		if (maximum > 18) maximum = 18;
+
+		wmove(hw, 4, 0);
+		wprintw(hw,
+		   "Minimum: %2d; Maximum: %2d (%s corrects previous entry)",
+		   minimum, maximum, unctrl('\b'));
+
+		wmove(hw, 6, 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, "    Con: %-2d", pstats.s_const);
+		wprintw(hw, "    Cha: %-2d", pstats.s_charisma);
+		wclrtoeol(hw);
+		wmove(hw, 6, 11*i + 9);
+		if (do_escape == FALSE) draw(hw);
+
+		/* Get player's input */
+		if (do_escape || maximum == minimum) {
+		    *our_stats[i] = maximum;
+		    stat_total -= maximum;
+		}
+		else for (;;) {
+		    ch = wgetch(hw);
+		    if (ch == '\b') {	/* Backspace */
+			if (i == 0) continue;	/* Can't move back */
+			else {
+			    stat_total += *our_stats[i-1];
+			    *our_stats[i] = 0;
+			    *our_stats[i-1] = 0;
+			    i -= 2;	/* Back out */
+			    break;
+			}
+		    }
+		    if (ch == '\033') {	/* Escape */
+			/*
+			 * Escape will result in using all maximums for
+			 * remaining abilities.
+			 */
+			do_escape = TRUE;
+			*our_stats[i] = maximum;
+			stat_total -= maximum;
+			break;
+		    }
+
+		    /* Do we have a legal digit? */
+		    if (ch >= '0' && ch <= '9') {
+			ch -= '0';	/* Convert it to a number */
+			*our_stats[i] = 10 * *our_stats[i] + ch;
+
+			/* Is the number in range? */
+			if (*our_stats[i] >= minimum &&
+			    *our_stats[i] <= maximum) {
+			    stat_total -= *our_stats[i];
+			    break;
+			}
+
+			/*
+			 * If it's too small, get more - 1x is the only
+			 * allowable case.
+			 */
+			if (*our_stats[i] < minimum && *our_stats[i] == 1) {
+			    /* Print the player's one */
+			    waddch(hw, '1');
+			    draw(hw);
+			    continue;
+			}
+		    }
+
+		    /* Error condition */
+		    putchar('\007');
+		    *our_stats[i] = 0;
+		    i--;	/* Rewind */
+		    break;
+		}
+	    }
+
+	    /* Discard extra points over 18 */
+	    if (stat_total > 18) stat_total = 18;
+
+	    /* Charisma gets what's left */
+	    pstats.s_charisma = stat_total;
+
+	    /* Intialize constants */
+	    pstats.s_lvl = 1;
+	    pstats.s_lvladj = 0;
+	    pstats.s_exp = 0L;
+	    strncpy(pstats.s_dmg, "1d4", sizeof(pstats.s_dmg));
+	    pstats.s_carry = totalenc(&player);
+
+	    /* Get the hit points. */
+	    pstats.s_hpt = 12 + const_bonus();  /* Base plus bonus */
+
+	    /* Add in the component that varies according to class */
+	    pstats.s_hpt += char_class[player.t_ctype].hit_pts;
+
+	    /* Display the character */
+	    wmove(hw, 2, 0);
+	    wprintw(hw,"You are creating a %s.",
+			char_class[player.t_ctype].name);
+	    wclrtoeol(hw);
+
+	    /* Get rid of max/min line */
+	    wmove(hw, 4, 0);
+	    wclrtoeol(hw);
+
+	    wmove(hw, 6, 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, "    Con: %2d", pstats.s_const);
+	    wprintw(hw, "    Cha: %2d", pstats.s_charisma);
+	    wclrtoeol(hw);
+
+	    wmove(hw, 8, 0);
+	    wprintw(hw, "    Hp: %2d", pstats.s_hpt);
+	    wclrtoeol(hw);
+
+	    wmove(hw, 10, 0);
+	    wprintw(hw, "    Gold: %d", purse);
+
+	    mvwaddstr(hw, 0, 0, "Is this character okay? ");
+	    draw(hw);
+	} while(wgetch(hw) != 'y');
+    }
+
+    pstats.s_arm = 10;
+    max_stats = pstats;
+
+    /* Set up the initial movement rate */
+    player.t_action = A_NIL;
+    player.t_movement = 6;
+    player.t_no_move = 0;
+    player.t_using = NULL;
+}
+
+
+
+
+
+
+/*
+ * init_stones:
+ *	Initialize the ring stone setting scheme for this time
+ */
+
+init_stones()
+{
+    register int i, j;
+
+    for (i = 0; i < NSTONES; i++)
+	used[i] = FALSE;
+
+    for (i = 0 ; i < MAXRINGS ; i++)
+    {
+        do
+            j = rnd(NSTONES);
+	until (!used[j]);
+	used[j] = TRUE;
+	r_stones[i] = stones[j];
+	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/arogue7/io.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,539 @@
+/*
+ * io.c  -  Various input/output functions
+ *
+ * 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.
+ */
+
+/*
+ * Various input/output functions
+ */
+
+#include "curses.h"
+#include <stdarg.h>
+#include <ctype.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()
+{
+    /* Needed to track where we are for 5.0 (PC) curses */
+    register int x, y;
+
+    strcpy(huh, msgbuf);
+    if (mpos) {
+	/*
+	 * If this message will fit on the line (plus space for --More--
+	 * then just add it (only during combat).
+	 */
+	if (player.t_quiet < 0 && mpos + newpos + strlen(morestr) + 2 < cols) {
+	    wmove(msgw, 0, mpos + 2);
+	    newpos += mpos + 2;
+	}
+	else {
+	    wmove(msgw, 0, mpos);
+	    waddstr(msgw, morestr);
+	    draw(cw);
+	    draw(msgw);
+	    wait_for(' ');
+	    overwrite(cw,msgw);
+	    wmove(msgw, 0, 0);
+	    touchwin(cw);
+	}
+    }
+    else {
+	overwrite(cw,msgw);
+        wmove(msgw, 0, 0);
+    }
+    waddstr(msgw, msgbuf);
+    getyx(msgw, y, x);
+    mpos = newpos;
+    newpos = 0;
+    wmove(msgw, y, x);
+    draw(cw);
+    clearok(msgw, FALSE);
+    draw(msgw);
+}
+
+doadd(char *fmt, va_list ap)
+{
+
+    /*
+     * Do the printf into buf
+     */
+    vsprintf(&msgbuf[newpos], 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;
+    register struct thing *tp;
+    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) );
+
+    if (can_on_monst == FIGHTOK && isalpha(ch) &&
+	(item = find_mons(y, x)) != NULL) {
+	tp = THINGPTR(item);	/* What monster is here? */
+
+	/* We can hit it if we're after it */
+	if (flgptr->t_dest == &tp->t_pos) return TRUE;
+
+	/*
+	 * Otherwise, if we're friendly we'll hit it unless it is also
+	 * friendly or is our race.
+	 */
+	if (off(*flgptr, ISFRIENDLY)	||
+	    on(*tp, ISFRIENDLY)		||
+	    flgptr->t_index == tp->t_index) return FALSE;
+	else return TRUE;
+    }
+    else 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));
+    }
+    return(FALSE);
+}
+/*
+ * 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, ox, temp;
+    register char *pb;
+    static char buf[LINELEN];
+    static int hpwidth = 0, s_hungry = -1;
+    static int s_lvl = -1, 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;
+
+    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_hungry == hungry_state		&&
+	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)  Con:%d(%d)  Cha:%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_charisma,
+	max_ptr->s_charisma);
+
+    /* 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();
+    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);
+    switch (hungry_state)
+    {
+	case F_SATIATED:
+	    waddstr(cw, "  Satiated");
+	when 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;
+
+    /*
+     * If nothing has changed since the last status, don't
+     * bother.
+     */
+line_two: 
+    if (!display					&&
+	s_lvl == level 					&& 
+	s_hp == stat_ptr->s_hpt				&& 
+	s_ac == ac_compute(FALSE) - dext_prot(s_dext)	&&
+	s_pack == stat_ptr->s_pack			&&
+	s_carry == stat_ptr->s_carry			&&
+	s_exp == stat_ptr->s_exp			) 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  Hp:%*d(%*d)  Ac:%d  Carry:%d(%d)  Exp:%d/%lu  %s",
+	level, hpwidth, stat_ptr->s_hpt, hpwidth, max_ptr->s_hpt,
+	ac_compute(FALSE) - dext_prot(s_dext),stat_ptr->s_pack/10,
+	stat_ptr->s_carry/10, stat_ptr->s_lvl, stat_ptr->s_exp, 
+	cnames[player.t_ctype][min(stat_ptr->s_lvl-1, NUM_CNAMES-1)]);
+
+    /*
+     * Save old status
+     */
+    s_lvl = level;
+    s_hp = stat_ptr->s_hpt;
+    s_ac = ac_compute(FALSE) - dext_prot(s_dext);
+    s_pack = stat_ptr->s_pack;
+    s_carry = stat_ptr->s_carry;
+    s_exp = stat_ptr->s_exp; 
+    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(ch)
+register char ch;
+{
+    register char c;
+
+    if (ch == '\n')
+        while ((c = wgetch(msgw)) != '\n' && c != '\r')
+	    continue;
+    else
+        while (wgetch(msgw) != ch)
+	    continue;
+}
+
+
+/*
+ * over_win:
+ *	Given a current window, a new window, and the max y and x of the
+ *	new window, paint the new window on top of the old window without
+ *	destroying any of the old window.  Current window and new window
+ *	are assumed to have lines lines and cols columns (max y and max x
+ *	pertain only the the useful information to be displayed.
+ *	If redraw is non-zero, we wait for the character "redraw" to be
+ *	typed and then redraw the starting screen.
+ */
+
+over_win(oldwin, newin, maxy, maxx, cursory, cursorx, redraw)
+WINDOW *oldwin, *newin;
+int maxy, maxx, cursory, cursorx;
+char redraw;
+{
+    static char blanks[LINELEN+1];
+    register int line, i;
+    WINDOW *ow;	/* Overlay window */
+
+    /* Create a blanking line */
+    for (i=0; i<maxx && i<cols && i<LINELEN; i++) blanks[i] = ' ';
+    blanks[i] = '\0';
+
+    /* Create the window we will display */
+    ow = newwin(lines, cols, 0, 0);
+
+    /* Blank out the area we want to use */
+    if (oldwin == cw) {
+	msg("");
+	line = 1;
+    }
+    else line = 0;
+
+    overwrite(oldwin, ow);	/* Get a copy of the old window */
+
+    /* Do the remaining blanking */
+    for (; line < maxy; line++) mvwaddstr(ow, line, 0, blanks);
+
+    overlay(newin, ow);	/* Overlay our new window */
+
+    /* Move the cursor to the specified location */
+    wmove(ow, cursory, cursorx);
+
+    clearok(ow, FALSE);		/* Draw inventory without clearing */
+    draw(ow);
+
+    if (redraw) {
+	wait_for(redraw);
+
+	clearok(oldwin, FALSE);		/* Setup to redraw current screen */
+	touchwin(oldwin);		/* clearing first */
+	draw(oldwin);
+    }
+
+    delwin(ow);
+}
+
+
+/*
+ * 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(' ');
+    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(' ');	
+}
+
+
+/*
+ * 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/arogue7/list.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,226 @@
+/*
+ * list.c  -  Functions for dealing with linked lists of goodies
+ *
+ * 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.
+ */
+
+/*
+ * Functions for dealing with linked lists of goodies
+ *
+ */
+
+#include "curses.h"
+#include <stdlib.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(obj);
+    FREE(item);
+}
+
+/*
+ * r_free_list:
+ *	Throw the whole list of room exits away
+ */
+
+_r_free_list(ptr)
+register struct linked_list **ptr;
+{
+    register struct linked_list *item;
+
+    while (*ptr != NULL)
+    {
+	item = *ptr;
+	*ptr = next(item);
+	r_discard(item);
+    }
+}
+
+/*
+ * r_discard:
+ *	free up an item and its room
+ */
+
+r_discard(item)
+register struct linked_list *item;
+{
+    total -= 2;
+    FREE(DOORPTR(item));
+    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)
+register struct linked_list *item;
+{
+    register struct thing *tp;
+
+    total -= 2;
+    tp = THINGPTR(item);
+    if (tp->t_name != NULL) FREE(tp->t_name);
+    FREE(tp);
+    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/arogue7/mach_dep.h	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,84 @@
+/*
+ * mach_dep.h  -  machine dependicies
+ *
+ * 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.
+ */
+
+/*
+ * define that the wizard commands exist
+ */
+#define	WIZARD	0
+
+/*
+ * define if you want to limit scores to one per class per userid
+ */
+#undef LIMITSCORE /* 1 */
+
+/* 
+ * define that rogue should "nice()" itself
+ */
+#undef NICE	/* 1 */
+
+#ifdef NICE
+#define	FUDGE_TIME	70	/* fudge factor allowed in time for saved game*/
+#else
+#define	FUDGE_TIME	50	/* fudge factor allowed in time for saved game*/
+#endif
+
+#undef	DUMP		/* 1 */	/* dump core rather than catch the signal     */
+#undef	NOCHECKACCESS	/* 1 */	/* If set, then don't check time on save file */
+
+
+/*
+ * where scorefile should live
+ */
+#ifndef SCOREFILE
+#define SCOREFILE	"/usr/games/lib/rogue_roll"
+#endif
+
+/*
+ * Variables for checking to make sure the system isn't too loaded
+ * for people to play
+ */
+
+#if u370
+#	define	MAXUSERS	40	/* max number of users for this game */
+#	define	MAXPROCESSES	140	/* number processes including system */
+					/* processes but not including gettys*/
+#endif
+#if uts
+#	define	MAXUSERS	45	/* max number of users for this game */
+#	define	MAXPROCESSES	150	/* number processes including system */
+					/* processes but not including gettys*/
+#endif
+#if vax
+#	define	MAXUSERS	17	/* max number of users for this game */
+#	define	MAXPROCESSES	85	/* number processes including system */
+					/* processes but not including gettys*/
+#endif
+#if u3b
+#	define	MAXUSERS	14	/* max number of users for this game */
+#	define	MAXPROCESSES	75	/* number processes including system */
+					/* processes but not including gettys*/
+#endif
+
+#undef	MAXUSERS
+#undef	MAXPROCESSES
+
+#undef	CHECKTIME	/* 15 *//* number of minutes between load checks     */
+				/* if not defined checks are only on startup */
+#define UTMP	"/etc/utmp"	/* where utmp file lives */
+/*
+ * define the current author user id of the program for "special handling"
+ */
+#ifndef AUTHOR
+#define AUTHOR 0
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/main.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,725 @@
+/*
+ * main.c  -  setup code
+ *
+ * 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.
+ */
+
+#include "curses.h"
+#include <signal.h>
+#ifdef BSD
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#include "mach_dep.h"
+#include "network.h"
+#include "rogue.h"
+#ifdef PC7300
+#include "sys/window.h"
+#include <ctype.h>
+extern struct uwdata wdata, oldwin;
+extern char oldtext[WTXTNUM][WTXTLEN];
+#endif
+
+main(argc, argv, envp)
+char **argv;
+char **envp;
+{
+    register char *env;
+    int lowtime;
+    time_t now;
+#ifdef PC7300
+    int hardwindow;	/* Do we have a hardware window? */
+#endif
+
+    md_init();
+
+    /*
+     * get home and options from environment
+     */
+
+    strncpy(home, md_gethomedir(), LINELEN);
+
+    /* Get default save file */
+    strcpy(file_name, home);
+    strcat(file_name, "arogue77.sav");
+
+    /* Get default score file */
+    strcpy(score_file, md_getroguedir());
+
+    if (*score_file)
+        strcat(score_file,"/");
+
+    strcat(score_file,"arogue77.scr");
+
+    if ((env = getenv("ROGUEOPTS")) != NULL)
+	parse_opts(env);
+
+    if (whoami[0] == '\0')
+        strucpy(whoami, md_getusername(), strlen(md_getusername()));
+
+    /*
+     * 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: "), "mT")) == 0)
+	{
+	    wizard = TRUE;
+	    argv++;
+	    argc--;
+	}
+#endif
+
+    if (!wizard && !author() && !holiday()) {
+	printf("Sorry, %s, but you can't play during working hours.\n", whoami);
+	printf("Try again later.\n");
+	exit(1);
+    }
+    if (!wizard && !author() && too_much()) {
+	printf("Sorry, %s, but the system is too loaded now.\n", whoami);
+	printf("Try again later.\n");
+	exit(1);
+    }
+
+#if NICE
+    if (!wizard)
+        nice(19);	/* nice the max amount */
+#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", whoami, dnum);
+    else
+	printf("Hello %s, just a moment while I dig the dungeon...", whoami);
+    fflush(stdout);
+    seed = dnum;
+    md_srand(seed);
+
+#ifdef PC7300
+    /* Store static window parameters */
+    hardwindow = ioctl(0, WIOCGETD, &wdata);
+    if (hardwindow >= 0) {	/* We have a hardware window */
+	extern char **environ;
+
+	/* Make sure our window is the right size */
+	oldwin = wdata;
+	if ((wdata.uw_height / wdata.uw_vs) < 23 ||
+	    (wdata.uw_width / wdata.uw_hs) < 75) {
+	    wdata.uw_width = 80 * wdata.uw_hs;
+	    wdata.uw_height = 24 * wdata.uw_vs;
+	    wdata.uw_x = 0;
+	    wdata.uw_y = wdata.uw_vs;
+	    wdata.uw_uflags = NBORDER;
+
+	    /* Make the change */
+	    if (ioctl(1, WIOCSETD, &wdata) >= 0 && environ) {
+		char **eptr, *tptr, *nptr, *newenv, *lptr = 0, *cptr = 0;
+		int i, nlines = -1, ncols = -1, nlindig = 0, ncoldig = 0;
+		struct utdata labelbuf;
+
+		/* Save and change window-associated text */
+		for (i=0; i<WTXTNUM; i++) {
+		    labelbuf.ut_num = i;
+		    ioctl(1, WIOCGETTEXT, &labelbuf);
+		    strncpy(oldtext[i], labelbuf.ut_text, WTXTLEN - 1);
+		    if (*labelbuf.ut_text) {
+			*labelbuf.ut_text = '\0';
+			ioctl(1, WIOCSETTEXT, &labelbuf);
+		    }
+		}
+
+		labelbuf.ut_num = WTXTLABEL;
+		strcpy(labelbuf.ut_text, "Advanced Rogue");
+		ioctl(1, WIOCSETTEXT, &labelbuf);
+
+		/* We have to change the TERMCAP entry */
+		eptr = environ;
+		while (*eptr) {
+		    if (strncmp(*eptr, "TERMCAP=", 8) == 0) break;
+		    else eptr++;
+		}
+
+		/* We found a TERMCAP entry */
+		if (*eptr) {
+		    /* Search for li# and co# */
+		    tptr = *eptr;
+		    while (*tptr) {
+			switch (*tptr) {
+			    case 'l':
+				if (nlines == -1 &&
+				    strncmp(tptr, "li#", 3) == 0) {
+				    tptr += 3;
+				    lptr = tptr;
+				    lines = atoi(tptr);
+				    while (isdigit(*tptr)) {
+					nlindig++;;
+					tptr++;
+				    }
+				}
+				else tptr++;
+				break;
+			    case 'c':
+				if (ncols == -1 &&
+				    strncmp(tptr, "co#", 3) == 0) {
+				    tptr += 3;
+				    cptr = tptr;
+				    cols = atoi(tptr);
+				    while (isdigit(*tptr)) {
+					ncoldig++;
+					tptr++;
+				    }
+				}
+				else tptr++;
+				break;
+			    default:
+				tptr++;
+			}
+		    }
+
+		    /* Change the entry */
+		    if (ncoldig != 2 || nlindig != 2) {
+			int length;
+
+			/* Add in difference in num lengths plus NULL */
+			length = strlen(*eptr) - ncoldig - nlindig + 5;
+
+			if (ncoldig == 0) length += 4; /* For :co# */
+			if (nlindig == 0) length += 4; /* For :li# */
+
+			newenv = malloc(length);
+			tptr = *eptr;
+			nptr = newenv;
+
+			if (nlindig == 0 || ncoldig == 0) {
+			    /* Copy up to the first : */
+			    while (*tptr && *tptr != ':') *nptr++ = *tptr++;
+
+			    /* Do we have to add a field? */
+			    if (nlindig == 0) {
+				strcpy(nptr, ":li#24");
+				nptr += 6;
+			    }
+			    if (ncoldig == 0) {
+				strcpy(nptr, ":co#80");
+				nptr += 6;
+			    }
+			}
+			while (*tptr) {
+			    if (tptr == lptr) {
+				strcpy(nptr, "24");
+				nptr += 2;
+				tptr += nlindig;
+			    }
+			    else if (tptr == cptr) {
+				strcpy(nptr, "80");
+				nptr += 2;
+				tptr += ncoldig;
+			    }
+			    else *nptr++ = *tptr++;
+			}
+
+			*nptr = '\0';
+
+			/* Replace the old one */
+			free(*eptr);
+			*eptr = newenv;
+		    }
+		    else {
+			/* Just overwrite the old numbers */
+			*lptr++ = '2';
+			*lptr = '4';
+			*cptr++ = '8';
+			*cptr = '0';
+		    }
+		}
+	    }
+	}
+    }
+#endif
+    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 */
+    init_foods();			/* set up the food table */
+
+    cols = COLS;
+    lines = LINES;
+    if (cols > 85) cols = 85;
+    if (lines > 24) lines = 24;
+    if (lines < 23 || cols < 75) { /* give player a break if larger font used */
+	printf("\nERROR: screen size too small for rogue\n");
+	byebye(0);
+    }
+
+    /*
+     * Now that we have cols and lines, we can update our window
+     * structure for non-hardware windows.
+     */
+#ifdef PC7300
+    if (hardwindow < 0) {
+	wdata.uw_x = 0;
+	wdata.uw_y = 0;
+	wdata.uw_width = COLS;
+	wdata.uw_height = LINES;
+	wdata.uw_uflags = 0;
+	wdata.uw_hs = 1;
+	wdata.uw_vs = 1;
+	wdata.uw_baseline = 0;
+    }
+#endif
+    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,TRUE);
+    keypad(msgw,TRUE);
+
+    init_player();			/* Roll up the rogue */
+    waswizard = wizard;
+
+#ifdef WIZARD
+    /* A super wizard doesn't have to get equipped */
+    if (wizard && strcmp(getenv("SUPER"),"YES") == 0) {
+	level = 1;
+	new_level(NORMLEV);
+    }
+    else
+#endif
+    new_level(STARTLEV);		/* Draw current level */
+    /*
+     * Start up daemons and fuses
+     */
+    daemon(doctor, &player, AFTER);
+    fuse(swander, 0, WANDERTIME, AFTER);
+    if (player.t_ctype == C_MAGICIAN || player.t_ctype == C_RANGER)
+	    fuse(spell_recovery, 0, SPELLTIME, AFTER);
+    if (player.t_ctype == C_DRUID || player.t_ctype == C_RANGER)
+	    fuse(chant_recovery, 0, SPELLTIME, AFTER);
+    if (player.t_ctype == C_CLERIC || player.t_ctype == C_PALADIN)
+	    fuse(prayer_recovery, 0, SPELLTIME, AFTER);
+    daemon(stomach, 0, AFTER);
+    if (player.t_ctype == C_THIEF	||
+	player.t_ctype == C_ASSASIN	||
+	player.t_ctype == C_MONK)
+	    daemon(trap_look, 0, AFTER);
+
+    /* Does this character have any special knowledge? */
+    switch (player.t_ctype) {
+	case C_ASSASIN:
+	    /* Assassins automatically recognize poison */
+	    p_know[P_POISON] = TRUE;
+    }
+
+    /* Choose a quest item */
+    quest_item = rnd(MAXRELIC);
+    draw(cw);
+    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(sig)
+int 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();
+#ifdef PC7300
+    endhardwin();
+#endif
+    printf("\n");	/* So the curser 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(sig)
+int sig;
+{
+    mvcur(0, cols - 1, lines - 1, 0);
+    endwin();
+    fflush(stdout);
+    kill(0, SIGTSTP);
+    signal(SIGTSTP, tstp);
+    raw();
+    noecho();
+    keypad(cw,1);
+    keypad(msgw,1);
+    clearok(curscr, TRUE);
+    touchwin(cw);
+    draw(cw);
+    md_flushinp();
+}
+# endif
+
+setup()
+{
+#ifdef CHECKTIME
+    int  checkout();
+
+    if (!author()) {
+	signal(SIGALRM, checkout);
+	alarm(CHECKTIME * 60);
+    }
+#endif
+/*
+#ifndef DUMP
+    signal(SIGILL, bugkill);
+#ifdef SIGTRAP
+    signal(SIGTRAP, bugkill);
+#endif
+#ifdef SIGIOT
+    signal(SIGIOT, bugkill);
+#endif
+#ifdef SIGEMT
+    signal(SIGEMT, bugkill);
+#endif
+    signal(SIGFPE, bugkill);
+#ifdef SIGBUS
+    signal(SIGBUS, bugkill);
+#endif
+    signal(SIGSEGV, bugkill);
+#ifdef SIGSYS
+    signal(SIGSYS, bugkill);
+#endif
+#ifdef SIGPIPE
+    signal(SIGPIPE, bugkill);
+#endif
+#endif
+*/
+#ifdef SIGTSTP
+    signal(SIGTSTP, tstp);
+#endif
+
+#ifdef SIGHUP
+    signal(SIGHUP, auto_save);
+#endif
+    signal(SIGTERM, auto_save);
+    signal(SIGINT, quit);
+#ifdef SIGQUIT
+    signal(SIGQUIT, endit);
+#endif
+    raw();				/* 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;
+    command();			/* Command execution */
+    endit(0);
+}
+
+/*
+ * see if the system is being used too much for this game
+ */
+too_much()
+{
+#if MAXPROCESSES
+	if (loadav() > MAXPROCESSES)
+		return(TRUE);
+#endif
+#if MAXUSERS
+	if (ucount() > MAXUSERS)
+		return(TRUE);
+#endif
+	return(FALSE);
+}
+
+/*
+ * author:
+ *	See if a user is an author of the program
+ */
+author()
+{
+	switch (md_getuid()) {
+#if AUTHOR
+		case AUTHOR:
+#endif
+		case 0: /* always OK for root to play */
+			return TRUE;
+		default:
+			return FALSE;
+	}
+}
+
+
+#if CHECKTIME
+static int num_checks = 0;	/* times we've gone over in checkout() */
+
+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()) {
+	    msg("Game time is over. Your game is being saved.\n\n");
+	    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 MAXPROCESSES
+
+#include <fcntl.h>
+
+loadav()
+{
+	char *sarcmd = "sar -v | cut -c17-20 | tail -2";
+	char *gettycmd = "grep getty /etc/inittab | wc -l";
+	char sysbuffer[BUFSIZ];
+	char tempfile[50];
+	char inbuf[BUFSIZ];
+	int fd, nprocess, ngetty;
+
+	sprintf(tempfile, "/tmp/rg%d", getpid());
+	sprintf(sysbuffer, "%s > %s", sarcmd, tempfile);
+	if (system(sysbuffer) != 0) {
+	    debug ("system() call failed");
+	    return (MAXPROCESSES - 1);
+	}
+	if ((fd = open(tempfile, O_RDONLY)) == -1) {
+	    debug ("open() call failed");
+	    return (MAXPROCESSES - 1);
+	}
+	if (read(fd, inbuf, BUFSIZ) == -1) {
+	    debug ("read() call failed");
+	    return (MAXPROCESSES - 1);
+	}
+	close(fd);
+	sscanf(inbuf, "%d", &nprocess);
+	sprintf(sysbuffer, "%s > %s", gettycmd, tempfile);
+	if (system(sysbuffer) != 0) {
+	    debug ("system() call failed");
+	    return (MAXPROCESSES - 1);
+	}
+	if ((fd = open(tempfile, O_RDONLY)) == -1) {
+	    debug ("open() call failed");
+	    return (MAXPROCESSES - 1);
+	}
+	if (read(fd, inbuf, BUFSIZ) == -1) {
+	    debug ("read() call failed");
+	    return (MAXPROCESSES - 1);
+	}
+	close(fd);
+	sscanf(inbuf, "%d", &ngetty);
+	unlink(tempfile);
+	return(nprocess - ngetty);
+}
+#endif
+
+#ifdef MAXUSERS
+/*
+ * 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)
+#ifdef BSD
+		if (buf.ut_line[0] == 't')	/* On a tty */
+#else
+		if (buf.ut_type == USER_PROCESS)
+#endif
+			count++;
+	fclose(utmp);
+	return count;
+}
+#endif
+
+/*
+ * holiday:
+ *	Returns TRUE when it is a good time to play rogue
+ */
+holiday()
+{
+#ifdef CHECKTIME
+	long 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 >= 18)
+		return TRUE;		/* OK before 8AM & after 6PM */
+	if(ntime->tm_yday <= 7 || ntime->tm_yday >= 350)
+		return TRUE;		/* OK during Christmas */
+	return FALSE;			/* All other times are bad */
+#else
+	return TRUE;
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/maze.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,368 @@
+/*
+ * maze.c  -  functions for dealing with mazes
+ *
+ * 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.
+ */
+
+#include "curses.h"
+#include <stdlib.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(5) + 5);		/* 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) < 40) {			/* treasure type maze */
+		treas = TRUE;
+		least = 10;
+		debug("treasure maze");
+	}
+	else {					/* normal maze level */
+		least = 5;
+		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, xcheck, absy, absx, see_radius;
+    register bool row;
+
+    /* 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 (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/arogue7/mdport.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,1195 @@
+/*
+    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 <Shlwapi.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 _PATH_MAX
+#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(random());
+#endif
+}
+
+int
+md_srand(seed)
+register int seed;
+{
+#ifdef _WIN32
+    srand(seed);
+#else
+    srandom(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;
+
+    while(1)
+    {
+        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/arogue7/misc.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,1202 @@
+/*
+ * misc.c - routines dealing specifically with miscellaneous magic
+ *
+ * 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.
+ */
+
+#include "curses.h"
+#include <ctype.h>
+#include "rogue.h"
+#ifdef PC7300
+#include "menu.h"
+#endif
+
+/*
+ * routines dealing specifically with miscellaneous magic
+ */
+
+/*
+ * changeclass:
+ *	Change the player's class to the specified one.
+ */
+
+changeclass(newclass)
+int newclass;
+{
+    if (newclass == player.t_ctype) {
+	msg("You feel more skillful.");
+	raise_level();
+    }
+    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 ((newclass == C_THIEF || newclass == C_ASSASIN)	&&
+	    cur_armor != NULL					&&
+	    cur_armor->o_which != LEATHER			&&
+	    cur_armor->o_which != STUDDED_LEATHER ) 
+		cur_armor->o_which = STUDDED_LEATHER;
+	/*
+	 * if he becomes a monk he can't wear armor
+	 */
+	if (newclass == C_MONK && cur_armor != NULL) {
+		cur_armor->o_ac = armors[cur_armor->o_which].a_class - 
+				  cur_armor->o_ac;
+		cur_armor->o_type = MM;
+		cur_armor->o_which = MM_PROTECT;
+		cur_armor->o_flags &= ~(ISPROT | ISKNOW | ISMETAL);
+		cur_misc[WEAR_CLOAK] = cur_armor;
+		cur_armor = NULL;
+	}
+	/*
+	 * if he used to be a spell caster of some sort, kill the fuse
+	 */
+	if (player.t_ctype == C_MAGICIAN || player.t_ctype == C_RANGER)
+		extinguish(spell_recovery);
+	if (player.t_ctype == C_DRUID || player.t_ctype == C_RANGER)
+		extinguish(chant_recovery);
+	if ((player.t_ctype == C_CLERIC || player.t_ctype == C_PALADIN) &&
+	     !cur_relic[HEIL_ANKH])
+		extinguish(prayer_recovery);
+	/*
+	 * if he becomes a spell caster of some kind, give him a fuse
+	 */
+	if (newclass == C_MAGICIAN || newclass == C_RANGER)
+		fuse(spell_recovery, 0, SPELLTIME, AFTER);
+	if (newclass == C_DRUID || newclass == C_RANGER)
+		fuse(chant_recovery, 0, SPELLTIME, AFTER);
+	if ((newclass==C_CLERIC || newclass==C_PALADIN) && !cur_misc[HEIL_ANKH])
+		fuse(prayer_recovery, 0, SPELLTIME, AFTER);
+	/*
+	 * 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	||
+	     player.t_ctype == C_RANGER		||
+	     player.t_ctype == C_PALADIN)		&&
+	    cur_weapon != NULL				&&
+	    cur_weapon->o_type == WEAPON		&&
+	   (cur_weapon->o_which== BASWORD	||
+	    cur_weapon->o_which== TWOSWORD )		&&
+	   !(newclass == C_FIGHTER		||
+	     newclass == C_RANGER		||
+	     newclass == C_PALADIN)			&&
+	   !(newclass == C_ASSASIN		&&
+	     cur_weapon->o_which == BASWORD))
+		cur_weapon->o_which = SWORD;
+
+	/*
+	 * if he was a thief then take out the trap_look() daemon
+	 */
+	if (player.t_ctype == C_THIEF || 
+	    player.t_ctype == C_MONK  ||
+	    player.t_ctype == C_ASSASIN)
+	    kill_daemon(trap_look);
+
+	/*
+	 * if he becomes a thief then add the trap_look() daemon
+	 */
+	if (newclass == C_THIEF || newclass == C_ASSASIN || newclass == C_MONK)
+	    daemon(trap_look, 0, AFTER);
+	char_type = player.t_ctype = newclass;
+	save = pstats.s_hpt;
+	max_stats.s_hpt = pstats.s_hpt = 0;
+	max_stats.s_lvl = pstats.s_lvl = 0; 
+	max_stats.s_lvladj = pstats.s_lvladj = 0; 
+	max_stats.s_exp = pstats.s_exp -= pstats.s_exp/10;
+	check_level();
+	if (pstats.s_hpt > save) /* don't add to current hits */
+	    pstats.s_hpt = save;
+    }
+}
+
+/*
+ * Use the relic that our monster is wielding.
+ */
+m_use_relic(monster)
+register struct thing *monster;
+{
+    register struct object *obj;
+
+    /* Make sure we really have it */
+    if (monster->t_using) obj = OBJPTR(monster->t_using);
+    else {
+	debug("Relic not set!");
+	monster->t_action = A_NIL;
+	return;
+    }
+
+    /* Now let's see what we're using */
+    if (obj->o_type == RELIC) switch (obj->o_which) {
+	case MING_STAFF: {
+	    static struct object missile = {
+	      MISSILE, {0,0}, "", 0, "", "0d4 " , NULL, 0, WS_MISSILE, 100, 1
+	    };
+
+	    debug("Firing Ming's staff");
+	    sprintf(missile.o_hurldmg, "%dd4", monster->t_stats.s_lvl);
+	    do_motion(&missile,
+		       monster->t_newpos.y, monster->t_newpos.x, monster);
+	    hit_monster(unc(missile.o_pos), &missile, monster);
+	    monster->t_artifact = monster->t_artifact * 4 / 5;
+	}
+	when EMORI_CLOAK:
+	    debug("stunning with Emori's cloak");
+	    do_zap(monster, obj, &monster->t_newpos, WS_PARALYZE, NULL);
+	    obj->o_charges = 0;
+
+	when ASMO_ROD: {
+	    char *name;
+
+	    switch (rnd(3)) { /* Select a function */
+		case 0:	   name = "lightning bolt";
+		when 1:	   name = "flame";
+		otherwise: name = "ice";
+	    }
+	    shoot_bolt(	monster, 
+			monster->t_pos, 
+			monster->t_newpos, 
+			FALSE, 
+			monster->t_index, 
+			name, 
+			roll(monster->t_stats.s_lvl,6));
+	    monster->t_artifact /= 2;
+	}
+	when BRIAN_MANDOLIN:
+	    /* Make sure the defendant is still around */
+	    if (DISTANCE(monster->t_pos.y, monster->t_pos.x,
+			 hero.y, hero.x) < 25) {
+		if (!save(VS_MAGIC, &player, -4) &&
+		    !ISWEARING(R_ALERT)) {
+		    msg("Some beautiful music enthralls you.");
+		    player.t_no_move += movement(&player) * FREEZETIME;
+		    player.t_action = A_FREEZE;
+		    monster->t_artifact = monster->t_artifact * 2 / 3;
+		}
+		else {
+		    msg("You wince at a sour note.");
+		    monster->t_artifact /= 3;
+		}
+	    }
+	when GERYON_HORN:
+	    /* Make sure the defendant is still around */
+	    if (DISTANCE(monster->t_pos.y, monster->t_pos.x,
+			 hero.y, hero.x) < 25) {
+		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.");
+			monster->t_artifact = monster->t_artifact * 3 / 4;
+		}
+		else  {
+		    msg("A shrill blast sends chills up your spine.");
+		    monster->t_artifact /= 3;
+		}
+	    }
+
+	otherwise:
+	    /* Unknown RELIC! */
+	    debug("Unknown wielded relic %d", obj->o_which);
+    }
+    else debug("Declared relic is %d", obj->o_type);
+
+    turn_off(*monster, CANSURPRISE);
+    /* Reset the monsters actions */
+    monster->t_action = A_NIL;
+    monster->t_using = NULL;
+}
+ 
+/*
+ * 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;
+    register struct object *obj, *tobj;
+    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, FALSE, FALSE);
+		when MM_BOOK:
+		    titem = get_item(pack, "put in", SCROLL, FALSE, FALSE);
+		}
+		if (titem == NULL)
+		    break;
+		detach(pack, titem);
+		inpack--;
+		put_contents(obj, titem);
+	    
+	    when '3':
+		titem = get_item(obj->contents,"take out",ALL,FALSE,FALSE);
+		if (titem == NULL)
+		    break;
+		take_contents(obj, titem);
+		
+	    when '4': 
+		switch (obj->o_which) {
+		case MM_BEAKER: 
+		    titem = get_item(obj->contents,"quaff",ALL,FALSE,FALSE);
+		    if (titem == NULL)
+			break;
+		    tobj = OBJPTR(titem);
+		    obj->o_ac--;
+		    detach(obj->contents, titem);
+		    quaff(tobj->o_which, 
+			  tobj->o_kind,
+			  tobj->o_flags,
+			  TRUE);
+		    if (p_know[tobj->o_which] && p_guess[tobj->o_which])
+		    {
+			free(p_guess[tobj->o_which]);
+			p_guess[tobj->o_which] = NULL;
+		    }
+		    else if (!p_know[tobj->o_which]		&& 
+			     askme				&&
+			     (tobj->o_flags & ISKNOW) == 0	&&
+			     (tobj->o_flags & ISPOST) == 0	&&
+			     p_guess[tobj->o_which] == NULL) {
+			nameitem(titem, FALSE);
+		    }
+		    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,FALSE,FALSE);
+		    if (titem == NULL)
+			break;
+		    tobj = OBJPTR(titem);
+		    obj->o_ac--;
+		    detach(obj->contents, titem);
+		    read_scroll(tobj->o_which, 
+			        tobj->o_flags & (ISCURSED|ISBLESSED),
+				TRUE);
+		    if (s_know[tobj->o_which] && s_guess[tobj->o_which])
+		    {
+			free(s_guess[tobj->o_which]);
+			s_guess[tobj->o_which] = NULL;
+		    }
+		    else if (!s_know[tobj->o_which]		&& 
+			     askme				&&
+			     (tobj->o_flags & ISKNOW) == 0	&&
+			     (tobj->o_flags & ISPOST) == 0	&&
+			     s_guess[tobj->o_which] == NULL) {
+			nameitem(titem, FALSE);
+		    }
+		    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 (' ');
+		clearok(cw, TRUE);
+		touchwin(cw);
+	}
+    }
+}
+
+do_panic(who)
+int who;	/* Kind of monster to panic (all if who is NULL) */
+{
+    register int x,y;
+    register struct linked_list *mon, *item;
+    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);
+
+		    /* Is this the right kind of monster to panic? */
+		    if (who && th->t_index != who) continue;
+
+		    if (who || 
+			(!on(*th, ISUNDEAD) && !save(VS_MAGIC, th, 0) && off(*th, WASTURNED))) {
+			msg("%s %s.", prname(monster_name(th), TRUE),
+			    terse ? "panics" : "turns to run in panic");
+
+			turn_on(*th, ISFLEE);
+			turn_on(*th, WASTURNED);
+			turn_off(*th, CANSURPRISE);
+
+			/* Disrupt what it was doing */
+			dsrpt_monster(th, TRUE, TRUE);
+
+			/* 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);
+
+			/*
+			 * if he has something he might drop it
+			 */
+			if ((item = th->t_pack) != NULL		&& 
+			    (OBJPTR(item))->o_type != RELIC	&& 
+			    rnd(100) < 50) {
+				detach(th->t_pack, item);
+				fall(item, FALSE);
+			}
+
+			/* It is okay to turn tail */
+			th->t_oldpos = th->t_pos;
+		    }
+		    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:
+	    sprintf(buf1, " [%s]", char_class[obj->o_ac].name);
+    }
+    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();
+	    }
+    }
+}
+
+#ifdef PC7300
+static menu_t Display;				/* The menu structure */
+static mitem_t Dispitems[MAXQUILL+1];		/* Info for each line */
+static char Displines[MAXQUILL+1][LINELEN+1];	/* The lines themselves */
+#endif
+/*
+ * try to write a scroll with the quill of Nagrom
+ */
+use_quill(obj)
+struct object *obj;
+{
+    struct linked_list	*item;
+    register int	i,
+			scroll_ability;
+    int			which_scroll,
+			curlen,
+			maxlen,
+			dummy;
+    bool		nohw = FALSE;
+
+    i = which_scroll = 0;
+    scroll_ability = obj->o_charges;
+
+    /* Prompt for scrolls */
+    msg("Which scroll are you writing? (* for list): ");
+
+    which_scroll = (int) (readchar() - 'a');
+    if (which_scroll == (int) ESCAPE - (int) 'a') {
+	mpos = 0;
+	msg("");
+	after = FALSE;
+	return;
+    }
+    if (which_scroll >= 0 && which_scroll < MAXQUILL) nohw = TRUE;
+
+    else if (slow_invent) {
+	register char c;
+
+	nohw = TRUE;
+	do {
+	    for (i=0; i<MAXQUILL; i++) {
+		msg("");
+		mvwaddch(msgw, 0, 0, '[');
+		waddch(msgw, (char) ((int) 'a' + i));
+		waddstr(msgw, "] A scroll of ");
+		waddstr(msgw, s_magic[quill_scrolls[i].s_which].mi_name);
+		waddstr(msgw, morestr);
+	        clearok(msgw, FALSE);
+		draw(msgw);
+		do {
+		    c = readchar();
+		} while (c != ' ' && c != ESCAPE);
+		if (c == ESCAPE)
+		    break;
+	    }
+	    msg("");
+	    mvwaddstr(msgw, 0, 0, "Which scroll are you writing? ");
+	    clearok(msgw, FALSE);
+	    draw(msgw);
+
+	    which_scroll = (int) (readchar() - 'a');
+	} while (which_scroll != (int) (ESCAPE - 'a') &&
+		 (which_scroll < 0 || which_scroll >= MAXQUILL));
+
+	if (which_scroll == (int) (ESCAPE - 'a')) {
+	    mpos = 0;
+	    msg("");
+	    after = FALSE;
+	    return;
+	}
+    }
+    else {
+	/* Now display the possible scrolls */
+	wclear(hw);
+	touchwin(hw);
+	mvwaddstr(hw, 2, 0, "	Cost		Scroll");
+	mvwaddstr(hw, 3, 0,
+		"-----------------------------------------------");
+	maxlen = 47;	/* Maximum width of header */
+
+	for (i=0; i<MAXQUILL; i++) {
+	    wmove(hw, i+4, 0);
+	    sprintf(prbuf, "[%c]	%3d	A scroll of %s",
+		    (char) ((int) 'a' + i),
+		    quill_scrolls[i].s_cost,
+		    s_magic[quill_scrolls[i].s_which].mi_name);
+#ifdef PC7300
+	    /* Put it into the PC menu display */
+	    strcpy(Displines[i], prbuf);
+	    Dispitems[i].mi_name = Displines[i];
+	    Dispitems[i].mi_flags = 0;
+	    Dispitems[i].mi_val = i;
+#endif
+	    waddstr(hw, prbuf);
+
+	    /* Get the length of the line */
+	    getyx(hw, dummy, curlen);
+	    if (maxlen < curlen) maxlen = curlen;
+	}
+
+	sprintf(prbuf, "[Current scroll power = %d]", scroll_ability);
+	mvwaddstr(hw, 0, 0, prbuf);
+	waddstr(hw, " Which scroll are you writing? ");
+	getyx(hw, dummy, curlen);
+	if (maxlen < curlen) maxlen = curlen;
+
+#ifdef PC7300
+	/* Place an end marker for the items */
+	Dispitems[MAXQUILL].mi_name = 0;
+
+	/* Design prompts */
+	sprintf(prbuf, "Current scroll power is %d", scroll_ability);
+
+	/* Set up the main menu structure */
+	Display.m_label = prbuf;
+	Display.m_title = "	Cost		Scroll";
+	Display.m_prompt = "Select a scroll or press Cancl to continue.";
+	Display.m_curptr = '\0';
+	Display.m_markptr = '\0';
+	Display.m_flags = M_ASISTITLE;
+	Display.m_selcnt = 1;
+	Display.m_items = Dispitems;
+	Display.m_curi = 0;
+
+	/*
+	 * Try to display the menu.  If we don't have a local terminal,
+	 * the call will fail and we will just continue with the
+	 * normal mode.
+	 */
+	if (menu(&Display) >= 0) {
+	    if (Display.m_selcnt == 0) {
+		/* Menu was cancelled */
+		after = FALSE;
+		return FALSE;	/* all done if abort */
+	    }
+	    else which_scroll = (int) Display.m_curi->mi_val;
+	    goto got_scroll;
+	}
+#endif
+	/* Should we overlay? */
+	if (menu_overlay && MAXQUILL + 3 < lines / 2) {
+	    over_win(cw, hw, MAXQUILL + 5, maxlen + 3, 0, curlen, NULL);
+	}
+	else draw(hw);
+    }
+
+    if (!nohw) {
+	which_scroll = (int) (readchar() - 'a');
+	while (which_scroll < 0 || which_scroll >= MAXQUILL) {
+	    if (which_scroll == (int) ESCAPE - (int) 'a') {
+		after = FALSE;
+
+		/* Restore the screen */
+		touchwin(cw);
+		if (MAXQUILL + 3 < lines / 2) clearok(cw, FALSE);
+		else {
+		    msg("");
+		    clearok(cw, TRUE);
+		}
+		return;
+	    }
+	    wmove(hw, 0, 0);
+	    wclrtoeol(hw);
+	    waddstr(hw, "Please enter one of the listed scrolls. ");
+	    getyx(hw, dummy, curlen);
+	    if (maxlen < curlen) maxlen = curlen;
+
+	    /* Should we overlay? */
+	    if (menu_overlay && MAXQUILL + 3 < lines / 2) {
+		over_win(cw, hw, MAXQUILL + 5, maxlen + 3,
+			    0, curlen, NULL);
+	    }
+	    else draw(hw);
+
+	    which_scroll = (int) (readchar() - 'a');
+	}
+    }
+
+    /* Now restore the screen if we have to */
+    if (!nohw) {
+	touchwin(cw);
+	if (MAXQUILL + 3 < lines / 2) clearok(cw, FALSE);
+	else {
+	    msg("");
+	    clearok(cw, TRUE);
+	}
+    }
+    else msg("");
+
+
+#ifdef PC7300
+got_scroll:
+#endif
+    /* We've waited our required time. */
+    player.t_using = NULL;
+    player.t_action = A_NIL;
+
+    if (quill_scrolls[which_scroll].s_cost > scroll_ability) {
+	msg("Your attempt fails.");
+	return;
+    }
+
+    obj->o_charges -= quill_scrolls[which_scroll].s_cost;
+    item = spec_item(SCROLL, quill_scrolls[which_scroll].s_which, 0, 0);
+    if (add_pack(item, FALSE, NULL) == FALSE) {
+	(OBJPTR(item))->o_pos = hero;
+	fall(item, TRUE);
+    }
+}
+
+use_mm(which)
+int which;
+{
+    register struct object *obj;
+    register struct linked_list *item;
+    bool cursed, blessed, is_mm;
+
+    cursed = FALSE;
+    is_mm = FALSE;
+
+    if (which < 0) {	/* A real miscellaneous magic item  */
+	/* This is miscellaneous magic.  It takes 3 movement periods to use */
+	if (player.t_action != C_USE) {
+	    int units;	/* Number of movement units for the item */
+
+	    item = get_item(pack, "use", USEABLE, FALSE, FALSE);
+
+	    /*
+	     * Make certain that it is a micellaneous magic item
+	     */
+	    if (item == NULL)
+		return;
+
+	    units = usage_time(item);
+	    if (units < 0) return;
+
+	    player.t_using = item;	/* Remember what it is */
+	    player.t_action = C_USE;	/* We are quaffing */
+	    player.t_no_move = units * movement(&player);
+	    return;
+	}
+
+	/* We have waited our time, let's use the item */
+	item = player.t_using;
+	player.t_using = NULL;
+	player.t_action = A_NIL;
+
+	is_mm = TRUE;
+
+	obj = OBJPTR(item);
+	cursed = (obj->o_flags & ISCURSED) != 0;
+	blessed = (obj->o_flags & ISBLESSED) != 0;
+	which = obj->o_which;
+    }
+
+    if (obj->o_type == POTION) {		/* An potion */
+	is_mm = FALSE;
+	inpack--;
+	detach (pack, item);
+	switch (obj->o_which) {
+	    case P_POISON:
+		if (cur_weapon) {
+		    if (cur_weapon->o_type == RELIC) {
+			msg("The poison burns off %s", 
+			    inv_name(cur_weapon,FALSE));
+		    }
+		    else {
+			cur_weapon->o_flags |= ISPOISON;
+			msg("Your weapon has %s gooey stuff on it",
+			    p_colors[cur_weapon->o_which]);
+		    }
+		}
+		else 
+		    msg("The poison pours on the floor and disappears!");
+	}
+	o_discard(item);
+    }
+    else if (obj->o_type == RELIC) {		/* An artifact */
+	is_mm = FALSE;
+	switch (obj->o_which) {
+	    case EMORI_CLOAK:
+		use_emori();
+	    when QUILL_NAGROM:
+		use_quill(obj);
+	    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(NULL);
+	    when HEIL_ANKH:
+	    case YENDOR_AMULET:
+	    case STONEBONES_AMULET:
+		/* Nothing happens by this mode */
+		msg("Nothing happens.");
+	    when EYE_VECNA:
+		msg("The pain subsides...");
+	    when SURTUR_RING:
+		/* Panic fire giants */
+		do_panic(findmindex("fire giant"));
+	}
+    }
+    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, 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--;
+	    if (food_left >= MORETIME + 5) {
+	        food_left = MORETIME + 5;
+	        msg(terse? "Getting hungry" : "You are starting to get hungry");
+	        hungry_state = F_HUNGRY;
+	    }
+	    aggravate(TRUE, TRUE);
+
+	/*
+	 * 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--;
+	    do_panic(NULL);
+	/*
+	 * 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 (!cur_relic[SURTUR_RING] && !save(VS_POISON, &player, 0)) {
+		msg ("You choke to death!!! --More--");
+		pstats.s_hpt = -1; /* in case he hangs up the phone */
+		wait_for(' ');
+		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...
+	     */
+	    obj->o_charges--;
+	    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--;
+	    changeclass(obj->o_ac);
+
+	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) {
+	nameitem(item, FALSE);
+    }
+    if (item != NULL && which == MM_SKILLS)
+	o_discard(item);
+    updpack(TRUE, &player);
+}
+
+/*
+ * usage_time:
+ *	Return how long it takes to use an item.  For now we only give time
+ *	for MM, RELIC, SCROLL, and POTION items.
+ */
+
+int
+usage_time(item)
+struct linked_list *item;
+{
+    register struct object *obj;
+    register int units = -1;
+
+    obj = OBJPTR(item);
+    switch (obj->o_type) {
+	case SCROLL:	units = 4;
+	when POTION:	units = 3;
+	when RELIC:			/* An artifact */
+	    switch (obj->o_which) {
+		case QUILL_NAGROM:	units = 2;
+		when EMORI_CLOAK:	units = 2;
+		when BRIAN_MANDOLIN:units = 4;
+		when GERYON_HORN:	units = 3;
+		when HEIL_ANKH:
+		case YENDOR_AMULET:
+		case STONEBONES_AMULET:
+				    units = 2;
+		when EYE_VECNA:
+		    /* Do some effects right away! */
+		    units = 6;
+
+		    /* The eye will do nothing other than give a headache */
+		    pstats.s_hpt -= 35;
+		    msg("You feel a sudden shooting pain in your eye!");
+		    if (pstats.s_hpt < 0) {
+			msg ("The pain is too much for you! -- More --");
+			wait_for(' ');
+			death(D_RELIC);
+		    }
+		when SURTUR_RING:
+		    units = 3;
+		    msg("Your nose tickles a bit.");
+	    }
+	when MM:
+	    switch (obj->o_which) {	/* Miscellaneous Magic */
+		case MM_JUG:
+		    if (obj->o_ac == JUG_EMPTY) {
+			msg("The jug is empty");
+			return (-1);
+		    }
+		    units = 3;
+		when MM_BEAKER:
+		case MM_BOOK:
+		    /* This is a strange case because it can go forever */
+		    units = 1;
+		when MM_OPEN:
+		case MM_HUNGER:
+		    /* Chimes */
+		    units = 3;
+		when MM_DRUMS:
+		    units = 3;
+		when MM_DISAPPEAR:
+		case MM_CHOKE:
+		    /* Dust */
+		    units = 3;
+		when MM_KEOGHTOM:
+		    /* Ointment */
+		    if (obj->o_charges <= 0) {
+			msg("The jar is empty!");
+			return (-1);
+		    }
+		    units = 5;
+		when MM_SKILLS:
+		    /* A whole book! */
+		    units = 15;
+		otherwise:
+		    /* What is it? */
+		    units = -1;
+	    }
+	otherwise:	units = -1;
+    }
+
+    return (units);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/monsters.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,827 @@
+/*
+ * monsters.c  -  File with various monster functions in it
+ *
+ * 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.
+ */
+
+/*
+ * File with various monster functions in it
+ *
+ */
+
+#include "curses.h"
+#include "rogue.h"
+#include <ctype.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);
+        turn_off(*tp, DIDHOLD);
+    }
+
+    /* 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);
+	turn_off(*tp, DIDSUFFOCATE);
+    }
+
+    /* 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);
+	carry_obj(tp, monsters[tp->t_index].m_carry/2); /* only half chance */
+
+	/* since it just got here, it is disoriented */
+	tp->t_no_move = 2 * movement(tp);
+
+	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);
+
+	    /* Calculate a movement rate */
+	    mp->t_no_move = movement(mp);
+
+	    /* 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;
+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;
+    char *strchr();
+
+    attach(mlist, item);
+    tp = THINGPTR(item);
+    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_action = A_NIL;
+    tp->t_doorgoal = 0;
+    tp->t_quiet = 0;
+    tp->t_dest = NULL;
+    tp->t_name = NULL;
+    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_lvladj = 0;
+    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;
+    tp->t_stats.s_dext = mp->m_stats.s_dex;
+    tp->t_movement = mp->m_stats.s_move;
+    if (vlevel > HARDER) { /* the deeper, the meaner we get */
+	 tp->t_stats.s_lvl += (vlevel - HARDER);
+	 num_dice += (vlevel - HARDER)/2;
+	 tp->t_stats.s_arm -= (vlevel - HARDER) / 4;
+    }
+    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_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]);
+
+    /*
+     * these are the base chances that a creatures will do something
+     * assuming it can. These are(or can be) modified at runtime
+     * based on what the creature experiences
+     */
+    tp->t_breathe = 75;		/* base chance of breathing */
+    tp->t_artifact = 90;	/* base chance of using artifact */
+    tp->t_summon = 40;		/* base chance of summoning */
+    tp->t_cast = 75;		/* base chance of casting a spell */
+    tp->t_wand = on(*tp, ISUNIQUE) ? 35 : 50;	/* base chance of using wands */
+
+    /* 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 it is 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.
+     * Then fill his pack with his wares.
+     */
+    if (on(*tp, CANSELL)) {	
+	tp->t_stats.s_exp = vlevel * 100;
+	tp->t_stats.s_lvl = vlevel/2 + 1;
+	make_sell_pack(tp);
+    }
+
+    /* 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);
+
+        strncpy(cur->o_damage, "0d0", sizeof(cur->o_damage));  
+	strncpy(cur->o_hurldmg, "0d0", sizeof(cur->o_hurldmg));  
+	strncpy(cur1->o_damage, "0d0", sizeof(cur1->o_damage));  
+	strncpy(cur1->o_hurldmg, "0d0", sizeof(cur1->o_hurldmg));  
+
+	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);
+    }
+
+
+    /* Calculate the initial movement rate */
+    updpack(TRUE, tp);
+    tp->t_no_move = movement(tp);
+
+    if (ISWEARING(R_AGGR))
+	runto(tp, &hero);
+    if (on(*tp, ISDISGUISE))
+    {
+	char mch;
+
+	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) < pstats.s_charisma/4)
+	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, *seller;
+    register struct linked_list *sellpack;
+    register struct object *obj;
+    register int worth, min_worth;
+    char buffer[LINELEN];
+
+
+    /*
+     * Get a linked_list pointer to the seller.  We need this in case
+     * he disappears so we can set monst_dead.
+     */
+    seller = find_mons(tp->t_pos.y, tp->t_pos.x);
+
+    sellpack = tp->t_pack;
+    if (sellpack == NULL) {
+	msg("%s looks puzzled and departs.", prname(monster_name(tp), TRUE));
+
+	/* Get rid of the monster */
+	killed(seller, FALSE, FALSE, FALSE);
+	return;
+    }
+
+    /* See how much the minimum pack item is worth */
+    min_worth = 100000;
+    for (item = sellpack; item != NULL; item = next(item)) {
+	obj = OBJPTR(item);
+	obj->o_flags |= ISPOST;	/* Force a long description of the item */
+	worth = get_worth(obj);
+	if (worth < min_worth) min_worth = worth;
+    }
+
+    /* See if player can afford an item */
+    if (min_worth > purse) {
+	msg("%s eyes your small purse and departs.", 
+	    prname(monster_name(tp), TRUE));
+
+	/* Get rid of the monster */
+	killed(seller, FALSE, FALSE, FALSE);
+	return;
+    }
+
+    /* Announce our intentions */
+    msg("%s opens his pack.--More--", prname(monster_name(tp), TRUE));
+    wait_for(' ');
+
+    /* Try to sell something */
+    sprintf(buffer, "You got %d gold pieces.  Buy", purse);
+    item = get_item(sellpack, buffer, ALL, TRUE, TRUE);
+
+    /* Get rid of the monster */
+    if (item != NULL) detach(tp->t_pack, item);	/* Take it out of the pack */
+    killed(seller, FALSE, FALSE, FALSE);
+
+    if (item == NULL) return;
+
+    /* Can he afford the selected item? */
+    obj = OBJPTR(item);
+
+    worth = get_worth(obj);
+    if (worth > purse) {
+	msg("You cannot afford it.");
+	o_discard(item);
+	return;
+    }
+
+    /* Charge him through the nose */
+    purse -= worth;
+
+    /* If a stick or ring, let player know the type */
+    switch (obj->o_type) {
+	case RING:  r_know[obj->o_which] = TRUE;
+	when POTION:p_know[obj->o_which] = TRUE;
+	when SCROLL:s_know[obj->o_which] = TRUE;
+	when STICK: ws_know[obj->o_which] = TRUE;
+	when MM:    m_know[obj->o_which] = TRUE;
+
+    }
+
+    /* Remove the POST flag that we used for get_item() */
+    obj->o_flags &= ~ISPOST;
+
+    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 char *mname;
+    bool nasty;	/* Will the monster "attack"? */
+
+    if ((it = find_mons(y, x)) == NULL) {
+	msg("Wake:  can't find monster in show (%d, %d)", y, x);
+	return (NULL);
+    }
+    tp = THINGPTR(it);
+    if (on(*tp, ISSTONE)) /* if stoned, don't do anything */
+	return it;
+
+    /*
+     * For now, if we are a friendly monster, we won't do any of
+     * our special effects.
+     */
+    if (on(*tp, ISFRIENDLY)) return it;
+
+    trp = roomin(&tp->t_pos); /* Current room for monster */
+
+    /*
+     * 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 */
+		    runto(tp, &cur->o_pos);
+
+		    /* 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) > 50))	&&
+	(off(player, ISINVIS) || on(*tp, CANSEE))			||
+	(trp != NULL && (trp->r_flags & ISTREAS))) {
+	runto(tp, &hero);
+    }
+
+    /*
+     * Get the name; we don't want to do it until here because we need to
+     * know whether the monster is still sleeping or not.
+     */
+    mname = monster_name(tp);
+
+    /* See if the monster will bother the player */
+    nasty = (on(*tp, ISRUN) && cansee(tp->t_pos.y, tp->t_pos.x));
+
+    /*
+     * if the creature is awake and can see the player and the
+     * player has the dreaded "eye of vecna" then see if the
+     * creature is turned to stone
+     */
+    if (cur_relic[EYE_VECNA] && nasty && off(*tp, NOSTONE) &&
+	(off(player, ISINVIS) || on(*tp, CANSEE))) {
+	turn_on(*tp, NOSTONE);	/* only have to save once */
+	if (!save(VS_PETRIFICATION, tp, -2)) {
+		turn_on(*tp, ISSTONE);
+		turn_off(*tp, ISRUN);
+		turn_off(*tp, ISINVIS);
+		turn_off(*tp, CANSURPRISE);
+		turn_off(*tp, ISDISGUISE);
+		msg("%s is turned to stone!", prname(mname, TRUE));
+		return it;
+	}
+    }
+
+    /* 
+     * 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, HUHDURATION);
+		    else {
+			fuse(unconfuse, 0, HUHDURATION, AFTER);
+			msg("%s's gaze has confused you.",prname(mname, TRUE));
+			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) &&  
+	   player.t_action != A_FREEZE && 
+	   !save(VS_PARALYZATION, &player, 0)) {
+	    if (ISWEARING(R_ALERT))
+		msg("You feel slightly drowsy for a moment.");
+	    else {
+		msg("%s's gaze puts you to sleep.", prname(mname, TRUE));
+		player.t_no_move += movement(&player) * SLEEPTIME;
+		player.t_action = A_FREEZE;
+		if (rnd(100) < 50) turn_off(*tp, CANSNORE);
+	    }
+	}
+
+	/* Fear */
+	if (on(*tp, CANFRIGHTEN) && !on(player, ISFLEE)) {
+	    turn_off(*tp, CANFRIGHTEN);
+	    if (!ISWEARING(R_HEROISM) && 
+		!save(VS_WAND, &player, -(tp->t_stats.s_lvl/10))) {
+		    turn_on(player, ISFLEE);
+		    player.t_dest = &tp->t_pos;
+		    msg("The sight of %s terrifies you.", prname(mname, FALSE));
+	    }
+	}
+
+	/* blinding creatures */
+	if(on(*tp, CANBLIND) && !find_slot(sight)) {
+	    turn_off(*tp, CANBLIND);
+	    if (!save(VS_WAND, &player, 0)) {
+		msg("The gaze of %s blinds you", prname(mname, FALSE));
+		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 %s ages you!", prname(mname, FALSE));
+		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 %s has no effect.", prname(mname, FALSE));
+	    else {
+		if (!save(VS_PETRIFICATION, &player, 0) && rnd(100) < 5) {
+		    pstats.s_hpt = -1;
+		    msg("The gaze of %s petrifies you.", prname(mname, FALSE));
+		    msg("You are turned to stone !!! --More--");
+		    wait_for(' ');
+		    death(D_PETRIFY);
+		}
+		else {
+		    msg("The gaze of %s stiffens your limbs.", 
+			prname(mname, FALSE));
+		    player.t_no_move += movement(&player) * STONETIME;
+		    player.t_action = A_FREEZE;
+		}
+	    }
+	}
+    }
+
+    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 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);
+    runto(tp, &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);
+
+    /* Calculate its movement rate */
+    tp->t_no_move = movement(tp);
+
+    /* Alert the player if a monster just teleported in */
+    if (hr == &rooms[i] && canteleport && seehim && !invisible(tp)) {
+	msg("A %s just teleported in", monster_name(tp));
+	light(&hero);
+	running = FALSE;
+    }
+
+    if (wizard)
+	msg("Started a wandering %s", monster_name(tp));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/move.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,1874 @@
+/*
+ * move.c  -  Hero movement commands
+ *
+ * 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.
+ */
+
+/*
+ * Hero movement commands
+ *
+ */
+
+#include "curses.h"
+#include <ctype.h>
+#include "rogue.h"
+#ifdef PC7300
+#include "menu.h"
+#endif
+
+/*
+ * Used to hold the new hero position
+ */
+
+static coord nh;
+
+static char Moves[3][3] = {
+    { 'y', 'k', 'u' },
+    { 'h', '.', '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, *mname;
+    register bool is_player = (th == &player),
+	          can_see;
+    register struct linked_list *mitem;
+    register struct thing *mp;
+
+
+    /* 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 = monster_name(th);
+    }
+    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("%s fell into a trap!", prname(mname, TRUE));
+
+		/* 
+		 * See if the fall killed the monster 
+		 * don't let a UNIQUE die since it might have an artifact
+		 * that we need
+		 */
+		if (off(*th,ISUNIQUE) && (th->t_stats.s_hpt-=roll(1,10)) <= 0){
+		    killed(mitem, FALSE, 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, ' ');
+
+		    /* let him summon on next lvl */
+		    if (on (*th, HASSUMMONED)) {
+			    turn_off(*th, HASSUMMONED); 
+			    turn_on(*th, CANSUMMON);
+		    }
+		    turn_on(*th,ISELSEWHERE);
+		    detach(mlist, mitem);
+		    attach(tlist, mitem);	/* remember him next level */
+
+		    /* Make sure that no one is still chasing us */
+		    for (mitem = mlist; mitem != NULL; mitem = next(mitem)) {
+			mp = THINGPTR(mitem);
+			if (mp->t_dest == &th->t_pos) {
+			    mp->t_dest = &hero;
+			    mp->t_wasshot = FALSE;
+			    turn_off(*mp, ISFLEE);	/* Don't run away! */
+			}
+		    }
+
+		    /* Make sure we were not chasing a monster here */
+		    th->t_dest = &hero;
+		    if (on(*th, ISFRIENDLY), turn_off(*th, ISFLEE));
+		}
+	    }
+	when BEARTRAP:
+	    if (is_stealth(th)) {
+		if (is_player) msg("You pass a bear trap.");
+		else if (can_see) msg("%s passes a bear trap.", 
+				      prname(mname, TRUE));
+	    }
+	    else {
+		th->t_no_move += movement(&player) * BEARTIME;
+		th->t_action = A_FREEZE;
+		if (is_player) msg("You are caught in a bear trap.");
+		else if (can_see) msg("%s is caught in a bear trap.",
+					prname(mname, TRUE));
+	    }
+	when SLEEPTRAP:
+	    if (is_player) {
+		msg("A strange white mist envelops you.");
+		if (!ISWEARING(R_ALERT)) {
+		    msg("You fall asleep.");
+		    player.t_no_move += movement(&player) * SLEEPTIME;
+		    player.t_action = A_FREEZE;
+		}
+	    }
+	    else {
+		if (can_see) 
+		    msg("A strange white mist envelops %s.",
+			prname(mname, FALSE));
+		if (on(*th, ISUNDEAD)) {
+		    if (can_see) 
+			msg("The mist doesn't seem to affect %s.",
+			   prname(mname, FALSE));
+		}
+		else {
+		    th->t_no_move += movement(th) * SLEEPTIME;
+		    th->t_action = A_FREEZE;
+		}
+	    }
+	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 %s.", prname(mname, FALSE));
+		    if ((th->t_stats.s_hpt -= roll(1, 6)) <= 0) {
+			if (can_see) 
+			    msg("The arrow killed %s.", prname(mname, FALSE));
+			killed(mitem, FALSE, FALSE, TRUE);
+		    }
+		}
+	    }
+	    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 %s.", prname(mname, FALSE));
+		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("%s seems to have disappeared!", prname(mname, TRUE));
+	    }
+	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 %s in the shoulder.",
+				prname(mname, FALSE));
+		    if ((th->t_stats.s_hpt -= roll(1,4)) <= 0) {
+			if (can_see) 
+			    msg("The dart killed %s.", prname(mname, FALSE));
+			killed(mitem, FALSE, FALSE, TRUE);
+		    }
+		    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 %s.", prname(mname,FALSE));
+			    killed(mitem, FALSE, FALSE, TRUE);
+			}
+		    }
+		}
+	    }
+	    else {
+		if (is_player)
+		    msg("A small dart whizzes by your ear and vanishes.");
+		else if (can_see)
+		    msg("A small dart whizzes by %s's ear and vanishes.",
+			prname(mname, FALSE));
+	    }
+        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(' ');
+			death(D_DROWN);
+		    }
+		}
+	    }
+	    else {
+		if (i < 60) {
+		    if (can_see) {
+			/* Drowns */
+			if (i < 30) 
+			    msg("%s drowned in the pool!", prname(mname, TRUE));
+
+			/* Teleported to another level */
+			else msg("%s disappeared!", prname(mname, TRUE));
+		    }
+		    killed(mitem, FALSE, FALSE, TRUE);
+		}
+	    }
+	}
+    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("%s fell into a trap!", prname(mname, TRUE));
+
+	    if (on(*th, ISUNIQUE)) {
+		    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, ' ');
+
+		    /* let him summon on next lvl */
+		    if (on (*th, HASSUMMONED)) {
+			    turn_off(*th, HASSUMMONED); 
+			    turn_on(*th, CANSUMMON);
+		    }
+		    turn_on(*th,ISELSEWHERE);
+		    detach(mlist, mitem);
+		    attach(tlist, mitem);	/* remember him next level */
+
+		    /* Make sure that no one is still chasing us */
+		    for (mitem = mlist; mitem != NULL; mitem = next(mitem)) {
+			mp = THINGPTR(mitem);
+			if (mp->t_dest == &th->t_pos) {
+			    mp->t_dest = &hero;
+			    mp->t_wasshot = FALSE;
+			    turn_off(*mp, ISFLEE);	/* Don't run away! */
+			}
+		    }
+
+		    /* Make sure we were not chasing a monster here */
+		    th->t_dest = &hero;
+		    if (on(*th, ISFRIENDLY), turn_off(*th, ISFLEE));
+	    }
+	    else
+		    killed(mitem, FALSE, FALSE, FALSE);
+	}
+    }
+
+    /* Move the cursor back onto the hero */
+    wmove(cw, hero.y, hero.x);
+
+    md_flushinp();
+    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, locx;	/* 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 been used once already.");
+	    return;
+	}
+
+	/* It takes 3 movement periods to dip something */
+	if (player.t_action != C_DIP) {
+	    if ((what = get_item(pack, "dip", ALL, FALSE, FALSE)) == NULL) {
+		msg("");
+		after = FALSE;
+		return;
+	    }
+
+	    ob = OBJPTR(what);
+	    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]) {
+		mpos = 0;
+		msg("You'll have to take it off first.");
+		return;
+	    }
+
+	    player.t_using = what;	/* Remember what it is */
+	    player.t_action = C_DIP;	/* We are dipping */
+	    player.t_no_move = 3 * movement(&player);
+	    return;
+	}
+
+	/* We have waited our time, let's dip it */
+	what = player.t_using;
+	player.t_using = NULL;
+	player.t_action = A_NIL;
+
+	ob = OBJPTR(what);
+
+	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;
+		        msg("The %s %s glows blue for a moment.",
+			    ws_made[wh],ws_type[wh]);
+		    }
+		    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;
+		        msg("The %s %s glows red for a moment.",
+			    ws_made[wh],ws_type[wh]);
+		    }
+		    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, &player);
+	}
+	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;
+    struct linked_list *item;
+    register struct thing *tp;
+    coord old_hero;
+    register int wasfirstmove, moved, num_hits;
+    bool changed=FALSE;	/* Did we switch places with a friendly monster? */
+
+    wasfirstmove = firstmove;
+    firstmove = FALSE;
+    curprice = -1;		/* if in trading post, we've moved off obj */
+
+    /*
+     * Do a confused move (maybe)
+     */
+    if (player.t_action == A_NIL &&
+	((on(player, ISHUH) && rnd(100) < 80) || 
+	 (on(player, ISDANCE) && rnd(100) < 80) || 
+	 (ISWEARING(R_DELUSION) && rnd(100) < 25)))
+	/* Get a random move */
+	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;
+	player.t_action = A_NIL;
+	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)) {
+			running = FALSE;
+			msg("You are too terrified to move that way");
+			player.t_action = A_NIL;
+			player.t_no_move = movement(&player);
+			return;
+	}
+    }
+
+    /* If we want to move to a monster, see what it is */
+    if (isalpha(ch)) {
+	item = find_mons(nh.y, nh.x);
+	if (item == NULL) {
+	    debug("Cannot find monster in move.");
+	    player.t_action = A_NIL;
+	    return;
+	}
+	tp = THINGPTR(item);
+    }
+
+    /*
+     * Take care of hero being held.  If the player is being held, he
+     * can't move unless he is either attacking a non-friendly monster
+     * or attacking a friendly monster that can't move.
+     */
+    if (on(player, ISHELD) &&
+	(!isalpha(ch) || (on(*tp, ISFRIENDLY) && off(*tp, ISHELD)))) {
+	msg("You are being held.");
+	player.t_action = A_NIL;
+	return;
+    }
+
+    /* See if we have to wait for our movement rate */
+    if (player.t_action == A_NIL) {
+	after = FALSE;
+	firstmove = wasfirstmove;	/* Remember if this is first move */
+	player.t_no_move = movement(&player);
+	if (player.t_ctype == C_MONK)
+	    player.t_no_move -= pstats.s_lvl/6;
+	if (on(player, ISFLY)) 
+	    player.t_no_move /= 2; /* If flying, speed him up */
+
+	if (player.t_no_move < 1) player.t_no_move = 1;
+
+	/* Remember our action */
+	player.t_action = Moves[dy+1][dx+1];
+	return;
+    }
+
+    /* Now let's forget the old move and just do it */
+    player.t_action = A_NIL;
+
+    /* If we're moving onto a friendly monster, let's change places. */
+    if (isalpha(ch) && on(*tp, ISFRIENDLY) && off(*tp, ISHELD)) {
+	coord tpos,	/* Where monster may have been going */
+	      current;	/* Current hero position */
+	int action;	/* The monster's action */
+
+	current = hero;
+	tpos = tp->t_newpos;
+	action = tp->t_action;
+
+	/* Disrupt whatever our friend was doing */
+	tp->t_action = A_NIL;
+
+	/* Tentatively move us to where he is */
+	hero = tp->t_pos;
+
+	/* See if we can move him to where we were */
+	tp->t_newpos = current;
+	do_chase(tp);
+
+	/* Did we succeed? */
+	if (ce(tp->t_pos, current)) {
+	    /* Reset our idea of what ch is */
+	    ch = CCHAR( winat(nh.y, nh.x) );
+
+	    /* Let it be known that we made the switch */
+	    changed = TRUE;
+	    old_hero = current;
+
+	    /* Make the monster think it didn't move */
+	    tp->t_oldpos = current;
+	    tp->t_doorgoal = NULL;
+
+	    /* Let the player know something funny happened. */
+	    msg("What a sidestep!");
+	}
+	else {
+	    /* Restore things -- we couldn't move */
+	    hero = current;
+	    tp->t_newpos = tpos;
+	    tp->t_action = action;
+	}
+    }
+
+    /* 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:
+	case POST:
+	    running = FALSE;
+	    break;
+	default:
+	    break;
+    }
+
+    if (isalpha(ch)) { /* if its a monster then fight it */
+	/*
+	 * If we were running down a corridor and didn't start right
+	 * next to the critter, don't do anything.
+	 */
+	if (running && wasfirstmove == FALSE && roomin(&hero) == NULL) {
+	    struct linked_list *item;
+
+	    item = find_mons(nh.y, nh.x);
+	    if (item != NULL && !invisible(THINGPTR(item))) {
+	        after = running = FALSE;
+	        return;
+	    }
+	}
+
+	/* We have to add time because we're attacking */
+	player.t_no_move = FIGHTBASE;
+	player.t_no_move += weap_move(&player, cur_weapon);
+	if (on(player, ISHASTE))
+		player.t_no_move /= 2;
+	else if (on(player, ISSLOW))
+		player.t_no_move *= 2;
+
+	/* We may attack faster if we're high enough level 
+	 * and the right class
+	 */
+	switch(player.t_ctype) {
+	    case C_FIGHTER: num_hits = player.t_stats.s_lvl/9  + 1;
+	    when C_PALADIN: num_hits = player.t_stats.s_lvl/12 + 1;
+	    when C_RANGER:  num_hits = player.t_stats.s_lvl/13 + 1;
+	    when C_MONK:    if(cur_weapon) num_hits= 1;
+	    		    else	   num_hits= player.t_stats.s_lvl/5 + 1;
+	    otherwise:      num_hits = 1;
+	}
+
+	/*
+	 * The player has already moved the initial movement period.
+	 * Let's add that in, do our division, and then subtract it
+	 * out so that the total time is divided, not just the
+	 * additional attack time.
+	 */
+	moved = movement(&player),
+	player.t_no_move += moved;
+	player.t_no_move /= num_hits;
+	player.t_no_move -= moved;
+	running = FALSE;
+
+	/* Mark that we are attacking and save the attack coordinate */
+	player.t_action = A_ATTACK;
+	player.t_newpos = nh;
+	runch = Moves[dy+1][dx+1];	/* Remember the direction */
+
+	if (player.t_no_move <= 0) after = FALSE;
+	return;
+    }
+
+    /*
+     * if not fighting then move the hero
+     */
+    if (changed == FALSE) {
+	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);
+	if (rp->r_flags & ISTREAS)
+	    wake_room(rp);
+    }
+    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, see_before;
+
+		/* 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 ((int)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);
+}
+
+/*
+ * movement:
+ *	Given a pointer to a player/monster structure, calculate the
+ *	movement rate for that character.
+ */
+
+short
+movement(tp)
+register struct thing *tp;
+{
+    register int result;
+    register int carry;		/* Percentage carried */
+
+    result = 0;
+
+    /* Adjust for armor (player only) */
+    if (tp == &player && cur_armor) {
+	int diff; /* Now armor class differs from normal one of same type */
+
+	/* Blessed armor adds less */
+	diff = cur_armor->o_ac - armors[cur_armor->o_which].a_class;
+	switch (cur_armor->o_which) {
+	    case LEATHER:
+	    case RING_MAIL:
+	    case STUDDED_LEATHER:
+	    case SCALE_MAIL:
+	    case PADDED_ARMOR:
+		diff += 1;
+	    when CHAIN_MAIL:
+	    case SPLINT_MAIL:
+	    case BANDED_MAIL:
+	    case PLATE_MAIL:
+		diff += 2;
+	    when PLATE_ARMOR:
+		diff += 3;
+	    otherwise:
+		debug("forgot an armor in movement()");
+	}
+	if (diff < 0) diff = 0;
+	result += diff;
+
+    }
+
+    /* Adjust for the pack */
+    carry = 100 * tp->t_stats.s_pack / tp->t_stats.s_carry;
+    if (carry > 75) result++;
+
+    /* Get a bonus for dexterity */
+    result -= dext_plus(tp == &player ? dex_compute() : tp->t_stats.s_dext);
+
+    /* only allow adjust for the minus's */
+    if (result < 0) result = 0;
+    result += tp->t_movement; /* now add in movement rate */
+
+    /* Is the character slowed? */
+    if (on(*tp, ISSLOW) || on(*tp, ISDANCE)) result *= 2;
+
+    /* Is the character hasted? */
+    if (on(*tp, ISHASTE)) result /= 2;
+
+    /* We have a minimum of 1 */
+    if (result < 1) result = 1;
+
+    return(result);
+}
+
+/*
+ * 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;
+}
+
+
+
+#define TRAPTYPES 9		/* 9 total trap types that can be set */
+#define WIZARDTRAPS 3		/* Only wizards can set 3 of these */
+
+static char *trap_types[TRAPTYPES] = {
+    "Trap Door",
+    "Bear Trap",
+    "Sleep Trap",
+    "Arrow Trap",
+    "Teleport Trap",
+    "Dart Trap",
+    "Magic pool",
+    "Maze Trap",
+    "Trading Post"
+};
+
+#ifdef PC7300
+#define TRAPWIDTH 13	/* Length of longest named trap from above list */
+#define	TRAPPREFIX 4	/* Length of prefix (eg. "[9] ") */
+static menu_t Display;				/* The menu structure */
+static mitem_t Dispitems[TRAPTYPES+1];		/* Info for each line */
+static char Displines[TRAPTYPES+1][TRAPWIDTH+TRAPPREFIX+1];
+#endif
+
+/*
+ * 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 int selection = rnd(TRAPTYPES-WIZARDTRAPS) + '1';
+    register int i, num_traps;
+    register char ch, och;
+    int thief_bonus = 0;
+    int s_dext;
+
+    if (is_player && player.t_ctype != C_THIEF && player.t_ctype != C_ASSASIN) {
+	msg("Only thieves and assassins can set traps.");
+	return;
+    }
+    switch (och = CCHAR( mvinch(y, x) )) {
+	case WALL:
+	case FLOOR:
+	case PASSAGE:
+	    break;
+	default:
+	    if (is_player) msg("The trap failed!");
+	    return;
+    }
+
+    if (is_player) {
+	int state = 0, /* 0 -> current screen, 1 -> prompt screen, 2 -> done */
+	    units;     /* Number of movement units for the given trap */
+
+	if (player.t_action == C_SETTRAP) {
+	    selection = player.t_selection;
+	    player.t_selection = 0;
+	    player.t_using = NULL;
+	    player.t_action = A_NIL;
+	}
+	else {
+	    msg("Which kind of trap do you wish to set? (* for a list): ");
+	    num_traps = TRAPTYPES - (wizard ? 0 : WIZARDTRAPS);
+	    do {
+		selection = tolower(readchar());
+		switch (selection) {
+		    case '*':
+		      if (state != 1) {
+#ifdef PC7300
+			for (i=0; i<TRAPTYPES; i++) {
+			    /*
+			     * Add numbers so the player can use a
+			     * number later, if he knows it.  Let's
+			     * put the number on here instead of in
+			     * trap_types in case we want to drop it
+			     * later.
+			     */
+			    sprintf(Displines[i], "[%d] %s",
+					i+1, trap_types[i]);
+			    Dispitems[i].mi_name = Displines[i];
+			    Dispitems[i].mi_flags = 0;
+			    Dispitems[i].mi_val = i+'1';
+			}
+
+			/* Place an end marker for the items */
+			Dispitems[num_traps].mi_name = 0;
+
+			/* Set up the main menu structure */
+			Display.m_label = "Trap Creation";
+			Display.m_title = "Trap Types";
+			Display.m_prompt = "Select a trap type or press Cancl.";
+			Display.m_curptr = '\0';
+			Display.m_markptr = '\0';
+			Display.m_flags = 0;
+			Display.m_selcnt = 1;
+			Display.m_items = Dispitems;
+			Display.m_curi = 0;
+
+			/*
+			 * Try to display the menu.  If we don't have a local
+			 * terminal, the call will fail and we will just
+			 * continue with the normal mode.
+			 */
+			if (menu(&Display) >= 0) {
+			    if (Display.m_selcnt == 0) {
+				/* Cancelled menu */
+				msg("");
+
+				trap_tries--;	/* Don't count this one */
+				after = FALSE;
+				return;
+			    }
+			    selection = Display.m_curi->mi_val;
+			    state = 2;
+			    break;
+			}
+#endif
+
+			wclear(hw);
+			touchwin(hw);
+			for (i=0; i<num_traps; i++) {
+			    wmove(hw, i+2, 0);
+			    wprintw(hw, "[%d] %s", i+1, trap_types[i]);
+			}
+			mvwaddstr(hw, 0, 0,
+				"Which kind of trap do you wish to set? ");
+
+			if (menu_overlay)
+			    /*
+			     * Put out the selection.  The longest line is
+			     * the prompt line (39 characters long).
+			     */
+			    over_win(cw, hw, num_traps + 3, 41, 0, 39, NULL);
+			else
+			    draw(hw);
+			state = 1;	/* Now in prompt window */
+		      }
+		      break;
+
+		    case ESCAPE:
+			if (state == 1) {
+			    clearok(cw, FALSE); /* 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, FALSE); /* 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 */
+			    wmove(hw, 0, 0);
+			    wprintw(hw, 
+				"Please enter a selection between 1 and %d:  ",
+				num_traps);
+			    if (menu_overlay)
+				/*
+				 * Put out the selection.  The longest line is
+				 * the prompt line (43 characters long).
+				 */
+				over_win(cw, hw, num_traps+3, 45, 0, 43, NULL);
+			    else 
+				draw(hw);
+			}
+			else {	/* Normal window */
+			    mpos = 0;
+			    msg("Please enter a selection between 1 and %d:  ",
+				num_traps);
+			}
+		}
+	    } while (state != 2);
+
+	    switch ((player.t_selection = selection)) {
+		case '1': units = 20;	/* Trap door */
+		when '2': units = 5;	/* Bear trap */
+		when '3': units = 6;	/* Sleeping gas trap */
+		when '4': units = 5;	/* Arrow trap */
+		when '5': units = 8;	/* Teleport trap */
+		when '6': units = 5;	/* Dart trap */
+		otherwise: units = 10;	/* Unknown trap */
+	    }
+	    player.t_no_move = units * movement(&player);
+	    player.t_action = C_SETTRAP;
+	    player.t_using = NULL;
+	    return;
+	}
+    }
+
+    if (is_player && player.t_ctype == C_THIEF)   thief_bonus = 30;
+    if (is_player && player.t_ctype == C_ASSASIN) thief_bonus = 20;
+
+    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;
+    }
+
+    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("Show:  Can't find monster in show (%d, %d)", y, x);
+	    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;
+}
+
+/*
+ * weap_move:
+ *	Calculate how many segments it will take to swing the given
+ *	weapon (note that the weapon may actually be a stick or
+ *	even something else).
+ */
+
+weap_move(wielder, weap)
+register struct thing *wielder;	/* Who's wielding the weapon */
+register struct object *weap;	/* The weapon */
+{
+    register int weap_rate;
+    int		 dexterity;
+    int		 strength;
+
+    if (weap == NULL) return(1); /* hand, claw, bite attacks are quick */
+
+    switch (weap->o_type) {
+	case STICK:
+	    if (EQUAL(ws_type[weap->o_which], "staff"))
+		weap_rate = 2;
+	    else weap_rate = 1;	/* A wand */
+
+	when WEAPON:
+	    weap_rate = weaps[weap->o_which].w_rate;
+
+	    /* Adjust for blessed or cursed weapon */
+	    if (weap->o_hplus < 0)	/* Cursed */
+		weap_rate -= (weap->o_hplus - 2) / 3;
+	    else if (weap_rate > 0)	/* Blessed */
+		weap_rate -= (2*weap->o_hplus + weap_rate - 1) / weap_rate;
+
+	when RELIC:
+	    switch (weap->o_which) {
+		case MUSTY_DAGGER:
+		case HRUGGEK_MSTAR:
+		case AXE_AKLAD:
+		case YEENOGHU_FLAIL:
+		case MING_STAFF:
+		case ORCUS_WAND:
+		case ASMO_ROD:
+		    /* These operate in the blink of an eye */
+		    weap_rate = 1;
+		otherwise:
+		    /* What is it? */
+		    weap_rate = 10;
+		    debug("unknown weapon in weap_move()");
+	    }
+	otherwise:
+	    /* What is it? */
+	    weap_rate = 10;
+	    debug("unknown weapon in weap_move()");
+    }
+
+    /* Put in a dexterity bonus */
+    if (wielder == &player) dexterity = dex_compute();
+    else dexterity = wielder->t_stats.s_dext;
+    weap_rate -= dext_plus(dexterity) / 2;
+
+    /* Put in a strength bonus */
+    if (wielder == &player) strength = str_compute();
+    else strength = wielder->t_stats.s_str;
+    weap_rate -= str_plus(strength) / 2;
+
+    /* It can't speed you up and it must take SOME time */
+    if (weap_rate <= 0) weap_rate = 1;
+
+    /* Do we need to adjust for fast/slow movement? */
+    if (on(*wielder, ISSLOW) || on(*wielder, ISDANCE)) weap_rate *= 2;
+    if (on(*wielder, ISHASTE)) weap_rate /= 2;
+
+    /* Return the result */
+    return(weap_rate);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/network.h	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,36 @@
+/*
+ * network.h  -  networking setup
+ *
+ * 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.
+ */
+
+/*
+ * Note that networking is set up for machines that can communicate
+ * via some system such as uucp.  The mechanism listed here uses
+ * uux and assumes that the target machine allows access to the
+ * game via the uux command.  NETCOMMAND must be defined if networking
+ * is desired.
+ */
+
+/* #define	NETCOMMAND "uux - -n '%s!%s -u' >/dev/null 2>&1" */
+
+/* Networking information -- should not vary among networking machines */
+#define	SYSLEN 9
+#define	LOGLEN 8
+#undef	NUMNET /* 1 */
+struct network {
+    char *system;
+    char *rogue;
+};
+extern struct network Network[];
+
+/* This system's name -- should not be defined if uname() is available */
+#undef SYSTEM 	/* "ihesa" */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/new_level.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,628 @@
+/*
+ * new_level.c - Dig and draw a new level
+ *
+ * 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.
+ */
+
+#include "curses.h"
+#include "rogue.h"
+#define TERRASAVE 3
+
+/*
+ * new_level:
+ *	Dig and draw a new level
+ *
+ */
+
+new_level(ltype)
+LEVTYPE	ltype;		/* designates type of level to create */
+{
+    register int rm, 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, startx, deltay, deltax;
+    bool fresh=TRUE, vert, top;
+    struct room *rp;
+    struct linked_list *nitem, *savmonst=NULL, *savitems=NULL;
+    coord stairs;
+
+    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;
+		    }
+		}
+
+		/*
+		 * If the monster is busy chasing another monster, don't save
+		 * it
+		 */
+		if (tp->t_dest && tp->t_dest != &hero) 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++)
+	r_free_list(rp->r_exit);	/* Free up the exit lists */
+
+    levtype = ltype;
+    foods_this_level = 0;		/* food for hero this level */
+    if (ltype == POSTLEV || ltype == STARTLEV) {
+	if (ltype == POSTLEV) do_post(FALSE);	/* Trading post */
+	else do_post(TRUE);	/* Equippage */
+	levtype = ltype = POSTLEV;
+    }
+    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 */
+	/* 
+	 * try to find a room for the hero. The objective here is to:
+	 *
+	 * --> don't put him in a treasure room
+	 * --> don't put him on an object 
+	 * --> try not to put him next to the stairs
+	 */
+	cnt = 5000;
+	do {
+	    rm = rnd_room();
+	    if (rooms[rm].r_flags & ISTREAS)
+		continue;
+	    rnd_pos(&rooms[rm], &hero);
+	} until(    cnt-- == 0	||
+		    (winat(hero.y, hero.x) == FLOOR &&
+		     DISTANCE(hero.y, hero.x, stairs.y, stairs.x) > cnt/10));
+    }
+    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(TRUE, TRUE);
+
+    /*
+     * If player is moving up or above his deepest point, wake up any
+     * non-uniques
+     */
+    else if (level < cur_max) aggravate(FALSE, FALSE);
+
+    light(&hero);
+    wmove(cw, hero.y, hero.x);
+    waddch(cw, PLAYER);
+
+    if (level > cur_max)
+	cur_max = level;
+
+    status(TRUE);
+
+    /* Do we sense any food on this level? */
+    if (cur_relic[SURTUR_RING]) quaff(P_FFIND, NULL, NULL, FALSE);
+}
+
+/*
+ * 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, *nextitem, *exitptr;
+    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 
+     */
+    if (ltype != MAZELEV && rnd(HARDER) < level - 10) {	
+	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 = nextitem) {
+	    register struct thing *tp;
+
+	    tp = THINGPTR(item);
+	    nextitem = next(item);
+	    if (rp == roomin(&tp->t_pos)) {
+		/*
+		 * Don't let nice creatures be generated in a treasure
+		 * room.
+		 */
+		if ((player.t_ctype==C_PALADIN || player.t_ctype==C_RANGER) &&
+		    off(*tp, ISMEAN)) {
+		    int index;
+
+		    if (on(*tp, ISUNIQUE)) index = tp->t_index;
+		    else index = -1;
+
+		    /* Get rid of the monster */
+		    killed(item, FALSE, FALSE, FALSE);
+
+		    /* Restore uniques back in the table */
+		    if (index != -1) monsters[index].m_normal = TRUE;
+
+		    continue;
+		}
+		turn_on(*tp, ISMEAN);
+		turn_on(*tp, ISGUARDIAN);
+	    }
+	}
+
+
+	/* 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;
+
+		    /* 
+		     * Put it there and leave it asleep. Wake the monsters
+		     * when the player enters the room. Hopefully, all bases
+		     * are covered as far as the ways to get in. This way
+		     * cpu time is not wasted on the awake monsters that
+		     * can't get to the player anyway.
+		     * try not to put any UNIQUEs in a treasure room.
+		     * note that they may have put put in already by the 
+		     * non-treasure room code.
+		     * also, try not to put ISMEAN monsters in a treasure
+		     * room as these are supposed to be non-hostile until
+		     * attacked. It also makes life simpler for the ranger
+		     * and paladin.
+		     */
+		    while (TRUE) {
+			item = new_item(sizeof *tp); /* Make a monster */
+			tp = THINGPTR(item);
+			new_monster(item,randmonster(FALSE, TRUE),&trp,TRUE);
+			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;
+			}
+			/*
+			 * only picky for these classes
+			 */
+			if (player.t_ctype!=C_RANGER&&player.t_ctype!=C_PALADIN)
+			    break;
+			if (on(*tp, ISMEAN))
+			    break;
+			killed (item, FALSE, FALSE, FALSE);
+		    }
+		    if (on(*tp, ISUNIQUE)) { /* just in case */
+			carry_obj(tp, monsters[tp->t_index].m_carry);
+			tp->t_no_move = movement(tp);
+		    }
+		    turn_on(*tp, ISGUARDIAN);
+
+		}
+
+		/* Treasures */
+		if ((rnd(100) < (MAXTREAS*100)/(width*length)) &&
+		    (mvinch(rp->r_pos.y+j, rp->r_pos.x+i) == FLOOR)) {
+		    item = new_thing(ALL, TRUE);
+		    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
+     * put more things in a maze to entice player to navigate them
+     */
+    for (i = 0; i < MAXOBJ; i++)
+	if (ltype == MAZELEV || rnd(100) < 45) {
+	    /*
+	     * Pick a new object and link it in the list
+	     */
+	    item = new_thing(ALL, TRUE);
+	    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/arogue7/options.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,464 @@
+/*
+ * options.c - This file has all the code for the option command
+ *
+ * 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.
+ */
+
+/*
+ * 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.
+ *
+ */
+
+#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	},
+    {"overlay", "Overlay menu: ",
+		(int *) &menu_overlay,	put_bool,	get_bool	},
+    {"name",	 "Name: ",
+		(int *) whoami,		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 == msgw)
+	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(' ');
+    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[LINELEN];
+
+		    /*
+		     * 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, (char *)value);
+
+		    else if (*op->o_opt == -1) { /* Only init ability once */
+			register int len = strlen(value);
+			register int i;
+
+			if (isupper(value[0])) value[0] = tolower(value[0]);
+			for (i=0; i<NUM_CHARTYPES-1; i++) {
+			    if (EQSTR(value, char_class[i].name, len)) {
+				*op->o_opt = i;
+				break;
+			    }
+			}
+		    }
+		}
+		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;
+{
+    waddstr(win, char_class[*ability].name);
+}
+
+
+/*
+ * 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/arogue7/outside.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,213 @@
+/*
+ * outside.c  -  functions for dealing with the "outside" level
+ *
+ * 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.
+ */
+
+#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;
+{
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/pack.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,1548 @@
+/*
+ * pack.c - Routines to deal with the pack.
+ *
+ * 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.
+ */
+
+#include "curses.h"
+#include <ctype.h>
+#include "rogue.h"
+#ifdef PC7300
+#include "menu.h"
+#endif
+
+/*
+ * Routines to deal with the pack
+ */
+
+/*
+ * 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, *ap;
+    register struct object *obj, *op;
+    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 ");
+	msg("%s (%c)", inv_name(obj, !terse), pack_char(pack, obj));
+    }
+
+    /* Relics can do strange things when you pick them up */
+    if (obj->o_type == RELIC) {
+	switch (obj->o_which) {
+	    /* the ankh of Heil gives you prayers */
+	    case HEIL_ANKH:
+		msg("The ankh welds itself into your hand.");
+		if (player.t_ctype != C_CLERIC && player.t_ctype != C_PALADIN)
+		    fuse(prayer_recovery, 0, SPELLTIME, AFTER);
+
+	    /* 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(' ');
+			death(D_RELIC);
+		    }
+		}
+		if (obj->o_charges < 0) /* should never happen, but.... */
+		    obj->o_charges = 0;
+		if (obj->o_charges == 0)
+			fuse(cloak_charge, obj, CLOAK_TIME, AFTER);
+
+	    /* The amulet must be worn. */
+	    when STONEBONES_AMULET:
+	    case YENDOR_AMULET:
+		if (cur_misc[WEAR_JEWEL]		|| 
+		    cur_relic[STONEBONES_AMULET]	||
+		    cur_relic[YENDOR_AMULET]) {
+		        msg("You have an urge to remove your current amulet.");
+		}
+		if((cur_misc[WEAR_JEWEL] && !dropcheck(cur_misc[WEAR_JEWEL])) ||
+		    cur_relic[STONEBONES_AMULET]			      ||
+		    cur_relic[YENDOR_AMULET]) {
+			pstats.s_hpt = -1;
+			msg("The %s begins pulsing.", inv_name(obj, TRUE));
+			msg("It fades away.... -- More --");
+			wait_for(' ');
+			death(D_RELIC);
+		}
+		msg("The %s welds itself into your chest.",inv_name(obj,TRUE));
+
+	    /* The eye must be inserted in eye socket */
+	    when EYE_VECNA:
+		msg("The eye forces you to jam it into your eye socket!");
+		pstats.s_hpt -= 75;
+		if (pstats.s_hpt < 0) {
+			msg ("The pain is too much for you! -- More --");
+			wait_for(' ');
+			death(D_RELIC);
+		}
+		waste_time();
+		msg("The excrutiating pain slowly turns into a dull throb.");
+		
+	    when QUILL_NAGROM:
+	        fuse(quill_charge,0,player.t_ctype==C_MAGICIAN ? 4 : 8,AFTER);
+
+	    /* Weapons will insist on being wielded. */
+	    when MUSTY_DAGGER:
+	    case HRUGGEK_MSTAR:
+	    case YEENOGHU_FLAIL:
+	    case AXE_AKLAD:
+		/* For the daggers start a fuse to change player to a thief. */
+		/* and set a daemon to eat gold.			     */
+		if (obj->o_which == MUSTY_DAGGER) {
+		    fuse(changeclass, C_THIEF, roll(20, 20), AFTER);
+		    if (purse > 0)
+			msg("Your purse feels lighter");
+		    else
+			purse = 1; /* fudge to get right msg from eat_gold() */
+		    eat_gold(obj);
+		    daemon(eat_gold, obj, AFTER);
+		}
+		/* For the axe start a fuse to change player to a fighter. */
+		if (obj->o_which == AXE_AKLAD)
+		    fuse(changeclass, C_FIGHTER, roll(20, 20), AFTER);
+		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(' ');
+			death(D_RELIC);
+		    }
+		}
+		cur_weapon = obj;
+
+	when SURTUR_RING:
+		msg("The ring forces itself through your nose!");
+		pstats.s_hpt -= 22;
+		if (pstats.s_hpt < 0) {
+			msg ("The pain is too much for you! -- More --");
+			wait_for(' ');
+			death(D_RELIC);
+		}
+		waste_time();
+		turn_on(player, NOFIRE);
+		msg("The pain slowly subsides.");
+	otherwise:
+		break;
+	}
+	cur_relic[obj->o_which]++;	/* Note that we have it */
+    }
+
+    updpack(FALSE, &player);
+    if (packret != NULL)
+	*packret = item;
+    return(TRUE);
+}
+
+#ifdef PC7300
+static menu_t Display;				/* The menu structure */
+static mitem_t Dispitems[MAXPACK+1];		/* Info for each line */
+static char Displines[MAXPACK+1][LINELEN+1];	/* The lines themselves */
+#endif
+
+/*
+ * 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, cnt, maxx, curx;
+    char inv_temp[2*LINELEN+1];
+
+    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');
+
+		    maxx = strlen(inv_temp);	/* Length of the listing */
+
+#ifdef PC7300
+		    /* Put it into the PC menu display */
+		    strcpy(Displines[0], inv_temp);
+		    Dispitems[0].mi_name = Displines[0];
+		    Dispitems[0].mi_flags = 0;
+		    Dispitems[0].mi_val = 0;
+#endif
+		}
+	    /*
+	     * Print the line for this object
+	     */
+	    default:
+		if (ch > 'z')
+		    ch = 'A';
+		if (slow_invent)
+		    msg("%c) %s", ch, inv_name(obj, FALSE));
+		else {
+		    if (++cnt >= lines - 2) { /* if bottom of screen */
+			dbotline(hw, morestr);
+			cnt = 0;
+			wclear(hw);
+		    }
+		    sprintf(inv_temp, "%c) %s\n", ch, inv_name(obj, FALSE));
+		    curx = strlen(inv_temp) - 1; /* Don't count new-line */
+		    if (curx > maxx) maxx = curx;
+		    waddstr(hw, inv_temp);
+#ifdef PC7300
+		    /* Put it into the PC menu display */
+		    strcpy(Displines[n_objs-1], inv_temp);
+		    Displines[n_objs-1][curx] = '\0'; /* Strip newline */
+		    Dispitems[n_objs-1].mi_name = Displines[n_objs-1];
+		    Dispitems[n_objs-1].mi_flags = 0;
+		    Dispitems[n_objs-1].mi_val = 0;
+#endif
+		}
+	}
+    }
+    if (n_objs == 0) {
+	if (terse)
+	    msg(type == ALL ? "Empty handed." :
+			    "Nothing appropriate");
+	else
+	    msg(type == ALL ? "You are empty handed." :
+			    "You don't have anything appropriate");
+	return FALSE;
+    }
+    if (n_objs == 1) {
+	msg(inv_temp);
+	return TRUE;
+    }
+    if (!slow_invent)
+    {
+#ifdef PC7300
+	/* Place an end marker for the items */
+	Dispitems[n_objs].mi_name = 0;
+
+	/* Set up the main menu structure */
+	Display.m_label = "Inventory";
+	Display.m_title = "Pack Contents";
+	Display.m_prompt = "Press Cancl to continue.";
+	Display.m_curptr = '\0';
+	Display.m_markptr = '\0';
+	Display.m_flags = 0;
+	Display.m_selcnt = 0;
+	Display.m_items = Dispitems;
+	Display.m_curi = 0;
+
+	/*
+	 * Try to display the menu.  If we don't have a local terminal,
+	 * the call will fail and we will just continue with the
+	 * normal mode.
+	 */
+	if (menu(&Display) >= 0) return TRUE;
+#endif
+	waddstr(hw, spacemsg);
+	curx = strlen(spacemsg);
+	if (curx > maxx) maxx = curx;
+
+	/*
+	 * If we have fewer than half a screenful, don't clear the screen.
+	 * Leave an extra blank line at the bottom and 3 blank columns
+	 * to he right.
+	 */
+	if (menu_overlay && n_objs < lines / 2 + 2) {
+	    over_win(cw, hw, n_objs + 2, maxx + 3, n_objs, curx, ' ');
+	    return TRUE;
+	}
+
+	draw(hw);
+	wait_for(' ');
+	clearok(cw, TRUE);
+	touchwin(cw);
+    }
+    return TRUE;
+}
+
+/*
+ * 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, FALSE, FALSE) == 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)
+	    {
+		msg("%c) %s",ch,inv_name(OBJPTR(item), FALSE));
+		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, askfirst, showcost)
+reg struct linked_list *list;
+char *purpose;	/* NULL if we should be silent (no prompts) */
+int type;
+bool askfirst, showcost;
+{
+    reg struct linked_list *item;
+    reg struct object *obj;
+    reg int cnt, pagecnt, ch, och, maxx, curx, confused;
+    struct linked_list *saveitem;
+    char description[2*LINELEN+1];
+    char cost[LINELEN/2];
+#ifdef PC7300
+    int menucount = 0;
+    int usemenu = 1;
+#endif
+
+    /*
+     * If this is the player's pack and the player is confused, we
+     * might just take anything.
+     */
+    if (list == player.t_pack && on(player, ISHUH) && rnd(100) < 75)
+	confused = 1;
+    else confused = 0;
+
+    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);
+	while(TRUE)  {
+	    if (purpose) {	/* Should we prompt the player? */
+		msg("%s what (* for the item)?",purpose);
+		ch = tolower(readchar());
+	    }
+	    else {
+		ch = pack_char(list, obj);
+		msg("%c) %s", ch, inv_name(obj,FALSE));
+	    }
+
+	    if (ch == '*') {
+		mpos = 0;
+		msg("%c) %s",pack_char(list, obj),inv_name(obj,FALSE));
+		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);
+
+	} 
+    }
+    while (TRUE) {
+	if (!askfirst && 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);
+	    pagecnt = 0;
+	    maxx = 0;
+	    for(item = list,ch = 'a'; item != NULL ; item = next(item), ch++) {
+		obj = OBJPTR(item);
+		if (!is_type(OBJPTR(item), type))
+		    continue;
+		cost[0] = '\0';
+		if (showcost) {
+		    sprintf(description, "[%d] ", get_worth(obj));
+		    sprintf(cost, "%8.8s", description);
+		}
+		sprintf(description,"%c) %s%s\n\r",ch,cost,inv_name(obj,FALSE));
+		waddstr(hw, description);
+		curx = strlen(description) - 2;	/* Don't count \n or \r */
+		if (maxx < curx) maxx = curx;
+#ifdef PC7300
+		if (usemenu) {
+		    /* Put it into the PC menu display */
+		    strcpy(Displines[menucount], description);
+		    Displines[menucount][curx] = '\0'; /* Strip newline */
+		    Dispitems[menucount].mi_name = Displines[menucount];
+		    Dispitems[menucount].mi_flags = 0;
+		    Dispitems[menucount++].mi_val = (int) item;
+		}
+#endif
+		if (++pagecnt >= lines - 2 && next(item) != NULL) {
+		    pagecnt = 0;
+		    dbotline(hw, spacemsg);
+		    wclear(hw);
+		}
+		if (ch == 'z') ch = 'A' - 1;
+	    }
+
+	    /* Put in the prompt */
+	    if (purpose) sprintf(description, "%s what? ", purpose);
+	    else strcpy(description, spacemsg);
+	    waddstr(hw, description);
+	    curx = strlen(description);
+	    if (maxx < curx) maxx = curx;
+
+#ifdef PC7300
+	    if (usemenu) {
+		/* Place an end marker for the items */
+		Dispitems[menucount].mi_name = 0;
+
+		/* Set up the main menu structure */
+		Display.m_label = "Sub-Inventory";
+		if (purpose) {
+		    Display.m_title = description;
+		    Display.m_prompt =
+			"Select an item or press Cancl for no selection.";
+		    Display.m_selcnt = 1;
+		}
+		else {
+		    Display.m_title = 0;
+		    Display.m_prompt = "Press Cancl to continue.";
+		    Display.m_selcnt = 0;
+		}
+		Display.m_curptr = '\0';
+		Display.m_markptr = '\0';
+		Display.m_flags = 0;
+		Display.m_items = Dispitems;
+		Display.m_curi = 0;
+
+		/*
+		 * Try to display the menu.  If we don't have a local terminal,
+		 * the call will fail and we will just continue with the
+		 * normal mode.
+		 */
+		if (menu(&Display) >= 0) {
+		    msg("");
+		    if (Display.m_selcnt == 0) {
+			/* Menu was cancelled */
+			if (purpose) {
+			    after = FALSE;
+			    return NULL;	/* all done if abort */
+			}
+			else return saveitem;
+		    }
+		    else return (struct linked_list *) Display.m_curi->mi_val;
+		}
+		else {
+		    usemenu = 0;	/* Can't use the menu facilities */
+		}
+	    }
+#endif
+	    /* Write the screen */
+	    if ((menu_overlay && cnt < lines / 2 + 2) || cnt == 1) {
+		over_win(cw, hw, cnt + 2, maxx + 3, cnt, curx, NULL);
+		cnt = -1;	/* Indicate we used over_win */
+	    }
+	    else draw(hw);
+
+	    if (purpose) {
+		do {
+		    ch = tolower(readchar());
+		} until (isalpha(ch) || ch == ESCAPE);
+	    }
+	    else {
+		ch = pack_char(list, OBJPTR(saveitem)); /* Pick a valid item */
+		wait_for(' ');
+	    }
+
+	    /* Redraw original screen */
+	    if (cnt < 0) {
+		clearok(cw, FALSE);	/* Setup to redraw current screen */
+		touchwin(cw);	/* clearing first */
+	    }
+	    else restscr(cw);
+
+	    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 (confused) {
+		/*
+		 * Confused is incremented each time so that if the rnd(cnt)
+		 * clause keeps failing, confused will equal cnt for the
+		 * last item of the correct type and rnd(cnt) < cnt will
+		 * have to be true.
+		 */
+		if (is_type(OBJPTR(item), type) && rnd(cnt) < confused++)
+		    break;
+	    }
+	    else 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 READABLE:
+	    if (obj->o_type == SCROLL ||
+		(obj->o_type == MM && obj->o_which == MM_SKILLS))
+		    return (TRUE);
+	when QUAFFABLE:
+	    if (obj->o_type == POTION ||
+		(obj->o_type == MM && obj->o_which == MM_JUG))
+		    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:
+		    case EMORI_CLOAK:
+			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:		if (!r_know[obj->o_which]) return(TRUE);
+	    when POTION:	if (!p_know[obj->o_which]) return(TRUE);
+	    when STICK:		if (!ws_know[obj->o_which]) return(TRUE);
+	    when SCROLL:	if (!s_know[obj->o_which]) return(TRUE);
+	    when MM:		if (!m_know[obj->o_which]) 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 AXE_AKLAD:
+			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_BEAKER:
+		case MM_BOOK:
+		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 STONEBONES_AMULET:
+		    case GERYON_HORN:
+		    case EYE_VECNA:
+		    case QUILL_NAGROM:
+		    case SURTUR_RING:
+			return (TRUE);
+		}
+	    }
+	    else if (obj->o_type == POTION) {
+		/*
+		 * only assassins can use poison
+		 */
+		if (player.t_ctype == C_ASSASIN && obj->o_which == P_POISON)
+		    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. Note that only UNIQUEs carry relics.
+     */
+    if (on(*mp, ISUNIQUE)) {
+	if (on(*mp, CARRYMDAGGER)) {
+	    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, CARRYYAMULET)) {
+	    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, CARRYBAMULET)) {
+	    item = spec_item(RELIC, STONEBONES_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, CARRYEYE)) {
+	    item = spec_item(RELIC, EYE_VECNA, NULL, NULL);
+	    obj = OBJPTR(item);
+	    obj->o_pos = mp->t_pos;
+	    attach(mp->t_pack, item);
+	}
+	if (on(*mp, CARRYAXE)) {
+	    item = spec_item(RELIC, AXE_AKLAD, NULL, NULL);
+	    obj = OBJPTR(item);
+	    obj->o_pos = mp->t_pos;
+	    attach(mp->t_pack, item);
+	}
+	if (on(*mp, CARRYQUILL)) {
+	    register int i, howmany;
+
+	    item = spec_item(RELIC, QUILL_NAGROM, NULL, NULL);
+	    obj = OBJPTR(item);
+	    obj->o_pos = mp->t_pos;
+	    obj->o_charges = rnd(QUILLCHARGES);
+	    attach(mp->t_pack, item);
+	    howmany = roll(4,3);
+	    for (i=0; i<howmany; i++) {
+		/*
+		 * the quill writes scrolls so give him a bunch
+		 */
+		item = new_thing(TYP_SCROLL, FALSE);
+		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 (on(*mp, CARRYSURTURRING)) {
+	    item = spec_item(RELIC, SURTUR_RING, 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 + (vlevel / 5)) - 2;
+	dam = rnd(5 + (vlevel / 5)) - 2;
+
+	/* Only choose an appropriate type of weapon */
+	switch (rnd(12)) {
+	    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;
+	    when 10:type = DART;
+	    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 dagger, give it one
+     */
+    if (on(*mp, CARRYDAGGER) && rnd(100) < chance) {
+	int hit, dam;
+
+	/* Get the "bonuses" */
+	hit = rnd(3 + (vlevel / 5)) - 1;
+	dam = rnd(3 + (vlevel / 5)) - 1;
+
+	/* Create the item */
+	item = spec_item(WEAPON, DAGGER, 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, TRUE);
+	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, TRUE);
+	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, TRUE);
+	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, TRUE);
+	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, TRUE);
+	obj = OBJPTR(item);
+	obj->o_pos = mp->t_pos;
+	attach(mp->t_pack, item);
+    }
+
+    /* Update the monster's encumberance */
+    updpack(TRUE, mp);
+}
+
+
+/*
+ * 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, pagecnt;
+    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.");
+
+    /* Something or things there */
+    else {
+	char linebuf[2*LINELEN+1];
+	int curlen, maxlen = 0;
+
+	wclear(hw);
+	cnt = 0;
+	pagecnt = 0;
+	for (item = lvl_obj, ch = 'a'; item != NULL && cnt < num_there;
+	     item = next(item), ch++, cnt++) {
+	    obj = OBJPTR(item);
+	    /* Construct how the line will look */
+	    sprintf(linebuf, "%c) %s\n\r", ch, inv_name(obj,FALSE));
+
+	    /* See how long it is */
+	    curlen = strlen(linebuf) - 2; /* Don't count \n or \r */
+	    if (maxlen < curlen) maxlen = curlen;
+
+	    /* Draw it in the window */
+	    waddstr(hw, linebuf);
+
+	    if (++pagecnt >= lines - 2 && next(item) != NULL) {
+		pagecnt = 0;
+		maxlen = 0;
+		dbotline(hw, spacemsg);
+		wclear(hw);
+	    }
+	    if (ch == 'z') ch = 'A' - 1;
+	}
+
+	strcpy(linebuf, "Pick up what? (* for all): ");
+
+	/* See how long it is */
+	curlen = strlen(linebuf); /* Don't count \n or \r */
+	if (maxlen < curlen) maxlen = curlen;
+
+	/* Draw it in the window */
+	waddstr(hw, linebuf);
+
+	/*
+	 * If we have fewer than half a screenful, don't clear the screen.
+	 * Leave an extra blank line at the bottom and 3 blank columns
+	 * to he right.
+	 */
+	if (menu_overlay && num_there < lines / 2 + 2) {
+	  over_win(cw, hw, num_there + 2, maxlen + 3, num_there, curlen, NULL);
+	  pagecnt = -1;	/* Indicate we used over_win */
+	}
+	else draw(hw);		/* write screen */
+
+	for (;;) {
+	    do {
+		ch = tolower(readchar());
+	    } until (isalpha(ch) || ch == '*' || ch == ESCAPE);
+
+	    /* Redraw original screen */
+	    if (pagecnt < 0) {
+		clearok(cw, FALSE);	/* Setup to redraw current screen */
+		touchwin(cw);	/* clearing first */
+	    }
+	    else restscr(cw);
+
+	    if (ch == ESCAPE) {
+		after = FALSE;
+		msg("");		/* clear top line */
+		break;
+	    }
+	    if (ch == '*') {
+		player.t_action = A_PICKUP;
+		return(1); /* set action to PICKUP and delay for first one */
+	    }
+	    /* 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, pagecnt < 0 ? num_there : pagecnt, 25);
+		wprintw(hw, " [between 'a' and '%c']: ",
+		    och == 'A' ? 'z' : och-1);
+		if (maxlen < 49) maxlen = 49;
+
+		/*
+		 * If we have fewer than half a screenful, don't clear the
+		 * screen.  Leave an extra blank line at the bottom and
+		 * 3 blank columns to he right.
+		 */
+		if (menu_overlay && num_there < lines / 2 + 2) {
+		    over_win(cw, hw, num_there + 2, maxlen + 3,
+				num_there, 49, NULL);
+		    cnt = -1;	/* Indicate we used over_win */
+		}
+		else draw(hw);		/* write screen */
+		continue;
+	    }
+	    else {
+		detach(lvl_obj, item);
+		if (add_pack(item, FALSE, NULL)) {
+		    /*
+		     * We make sure here that the dungeon floor gets 
+		     * updated with what's left on the vacated spot.
+		     */
+		    if ((item = find_obj(y, x)) == NULL) {
+			coord roomcoord;	/* Needed to pass to roomin() */
+
+			roomcoord.y = y;
+			roomcoord.x = x;
+			mvaddch(y, x,
+				(roomin(&roomcoord) == NULL ? PASSAGE : FLOOR));
+		    }
+		    else mvaddch(y, x, (OBJPTR(item))->o_type);
+		    return(1);
+		}
+		else attach(lvl_obj, item);	/* Couldn't pick it up! */
+		break;
+	    }
+	}
+    }
+
+    return(0);
+}
+
+/*
+ * make_sell_pack:
+ *
+ *	Create a pack for sellers (a la quartermaster)
+ */
+
+make_sell_pack(tp)
+struct thing *tp;
+{
+    reg struct linked_list *item;
+    reg struct object *obj;
+    reg int sell_type, nitems, i;
+
+    /* Select the items */
+    nitems = rnd(6) + 5;
+
+    switch (rnd(9)) {
+	/* Armor */
+	case 0:
+	case 1:
+	    turn_on(*tp, CARRYARMOR);
+	    sell_type = TYP_ARMOR;
+	    break;
+
+	/* Weapon */
+	case 2:
+	case 3:
+	    turn_on(*tp, CARRYWEAPON);
+	    sell_type = TYP_WEAPON;
+	    break;
+
+	/* Staff or wand */
+	case 4:
+	    turn_on(*tp, CARRYSTICK);
+	    sell_type = TYP_STICK;
+	    break;
+
+	/* Ring */
+	case 5:
+	    turn_on(*tp, CARRYRING);
+	    sell_type = TYP_RING;
+	    break;
+
+	/* scroll */
+	case 6:
+	    turn_on(*tp, CARRYSCROLL);
+	    sell_type = TYP_SCROLL;
+	    break;
+
+	/* potions */
+	case 7:
+	    turn_on(*tp, CARRYPOTION);
+	    sell_type = TYP_POTION;
+	    break;
+
+	/* Miscellaneous magic */ 
+	case 8:
+	    turn_on(*tp, CARRYMISC);
+	    sell_type = TYP_MM;
+	    break;
+    }
+    for (i=0; i<nitems; i++) {
+	item = new_thing(sell_type, FALSE);
+	obj = OBJPTR(item);
+	obj->o_pos = tp->t_pos;
+	attach(tp->t_pack, item);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/passages.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,366 @@
+/*
+ * passages.c  -  Draw the connecting passages
+ *
+ * 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.
+ */
+
+/*
+ * Draw the connecting passages
+ *
+ * @(#)passages.c	3.4 (Berkeley) 6/15/81
+ */
+
+#include "curses.h"
+#include "rogue.h"
+
+/*
+ * do_passages:
+ *	Draw all the passages on a level.
+ */
+
+do_passages()
+{
+    register struct rdes *r1, *r2;
+    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;
+    register char rmt;
+    register int distance, max_diag, offset, i;
+    register int rm;
+    int turns[3], turn_dist[3];
+    register char direc;
+    coord delta, curr, turn_delta, spos, epos;
+
+    if (r1 < r2)
+    {
+	rm = r1;
+	if (r1 + 1 == r2)
+	    direc = 'r';
+	else
+	    direc = 'd';
+    }
+    else
+    {
+	rm = r2;
+	if (r2 + 1 == r1)
+	    direc = 'r';
+	else
+	    direc = 'd';
+    }
+    rpf = &rooms[rm];
+    /*
+     * Set up the movement variables, in two cases:
+     * first drawing one down.
+     */
+    if (direc == 'd')
+    {
+	rmt = rm + 3;				/* room # of dest */
+	rpt = &rooms[rmt];			/* room pointer of dest */
+	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);
+	offset = abs(spos.x - epos.x);	/* how far to turn */
+    }
+    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;
+	offset = abs(spos.y - epos.y);
+    }
+    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('#');
+    }
+
+    /* How far can we move diagonally? */
+    max_diag = min(distance, offset);
+
+    /*
+     * Decide how many turns we will have.
+     */
+    for (i=0; i<3; i++) turn_dist[i] = 0;	/* Init distances */
+    if (max_diag > 0) {
+	int nturns;
+
+	for (i=0, nturns=0; i<3; i++) {
+	    if (rnd(3 - i + nturns) == 0) {
+		nturns++;
+		turns[i] = 0;
+	    }
+	    else turns[i] = -1;
+	}
+    }
+    else {
+	/* Just use a straight line (middle turn) */
+	turns[0] = turns[2] = -1;
+	turns[1] = 0;
+    }
+
+    /*
+     * Now decide how long each turn will be (for those selected above).
+     */
+    while (max_diag > 0) {
+	for (i=0; i<3; i++) {
+	    if (turns[i] >= 0 && max_diag > 0 && rnd(2) == 0) {
+		turn_dist[i]++;
+		max_diag--;
+	    }
+	}
+    }
+    
+    /*
+     * If we have extra offset space, add it to the straight turn.
+     */
+    if (offset > distance) turn_dist[1] += offset - distance;
+
+    /*
+     * Decide where we want to make our turns.
+     * First calculate the offsets, then use those offsets to calculate
+     * the exact position relative to "distance."
+     */
+    turns[0] = rnd(distance - turn_dist[0] - turn_dist[2]);
+    turns[2] = rnd(distance - turn_dist[0] - turn_dist[2] - turns[0]);
+    turns[1] = rnd(distance - turn_dist[0] - turn_dist[2] -
+		   turns[0] - turns[2]);
+
+    turns[0] = distance - turns[0];
+    turns[1] = turns[0] - turn_dist[0] - turns[1];
+    turns[2] = turns[1] - turns[2];
+
+    /*
+     * Get ready to move...
+     */
+    curr.x = spos.x;
+    curr.y = spos.y;
+    while (distance > 0) {
+	/*
+	 * Move to next row/column
+	 */
+	curr.x += delta.x;
+	curr.y += delta.y;
+
+	/*
+	 * Check if we are at a turn place; if so make a turn
+	 */
+	for (i=0; i<3; i++) {
+	    if (distance == turns[i] && turn_dist[i] > 0) {
+		/*
+		 * If this is the start of a straight path,
+		 * we might put in a right-angle turn (33% chance).
+		 */
+		if (i == 1 && rnd(3) == 0) {
+		    cmov(curr);
+		    addch(PASSAGE);
+		}
+
+		/* Now dig the turn */
+		while (turn_dist[i]--) {
+		    curr.x += turn_delta.x;
+		    curr.y += turn_delta.y;
+		    cmov(curr);
+		    addch(PASSAGE);
+		    if (i != 1) {	/* A diagonal */
+			if (--distance > 0) {
+			    curr.x += delta.x;
+			    curr.y += delta.y;
+			}
+		    }
+		}
+	    }
+	}
+
+	if (distance > 0) {
+	    /*
+	     * Dig the passage.
+	     */
+	    cmov(curr);
+	    addch(PASSAGE);
+	    distance--;
+	}
+    }
+    curr.x += delta.x;
+    curr.y += delta.y;
+    if (!ce(curr, epos))
+	msg("Warning, connectivity problem (%d, %d) to (%d, %d).",
+	    curr.y, curr.x, epos.y, epos.x);
+}
+
+/*
+ * 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/arogue7/player.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,812 @@
+/*
+ * player.c  -  This file contains functions for dealing with special player 
+ * abilities
+ *
+ * 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.
+ */
+
+/*
+ * This file contains functions for dealing with special player abilities
+ */
+
+#include <ctype.h>
+#include "curses.h"
+#include "rogue.h"
+#ifdef PC7300
+#include "menu.h"
+#endif
+
+
+/*
+ * affect:
+ *	cleric affecting undead
+ */
+
+affect()
+{
+    register struct linked_list *item;
+    register struct thing *tp;
+    register char *mname;
+    bool see;
+    coord new_pos;
+    int lvl;
+
+    if (!(player.t_ctype == C_CLERIC  ||
+          (player.t_ctype == C_PALADIN && pstats.s_lvl > 4) ||
+	  cur_relic[HEIL_ANKH] != 0)) {
+	msg("You cannot affect undead.");
+	return;
+    }
+
+    new_pos.y = hero.y + player.t_newpos.y;
+    new_pos.x = hero.x + player.t_newpos.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 = monster_name(tp);
+
+    if (on(player, ISINVIS) && off(*tp, CANSEE)) {
+	msg("%s%s cannot see you", see ? "The " : "It",
+	    see ? mname : "");
+	return;
+    }
+
+    if (off(*tp, TURNABLE) || on(*tp, WASTURNED)) 
+	goto annoy;
+    turn_off(*tp, TURNABLE);
+
+    lvl = pstats.s_lvl;
+    if (player.t_ctype == C_PALADIN && cur_relic[HEIL_ANKH] == 0) {
+	lvl -= 4;
+    }
+    /* Can cleric kill it? */
+    if (lvl >= 3 * tp->t_stats.s_lvl) {
+	unsigned long test;	/* For overflow check */
+
+	msg("You have destroyed %s%s.", see ? "the " : "it", see ? mname : "");
+	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, TRUE);
+	check_level();
+	return;
+    }
+
+    /* Can cleric turn it? */
+    if (rnd(100) + 1 >
+	 (100 * ((2 * tp->t_stats.s_lvl) - lvl)) / 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);
+
+	/* Disrupt it */
+	dsrpt_monster(tp, TRUE, TRUE);
+
+	/* Let player know */
+	msg("You have turned %s%s.", see ? "the " : "it", see ? mname : "");
+
+	/* 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();
+
+	/* 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);
+
+	/* It is okay to turn tail */
+	tp->t_oldpos = tp->t_pos;
+
+	return;
+    }
+
+    /* Otherwise -- no go */
+annoy:
+    if (see && tp->t_stats.s_intel > 16)
+	msg("%s laughs at you...", prname(mname, TRUE));
+    else
+	msg("You do not affect %s%s.", see ? "the " : "it", see ? mname : "");
+
+    /* Annoy monster */
+   if (off(*tp, ISFLEE)) runto(tp, &hero);
+}
+
+/*
+ * the magic user is going to try and cast a spell
+ */
+cast()
+{
+    int		spell_ability,
+		which_spell,
+		num_spells;
+
+    if (player.t_ctype != C_MAGICIAN && player.t_ctype != C_RANGER) {
+	msg("You are not permitted to cast spells.");
+	return;
+    }
+    spell_ability = pstats.s_lvl * pstats.s_intel;
+    if (player.t_ctype != C_MAGICIAN)
+	spell_ability /= 3;
+
+    if (player.t_action != C_CAST) {
+	/* 
+	 * Get the number of avilable spells 
+	 */
+	num_spells = 0;
+	if (pstats.s_intel >= 16) 
+	    num_spells += pstats.s_intel - 15;
+	num_spells += pstats.s_lvl;
+	if (player.t_ctype != C_MAGICIAN) 
+	    num_spells /= 3;
+	if (num_spells > MAXSPELLS)	  
+	    num_spells = MAXSPELLS;
+	if (num_spells < 1) {
+	    msg("You are not allowed to cast spells yet.");
+	    return;
+	}
+	if (pick_spell(	magic_spells, 
+			spell_ability, 
+			num_spells, 
+			spell_power,
+			"cast",
+			"spell"))
+	    player.t_action = C_CAST;
+	return;
+    }
+
+    /* We've waited our required casting time. */
+    which_spell = player.t_selection;
+    player.t_selection = 0;
+    player.t_using = NULL;
+    player.t_action = A_NIL;
+
+    if ((spell_power + magic_spells[which_spell].s_cost) > spell_ability) {
+	msg("Your attempt fails.");
+	return;
+    }
+
+    msg("Your spell is successful.");
+
+    if (magic_spells[which_spell].s_type == TYP_POTION)
+        quaff(	magic_spells[which_spell].s_which,
+		NULL,
+        	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 (!player_zap(magic_spells[which_spell].s_which,
+			 magic_spells[which_spell].s_flag)) {
+	     after = FALSE;
+	     return;
+	 }
+    }
+    spell_power += magic_spells[which_spell].s_cost;
+}
+
+/* 
+ * the druid asks his deity for a spell
+ */
+chant()
+{
+    register int	num_chants, 
+			chant_ability, 
+			which_chant;
+
+    which_chant = num_chants = chant_ability = 0;
+
+    if (player.t_ctype != C_DRUID && player.t_ctype != C_RANGER) {
+	msg("You are not permitted to chant.");
+	return;
+    }
+    if (cur_misc[WEAR_CLOAK] != NULL &&
+	cur_misc[WEAR_CLOAK]->o_which == MM_R_POWERLESS) {
+	msg("You can't seem to chant!");
+	return;
+    }
+    chant_ability = pstats.s_lvl * pstats.s_wisdom;
+    if (player.t_ctype != C_DRUID)
+	chant_ability /= 3;
+
+    if (player.t_action != C_CHANT) {
+	num_chants = 0;
+
+	/* Get the number of avilable chants */
+	if (pstats.s_wisdom > 16) 
+	    num_chants = (pstats.s_wisdom - 15) / 2;
+
+	num_chants += pstats.s_lvl;
+
+	if (player.t_ctype != C_DRUID) 
+	    num_chants /= 3;
+
+	if (num_chants > MAXCHANTS) 
+	    num_chants = MAXCHANTS;
+
+	if (num_chants < 1) {
+	    msg("You are not permitted to chant yet.");
+	    return;
+	}
+
+	/* Prompt for chant */
+	if (pick_spell(	druid_spells, 
+			chant_ability, 
+			num_chants, 
+			chant_time,
+			"sing",
+			"chant"))
+	    player.t_action = C_CHANT;
+
+	return;
+    }
+
+    /* We've waited our required chanting time. */
+    which_chant = player.t_selection;
+    player.t_selection = 0;
+    player.t_using = NULL;
+    player.t_action = A_NIL;
+
+    if (druid_spells[which_chant].s_cost + chant_time > chant_ability) {
+	msg("Your chant fails.");
+	return;
+    }
+
+    msg("Your chant has been granted.");
+
+    if (druid_spells[which_chant].s_type == TYP_POTION)
+	quaff(		druid_spells[which_chant].s_which,
+			NULL,
+			druid_spells[which_chant].s_flag,
+			FALSE);
+    else if (druid_spells[which_chant].s_type == TYP_SCROLL)
+	read_scroll(	druid_spells[which_chant].s_which,
+			druid_spells[which_chant].s_flag,
+			FALSE);
+    else if (druid_spells[which_chant].s_type == TYP_STICK) {
+	 if (!player_zap(druid_spells[which_chant].s_which,
+			 druid_spells[which_chant].s_flag)) {
+	     after = FALSE;
+	     return;
+	 }
+    }
+    chant_time += druid_spells[which_chant].s_cost;
+}
+
+/* Constitution bonus */
+
+const_bonus()	/* Hit point adjustment for changing levels */
+{
+    register int bonus;
+    if (pstats.s_const > 6 && pstats.s_const <= 14) 
+	bonus = 0;
+    else if (pstats.s_const > 14) 
+	bonus = pstats.s_const-14;
+    else if (pstats.s_const > 3) 
+	bonus = -1;
+    else
+	bonus = -2;
+    switch(player.t_ctype) {
+	case C_FIGHTER:		bonus = min(bonus, 11);
+	when C_MAGICIAN:	bonus = min(bonus, 4);
+	when C_CLERIC:		bonus = min(bonus, 4);
+	when C_THIEF:		bonus = min(bonus, 4);
+	when C_RANGER:		bonus = min(bonus, 6);
+	when C_PALADIN:		bonus = min(bonus, 8);
+	when C_ASSASIN:		bonus = min(bonus, 4);
+	when C_MONK:		bonus = min(bonus, 6);
+	when C_DRUID:		bonus = min(bonus, 4);
+	otherwise:		bonus = min(bonus, 4);
+    }
+    return(bonus);
+}
+
+
+/* Routines for thieves */
+
+/*
+ * gsense:
+ *	Sense gold
+ */
+
+gsense()
+{
+    /* Only thieves can do this */
+    if (player.t_ctype != C_THIEF && player.t_ctype != C_ASSASIN) {
+	msg("You seem to have no gold sense.");
+	return;
+    }
+
+    read_scroll(S_GFIND, NULL, FALSE);
+}
+
+/* 
+ * the cleric asks his deity for a spell
+ */
+pray()
+{
+    register int	num_prayers, 
+			prayer_ability, 
+			which_prayer;
+
+    which_prayer = num_prayers = prayer_ability =  0;
+
+    if (player.t_ctype != C_CLERIC  && 
+	player.t_ctype != C_PALADIN &&
+	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;
+    }
+
+    prayer_ability = pstats.s_lvl * pstats.s_wisdom;
+    if (player.t_ctype != C_CLERIC)
+	prayer_ability /= 3;
+
+    if (cur_relic[HEIL_ANKH]) prayer_ability *= 2;
+
+    if (player.t_action != C_PRAY) {
+	num_prayers = 0;
+
+	/* Get the number of avilable prayers */
+	if (pstats.s_wisdom > 16) 
+	    num_prayers += (pstats.s_wisdom - 15) / 2;
+
+	num_prayers += pstats.s_lvl;
+	if (cur_relic[HEIL_ANKH]) num_prayers += 3;
+
+	if (player.t_ctype != C_CLERIC) 
+	    num_prayers /= 3;
+
+	if (num_prayers > MAXPRAYERS) 
+	    num_prayers = MAXPRAYERS;
+	if (num_prayers < 1) {
+	    msg("You are not permitted to pray yet.");
+	    return;
+	}
+
+	/* Prompt for prayer */
+	if (pick_spell(	cleric_spells, 
+			prayer_ability, 
+			num_prayers, 
+			pray_time,
+			"offer",
+			"prayer"))
+	    player.t_action = C_PRAY;
+
+	return;
+    }
+
+    /* We've waited our required praying time. */
+    which_prayer = player.t_selection;
+    player.t_selection = 0;
+    player.t_using = NULL;
+    player.t_action = A_NIL;
+
+    if (cleric_spells[which_prayer].s_cost + pray_time > prayer_ability) {
+	msg("Your prayer fails.");
+	return;
+    }
+
+    msg("Your prayer has been granted.");
+
+    if (cleric_spells[which_prayer].s_type == TYP_POTION)
+	quaff(		cleric_spells[which_prayer].s_which,
+			NULL,
+			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 (!player_zap(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 char *mname;
+    coord new_pos;
+    int thief_bonus = -50;
+    bool isinvisible = FALSE;
+
+    if (player.t_ctype != C_THIEF && player.t_ctype != C_ASSASIN) {
+	msg("Only thieves and assassins can steal.");
+	return;
+    }
+    if (on(player, ISBLIND)) {
+	msg("You can't see anything.");
+	return;
+    }
+
+    new_pos.y = hero.y + player.t_newpos.y;
+    new_pos.x = hero.x + player.t_newpos.x;
+
+    /* 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 (on(*tp, ISSTONE)) {
+	msg ("You can't steal from stone!");
+	return;
+    }
+    if (isinvisible = invisible(tp)) mname = "creature";
+    else mname = monster_name(tp);
+
+    /* Can player steal something unnoticed? */
+    if (player.t_ctype == C_THIEF) thief_bonus = 10;
+    if (player.t_ctype == C_ASSASIN) thief_bonus = 0;
+    if (on(*tp, ISUNIQUE)) thief_bonus -= 15;
+    if (isinvisible) thief_bonus -= 20;
+    if (on(*tp, ISINWALL) && off(player, CANINWALL)) thief_bonus -= 50;
+
+    if (on(*tp, ISHELD) || tp->t_action == A_FREEZE ||
+	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 &&
+		pack_ptr != tp->t_using &&  /* Monster can't be using it */
+		rnd(++count) == 0)
+		s_item = pack_ptr;
+
+	/* 
+	 * Find anything?
+	 */
+	if (s_item == NULL) {
+	    msg("%s apparently has nothing to steal.", prname(mname, TRUE));
+	    return;
+	}
+
+	/* Take it from monster */
+	if (tp->t_pack) detach(tp->t_pack, s_item);
+
+	/* Recalculate the monster's encumberance */
+	updpack(TRUE, tp);
+
+	/* 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();
+    }
+
+    else {
+	msg("Your attempt fails.");
+
+	/* Annoy monster (maybe) */
+	if (rnd(35) >= dex_compute() + thief_bonus) {
+	    /*
+	     * If this is a charmed creature, there is a chance it
+	     * will become uncharmed.
+	     */
+	    if (on(*tp, ISCHARMED) && save(VS_MAGIC, tp, 0)) {
+		msg("The eyes of %s turn clear.", prname(mname, FALSE));
+		turn_off(*tp, ISCHARMED);
+	    }
+	    if (on(*tp, CANSELL)) {
+		turn_off(*tp, CANSELL);
+		tp->t_action = A_NIL;
+		tp->t_movement = 0;
+		if (rnd(100) < 50) /* make him steal something */
+		    turn_on(*tp, STEALMAGIC);
+		else
+		    turn_on(*tp, STEALGOLD);
+		if (!isinvisible)
+		    msg("%s looks insulted.", prname(mname, TRUE));
+	    }
+	    runto(tp, &hero);
+	}
+    }
+}
+
+#ifdef PC7300
+/* Use MAXSPELLS or whatever is the biggest number of spells/prayers/etc */
+static menu_t Display;				/* The menu structure */
+static mitem_t Dispitems[MAXSPELLS+1];		/* Info for each line */
+static char Displines[MAXSPELLS+1][LINELEN+1];	/* The lines themselves */
+#endif
+
+/*
+ * this routine lets the player pick the spell that they
+ * want to cast regardless of character class
+ */
+pick_spell(spells, ability, num_spells, power, prompt, type)
+struct spells	spells[];	/* spell list				 */
+int		ability;	/* spell ability			 */
+int		num_spells;	/* number of spells that can be cast	 */
+int		power;		/* spell power				 */
+char		*prompt;	/* prompt for spell list		 */
+char		*type;		/* type of thing--> spell, prayer, chant */
+{
+    bool		nohw = FALSE;
+    register int	i;
+    int			curlen,
+			maxlen,
+			dummy,
+			which_spell,
+			spell_left;
+#ifdef PC7300
+    char label[LINELEN],	/* For menu label */
+	 title[LINELEN];	/* For menu title */
+#endif
+
+    if (cur_misc[WEAR_CLOAK] != NULL &&
+	cur_misc[WEAR_CLOAK]->o_which == MM_R_POWERLESS) {
+	msg("You can't seem to start a %s!", type);
+	return(FALSE);
+    }
+
+    /* Prompt for spells */
+    msg("Which %s are you %sing? (* for list): ", type, prompt);
+
+    which_spell = (int) (readchar() - 'a');
+    msg("");	/* Get rid of the prompt */
+    if (which_spell == (int) ESCAPE - (int) 'a') {
+	after = FALSE;
+	return(FALSE);
+    }
+    if (which_spell >= 0 && which_spell < num_spells) nohw = TRUE;
+
+    else if (slow_invent) {
+	register char c;
+
+	nohw = TRUE;
+	do {
+	    for (i=0; i<num_spells; i++) {
+		msg("");
+		mvwaddch(msgw, 0, 0, '[');
+		waddch(msgw, (char) ((int) 'a' + i));
+		wprintw(msgw, "] A %s of ", type);
+		if (spells[i].s_type == TYP_POTION)
+		    waddstr(msgw, p_magic[spells[i].s_which].mi_name);
+		else if (spells[i].s_type == TYP_SCROLL)
+		    waddstr(msgw, s_magic[spells[i].s_which].mi_name);
+		else if (spells[i].s_type == TYP_STICK)
+		    waddstr(msgw, ws_magic[spells[i].s_which].mi_name);
+		waddstr(msgw, morestr);
+	        wclrtobot(msgw);
+		clearok(msgw, FALSE);
+		draw(msgw);
+		do {
+		    c = readchar();
+		} while (c != ' ' && c != ESCAPE);
+		if (c == ESCAPE)
+		    break;
+	    }
+	    msg("");
+	    wmove(msgw, 0, 0);
+	    wprintw(msgw, "Which %s are you %sing? ", type, prompt);
+	    clearok(msgw, FALSE);
+	    draw(msgw);
+
+	    which_spell = (int) (readchar() - 'a');
+	} while (which_spell != (int) (ESCAPE - 'a') &&
+		 (which_spell < 0 || which_spell >= num_spells));
+
+	if (which_spell == (int) (ESCAPE - 'a')) {
+	    mpos = 0;
+	    msg("");
+	    after = FALSE;
+	    return(FALSE);
+	}
+    }
+    else {
+	/* Now display the possible spells */
+	wclear(hw);
+	touchwin(hw);
+	wmove(hw, 2, 0);
+	*type = toupper(*type);
+	wprintw(hw, "	Cost	%s", type);
+	*type = tolower(*type);
+	mvwaddstr(hw, 3, 0,
+		"-----------------------------------------------");
+	maxlen = 47;	/* Maximum width of header */
+
+	for (i=0; i<num_spells; i++) {
+	    sprintf(prbuf, "[%c]	%3d	A %s of ",
+			(char) ((int) 'a' + i), spells[i].s_cost, type);
+	    if (spells[i].s_type == TYP_POTION)
+		strcat(prbuf, p_magic[spells[i].s_which].mi_name);
+	    else if (spells[i].s_type == TYP_SCROLL)
+		strcat(prbuf, s_magic[spells[i].s_which].mi_name);
+	    else if (spells[i].s_type == TYP_STICK)
+		strcat(prbuf, ws_magic[spells[i].s_which].mi_name);
+	    mvwaddstr(hw, i+4, 0, prbuf);
+
+	    /* Get the length of the line */
+	    getyx(hw, dummy, curlen);
+	    if (maxlen < curlen) maxlen = curlen;
+
+#ifdef PC7300
+	    /* Put it into the PC menu display */
+	    strcpy(Displines[i], prbuf);
+	    Dispitems[i].mi_name = Displines[i];
+	    Dispitems[i].mi_flags = 0;
+	    Dispitems[i].mi_val = i;
+#endif
+	}
+
+	spell_left = ability - power;
+	if (spell_left < 0) {
+	    spell_left = 0;
+	    if (spell_left < -20) power = ability + 20;
+	}
+	sprintf(prbuf, "[Current %s power = %d]", type, spell_left);
+
+	mvwaddstr(hw, 0, 0, prbuf);
+	wprintw(hw, " Which %s are you %sing? ", type, prompt);
+	getyx(hw, dummy, curlen);
+	if (maxlen < curlen) maxlen = curlen;
+
+#ifdef PC7300
+	/* Place an end marker for the items */
+	Dispitems[num_spells].mi_name = 0;
+
+	/* Design prompts */
+	sprintf(label, "Current %s power is %d", type, spell_left);
+	*type = toupper(*type);
+	sprintf(title, "	Cost	%s", type);
+	*type = tolower(*type);
+	sprintf(prbuf, "Select a %s or press Cancl to continue.", type);
+
+	/* Set up the main menu structure */
+	Display.m_label = label;
+	Display.m_title = title;
+	Display.m_prompt = prbuf;
+	Display.m_curptr = '\0';
+	Display.m_markptr = '\0';
+	Display.m_flags = M_ASISTITLE;
+	Display.m_selcnt = 1;
+	Display.m_items = Dispitems;
+	Display.m_curi = 0;
+
+	/*
+	 * Try to display the menu.  If we don't have a local terminal,
+	 * the call will fail and we will just continue with the
+	 * normal mode.
+	 */
+	if (menu(&Display) >= 0) {
+	    if (Display.m_selcnt == 0) {
+		/* Menu was cancelled */
+		after = FALSE;
+		return FALSE;	/* all done if abort */
+	    }
+	    else which_spell = (int) Display.m_curi->mi_val;
+	    goto got_spell;
+	}
+#endif
+	/* Should we overlay? */
+	if (menu_overlay && num_spells + 3 < lines / 2) {
+	    over_win(cw, hw, num_spells + 5, maxlen + 3, 0, curlen, NULL);
+	}
+	else draw(hw);
+    }
+
+    if (!nohw) {
+	which_spell = (int) (readchar() - 'a');
+	while (which_spell < 0 || which_spell >= num_spells) {
+	    if (which_spell == (int) ESCAPE - (int) 'a') {
+		after = FALSE;
+
+		/* Restore the screen */
+		touchwin(cw);
+		if (num_spells + 3 < lines / 2) clearok(cw, FALSE);
+		else clearok(cw, TRUE);
+		return(FALSE);
+	    }
+	    wmove(hw, 0, 0);
+	    wclrtoeol(hw);
+	    wprintw(hw, "Please enter one of the listed %ss. ", type);
+	    getyx(hw, dummy, curlen);
+	    if (maxlen < curlen) maxlen = curlen;
+
+	    /* Should we overlay? */
+	    if (menu_overlay && num_spells + 3 < lines / 2) {
+		over_win(cw, hw, num_spells + 5, maxlen + 3,
+			    0, curlen, NULL);
+	    }
+	    else draw(hw);
+
+	    which_spell = (int) (readchar() - 'a');
+	}
+    }
+
+    /* Now restore the screen if we have to */
+    if (!nohw) {
+	touchwin(cw);
+	if (num_spells + 3 < lines / 2) clearok(cw, FALSE);
+	else clearok(cw, TRUE);
+    }
+
+#ifdef PC7300
+got_spell:
+#endif
+    if (spells[which_spell].s_type == TYP_STICK && 
+	need_dir(STICK, spells[which_spell].s_which)) {
+	    if (!get_dir(&player.t_newpos)) {
+		after = FALSE;
+		return(FALSE);
+	    }
+    }
+    player.t_selection = which_spell;
+    player.t_using = NULL;
+    player.t_no_move = (which_spell/3 + 1) * movement(&player);
+    return(TRUE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/potions.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,980 @@
+/*
+ * potions.c  -  Function(s) for dealing with potions
+ *
+ * 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.
+ */
+
+/*
+ * Function(s) for dealing with potions
+ */
+
+#include "curses.h"
+#include "rogue.h"
+
+
+/*
+ * add_abil is an array of functions used to change attributes.  It must be
+ * ordered according to the attribute definitions in rogue.h.
+ */
+
+void (*add_abil[NUMABILITIES])() = {
+    add_intelligence, add_strength, add_wisdom, add_dexterity,
+    add_constitution, add_charisma
+};
+
+/*
+ * res_abil is an array of functions used to change attributes.  It must be
+ * ordered according to the attribute definitions in rogue.h.
+ */
+
+void (*res_abil[NUMABILITIES])() = {
+    res_intelligence, res_strength, res_wisdom, res_dexterity,
+    res_constitution, res_charisma
+};
+
+/*
+ * Increase player's constitution
+ */
+
+void
+add_constitution(change)
+int change;
+{
+    /* Do the potion */
+    if (change < 0) {
+	msg("You feel less healthy now.");
+	pstats.s_const += change;
+	if (pstats.s_const <= 0)
+	    death(D_CONSTITUTION);
+    }
+    else {
+	msg("You feel healthier now.");
+	pstats.s_const = min(pstats.s_const + change, 25);
+    }
+
+    /* Adjust the maximum */
+    if (max_stats.s_const < pstats.s_const)
+	max_stats.s_const = pstats.s_const;
+}
+
+/*
+ * Increase player's charisma
+ */
+
+void
+add_charisma(change)
+int change;
+{
+    /* Do the potion */
+    if (change < 0) msg("You feel less attractive now.");
+    else msg("You feel more attractive now.");
+
+    pstats.s_charisma += change;
+    if (pstats.s_charisma > 25) pstats.s_charisma = 25;
+    else if (pstats.s_charisma < 3) pstats.s_charisma = 3;
+
+    /* Adjust the maximum */
+    if (max_stats.s_charisma < pstats.s_charisma)
+	max_stats.s_charisma = pstats.s_charisma;
+}
+
+/*
+ * Increase player's dexterity
+ */
+
+void
+add_dexterity(change)
+int change;
+{
+    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 (change < 0) msg("You feel less dextrous now.");
+    else msg("You feel more dextrous now.  Watch those hands!");
+
+    pstats.s_dext += change;
+    if (pstats.s_dext > 25) pstats.s_dext = 25;
+    else if (pstats.s_dext < 3) pstats.s_dext = 3;
+
+    /* 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 (player.t_ctype == C_MONK) { /* monks cannot be slowed or hasted */
+	msg(nothing);
+	return;
+    }
+
+    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.");
+	player.t_no_move += movement(&player) * rnd(hasttime);
+	player.t_action = A_FREEZE;
+	lengthen(nohaste, roll(hasttime,hasttime));
+    }
+    else {
+	msg("You feel yourself moving %sfaster.", blessed ? "much " : "");
+	turn_on(player, ISHASTE);
+	fuse(nohaste, 0, roll(hasttime, hasttime), AFTER);
+    }
+}
+
+/*
+ * Increase player's intelligence
+ */
+void
+add_intelligence(change)
+int change;
+{
+    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 (change < 0) msg("You feel slightly less intelligent now.");
+    else msg("You feel more intelligent now.  What a mind!");
+
+    pstats.s_intel += change;
+    if (pstats.s_intel > 25) pstats.s_intel = 25;
+    else if (pstats.s_intel < 3) pstats.s_intel = 3;
+
+    /* 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()
+{
+    /* monks cannot be slowed or hasted */
+    if (player.t_ctype == C_MONK || ISWEARING(R_FREEDOM)) { 
+	msg(nothing);
+	return;
+    }
+
+    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);
+	    fuse(noslow, 0, roll(HASTETIME,HASTETIME), AFTER);
+	}
+    }
+}
+
+/*
+ * Increase player's strength
+ */
+
+void
+add_strength(change)
+int change;
+{
+
+    if (change < 0) {
+	msg("You feel slightly weaker now.");
+	chg_str(change);
+    }
+    else {
+	msg("You feel stronger now.  What bulging muscles!");
+	chg_str(change);
+    }
+}
+
+/*
+ * Increase player's wisdom
+ */
+
+void
+add_wisdom(change)
+int change;
+{
+    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 (change < 0) msg("You feel slightly less wise now.");
+    else msg("You feel wiser now.  What a sage!");
+
+    pstats.s_wisdom += change;
+    if (pstats.s_wisdom > 25) pstats.s_wisdom = 25;
+    else if (pstats.s_wisdom < 3) pstats.s_wisdom = 3;
+
+    /* 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;
+}
+
+quaff(which, kind, flags, is_potion)
+int which;
+int kind;
+int flags;
+bool is_potion;
+{
+    register struct object *obj;
+    register struct linked_list *item, *titem;
+    register struct thing *th;
+    bool cursed, blessed;
+
+    blessed = FALSE;
+    cursed = FALSE;
+    item = NULL;
+
+    if (which < 0) {	/* figure out which ourselves */
+	/* This is a potion.  */
+	if (player.t_action != C_QUAFF) {
+	    int units;
+
+	    item = get_item(pack, "quaff", QUAFFABLE, FALSE, FALSE);
+
+	    /*
+	     * Make certain that it is somethings that we want to drink
+	     */
+	    if (item == NULL)
+		return;
+
+	    /* How long does it take to quaff? */
+	    units = usage_time(item);
+	    if (units < 0) return;
+
+	    player.t_using = item;	/* Remember what it is */
+	    player.t_no_move = units * movement(&player);
+	    if ((OBJPTR(item))->o_type == POTION) player.t_action = C_QUAFF;
+	    else player.t_action = C_USE;
+	    return;
+	}
+
+	/* We have waited our time, let's quaff the potion */
+	item = player.t_using;
+	player.t_using = NULL;
+	player.t_action = A_NIL;
+
+	obj = OBJPTR(item);
+	/* remove it from the pack */
+	inpack--;
+	detach(pack, item);
+
+	flags = obj->o_flags;
+	which = obj->o_which;
+	kind = obj->o_kind;
+    }
+    cursed = flags & ISCURSED;
+    blessed = flags & ISBLESSED;
+
+    switch(which) {
+	case P_CLEAR:
+	    if (cursed) {
+		confus_player();
+	    }
+	    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) == 0)
+			    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) {
+		msg("You feel worse now.");
+		pstats.s_hpt -= roll(pstats.s_lvl, char_class[player.t_ctype].hit_pts);
+		if (pstats.s_hpt <= 0) 
+		    death(D_POISON);
+	    }
+	    else {
+		if (blessed) {
+		    pstats.s_hpt += roll(pstats.s_lvl+1, char_class[player.t_ctype].hit_pts);
+		    if (pstats.s_hpt > max_stats.s_hpt)
+			pstats.s_hpt = ++max_stats.s_hpt;
+		    if (on(player, ISHUH)) {
+			extinguish(unconfuse);
+			unconfuse();
+		    }
+		}
+		else {
+		    pstats.s_hpt += roll(pstats.s_lvl+1, char_class[player.t_ctype].hit_pts/2);
+		    if (pstats.s_hpt > 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:
+	    /* If it is cursed, we take a point away */
+	    if (cursed) {
+		if (ISWEARING(R_SUSABILITY)) {
+		    msg(nothing);
+		    break;
+		}
+		else add_abil[kind](-1);
+	    }
+
+	    /* Otherwise we add points */
+	    else add_abil[kind](blessed ? 3 : 1);
+
+	    if (is_potion) p_know[P_ABIL] = TRUE;
+	when P_MFIND:
+	    /*
+	     * Potion of monster detection, if there are monters, detect them
+	     */
+	    if (mlist != NULL)
+	    {
+		register struct thing *tp;
+		register struct linked_list *item;
+
+		msg("You begin to sense the presence of monsters.");
+		wclear(hw);
+		for (item=mlist; item!=NULL; item=next(item)) {
+		    tp = THINGPTR(item);
+		    if (on(*tp, NODETECT))
+			continue;
+		    if (off(*tp, ISRUN))/* turn off only on sleeping ones */
+			turn_off(*tp, CANSURPRISE);
+		    mvwaddch(hw, tp->t_pos.y, tp->t_pos.x, 
+			     monsters[tp->t_index].m_appear);
+		}
+		waddstr(msgw, morestr);
+		clearok(msgw, FALSE);
+		draw(msgw);
+		overlay(hw, cw);
+		draw(cw);
+		wait_for(' ');
+		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
+	     */
+	    {
+		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);
+		    }
+		}
+		for (titem = mlist; titem != NULL; titem = next(titem)) {
+		    register struct linked_list *pitem;
+
+		    th = THINGPTR(titem);
+		    if (on(*th, NODETECT)) continue;
+		    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 (show) {
+		    if (is_potion) p_know[P_TFIND] = TRUE;
+		    msg("You sense the presence of magic on this level.");
+		    waddstr(msgw, morestr);
+		    clearok(msgw, FALSE);
+		    draw(msgw);
+		    overlay(hw,cw);
+		    draw(cw);
+		    wait_for(' ');
+		    msg("");
+		    break;
+		}
+		else
+	            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) != 0)
+		    lengthen(unsee, blessed ? SEEDURATION*3 : SEEDURATION);
+		sight();
+	    }
+	when P_PHASE:
+	    if (cursed) {
+		msg("You can't move.");
+		player.t_no_move = movement(&player) * FREEZETIME;
+		player.t_action = A_FREEZE;
+	    }
+	    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) {
+	        if (is_potion) p_know[P_FLY] = TRUE;
+		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();
+		if (blessed) raise_level();
+	    }
+	when P_HASTE:
+	    if (cursed) {	/* Slow player down */
+		add_slow();
+	    }
+	    else {
+		add_haste(blessed);
+	        if (is_potion) p_know[P_HASTE] = TRUE;
+	    }
+	when P_RESTORE: {
+	    register int i, howmuch, strength_tally;
+
+	    msg("Hey, this tastes great.  It make you feel %swarm all over.",
+		blessed ? "really " : "");
+	    howmuch = blessed ? 2 : 1;
+
+	    for (i=0; i<NUMABILITIES; i++) {
+		if (i == A_STRENGTH) {
+		    if (lost_str) {
+			if (lost_str > howmuch) {
+			    lost_str -= howmuch;
+
+			    /*
+			     * Save the lost strength.  We have to set
+			     * temporarilty set it to 0 so that res_strength
+			     * will not restore it.
+			     */
+			    strength_tally = lost_str;
+			    lost_str = 0;
+			    res_strength(howmuch);
+			    lost_str = strength_tally;
+			}
+			else {
+			lost_str = 0;
+			    extinguish(res_strength);
+			    res_strength(howmuch);
+			}
+		    }
+		    else res_strength(howmuch);
+		}
+		else res_abil[i](howmuch);
+	    }
+	}
+	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 */
+	    }
+
+	when P_FFIND:
+	    {
+		register struct linked_list *nitem;
+		register struct object *nobj;
+		bool show;
+
+		show = FALSE;
+		wclear(hw);
+		for (nitem = lvl_obj; nitem != NULL; nitem = next(nitem)) {
+		    nobj = OBJPTR(nitem);
+		    if (nobj->o_type == FOOD) {
+			show = TRUE;
+			mvwaddch(hw, nobj->o_pos.y, nobj->o_pos.x, FOOD);
+		    }
+		}
+		for (nitem = mlist; nitem != NULL; nitem = next(nitem)) {
+		    register struct linked_list *pitem;
+		    register struct thing *th;
+
+		    th = THINGPTR(nitem);
+		    if (on(*th, NODETECT)) continue;
+		    for(pitem = th->t_pack; pitem != NULL; pitem = next(pitem)){
+			nobj = OBJPTR(pitem);
+			if (nobj->o_type == FOOD) {
+			    show = TRUE;
+			    mvwaddch(hw, th->t_pos.y, th->t_pos.x, FOOD);
+			}
+		    }
+		}
+		if (show) {
+		    if (is_potion) p_know[P_FFIND] = TRUE;
+		    msg("Your nose tingles.");
+		    msg("You sense the presence of food on this level.");
+		    waddstr(msgw, morestr);
+		    clearok(msgw, FALSE);
+		    draw(msgw);
+		    overlay(hw,cw);
+		    draw(cw);
+		    wait_for(' ');
+		    msg("");
+		}
+		else
+	            msg("You have a strange feeling for a moment, then it passes.");
+	    }
+
+	when P_SKILL:
+	    if (cursed) {
+		msg("You feel less skillful.");
+
+		/* Does he currently have an artifical skill? */
+		if (!find_slot(unskill)) {	/* No skill */
+		    pstats.s_lvladj = -2;
+		    pstats.s_lvl += pstats.s_lvladj;
+		    fuse(unskill, 0, SKILLDURATION, AFTER);
+		}
+		else {	/* Has an artifical skill */
+		    /* Is the skill beneficial? */
+		    if (pstats.s_lvladj > 0) {
+			/* Decrease the previous skill advantage */
+			pstats.s_lvl -= 2;
+			pstats.s_lvladj -= 2;
+
+			/* If there is now a negative skill, lengthen time */
+			if (pstats.s_lvladj < 0)
+			    lengthen(unskill, SKILLDURATION);
+
+			/* If there is no skill advantage, unfuse us */
+			else if (pstats.s_lvladj == 0) extinguish(unskill);
+		    }
+		    else {	/* Already bad */
+			/* Make it a little worse, and lengthen it */
+			pstats.s_lvl--;
+			pstats.s_lvladj--;
+			lengthen(unskill, SKILLDURATION);
+		    }
+		}
+
+		/* Is our level too low now? */
+		if (pstats.s_lvl < 1) death(D_POTION);
+	    }
+	    else {
+		int adjust;
+
+		msg("You feel more skillful.");
+
+		/* Get the adjustment */
+		adjust = blessed ? 3 : 2;
+
+		/* Does he currently have an artifical skill? */
+		if (!find_slot(unskill)) {
+		    pstats.s_lvladj = adjust;
+		    pstats.s_lvl += pstats.s_lvladj;
+		    fuse(unskill, 0, 
+			 blessed ? SKILLDURATION*2 : SKILLDURATION, AFTER);
+		}
+		else {	/* Has an artifical skill */
+		    /* Is the skill detrimental? */
+		    if (pstats.s_lvladj < 0) {
+			/* Decrease the previous skill advantage */
+			pstats.s_lvl += adjust;
+			pstats.s_lvladj += adjust;
+
+			/* If there is now a positive skill, lengthen time */
+			if (pstats.s_lvladj < 0)
+			    lengthen(unskill, SKILLDURATION);
+
+			/* If there is no skill advantage, unfuse us */
+			else if (pstats.s_lvladj == 0) extinguish(unskill);
+		    }
+		    else {	/* Already good */
+			/*
+			 * Make the skill the maximum of the current good
+			 * skill and what the adjust would give him.
+			 */
+			pstats.s_lvl -= pstats.s_lvladj;
+			pstats.s_lvladj = max(pstats.s_lvladj, adjust);
+			pstats.s_lvl += pstats.s_lvladj;
+			lengthen(unskill,
+				 blessed ? SKILLDURATION*2 : SKILLDURATION);
+		    }
+		}
+	    }
+
+	when P_FIRE: {
+	    int duration;
+	    bool say_message;
+
+	    say_message = TRUE;
+
+	    if (blessed) duration = 3;
+	    else duration = 1;
+
+	    if (on(player, NOFIRE)) {
+		if (find_slot(nofire))
+		    lengthen(nofire, duration*FIRETIME);
+		else {
+		    msg("Nothing happens.");	/* has on a ring */
+		    say_message = FALSE;
+		}
+	    }
+	    else {
+		fuse(nofire, 0, duration*FIRETIME, AFTER);
+		turn_on(player, NOFIRE);
+	    }
+	    if (say_message)  {
+	        if (is_potion) p_know[P_FIRE] = TRUE;
+		msg("You feel %sfire resistant", blessed ? "very " : "");
+	    }
+	}
+	when P_COLD: {
+	    int duration;
+	    bool say_message;
+
+	    say_message = TRUE;
+
+	    if (blessed) duration = 3;
+	    else duration = 1;
+
+	    if (on(player, NOCOLD)) {
+		if (find_slot(nocold))
+		    lengthen(nocold, duration*COLDTIME);
+		else {
+		    msg("Nothing happens.");	/* has on a ring */
+		    say_message = FALSE;
+		}
+	    }
+	    else {
+		fuse(nocold, 0, duration*COLDTIME, AFTER);
+		turn_on(player, NOCOLD);
+	    }
+	    if (say_message)  {
+	        if (is_potion) p_know[P_COLD] = TRUE;
+		msg("You feel %scold resistant", blessed ? "very " : "");
+	    }
+	}
+	when P_LIGHTNING: {
+	    int duration;
+	    bool say_message;
+
+	    say_message = TRUE;
+
+	    if (blessed) duration = 3;
+	    else duration = 1;
+
+	    if (on(player, NOBOLT)) {
+		if (find_slot(nobolt))
+		    lengthen(nobolt, duration*BOLTTIME);
+	    }
+	    else {
+		fuse(nobolt, 0, duration*BOLTTIME, AFTER);
+		turn_on(player, NOBOLT);
+	    }
+	    if (say_message) 
+		msg("Your skin turns %sblue!", blessed ? "very " : "");
+	}
+	when P_POISON:
+	    if (!save(VS_POISON, &player, -2)) {
+		msg("You feel very sick now.");
+		pstats.s_hpt /= 2;
+		if (!ISWEARING(R_SUSABILITY))
+		    pstats.s_const--;
+	    }
+	    else {
+		msg("You feel sick now.");
+		pstats.s_hpt -= (pstats.s_hpt / 4);
+	    }
+	    if (pstats.s_const <= 0 || pstats.s_hpt <= 0) 
+		death(D_POISON);
+	otherwise:
+	    msg("What an odd tasting potion!");
+	    return;
+    }
+    status(FALSE);
+    if (is_potion && item && p_know[which] && p_guess[which])
+    {
+	free(p_guess[which]);
+	p_guess[which] = NULL;
+    }
+    else if (is_potion			&& 
+	     !p_know[which]		&& 
+	     item			&&
+	     askme			&&
+	     (flags & ISKNOW) == 0	&&
+	     (flags & ISPOST) == 0	&&
+	     p_guess[which] == NULL) {
+	nameitem(item, FALSE);
+    }
+    if (item != NULL) o_discard(item);
+    updpack(TRUE, &player);
+}
+
+
+/*
+ * res_dexterity:
+ *	Restore player's dexterity
+ *	if called with zero the restore fully
+ */
+
+void
+res_dexterity(howmuch)
+int howmuch;
+{
+    short save_max;
+    int ring_str;
+
+    if (howmuch < 0) return;
+
+    /* 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
+ */
+
+void
+res_intelligence(howmuch)
+int howmuch;
+{
+    short save_max;
+    int ring_str;
+
+    if (howmuch <= 0) return;
+
+    /* Discount the ring value */
+    ring_str = ring_value(R_ADDINTEL);
+    pstats.s_intel -= ring_str;
+
+    pstats.s_intel = min(pstats.s_intel + howmuch, 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
+ */
+
+void
+res_wisdom(howmuch)
+int howmuch;
+{
+    short save_max;
+    int ring_str;
+
+    if (howmuch <= 0) return;
+
+    /* Discount the ring value */
+    ring_str = ring_value(R_ADDWISDOM);
+    pstats.s_wisdom -= ring_str;
+
+    pstats.s_wisdom = min(pstats.s_wisdom + howmuch, 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;
+    }
+}
+
+/*
+ * res_constitution:
+ *	Restore the players constitution.
+ */
+
+void
+res_constitution(howmuch)
+int howmuch;
+{
+    if (howmuch > 0)
+	pstats.s_const = min(pstats.s_const + howmuch, max_stats.s_const);
+}
+
+/*
+ * res_charisma:
+ *	Restore the players charisma.
+ */
+
+void
+res_charisma(howmuch)
+int howmuch;
+{
+    if (howmuch > 0)
+	pstats.s_charisma =
+	    min(pstats.s_charisma + howmuch, max_stats.s_charisma);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/rings.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,161 @@
+/*
+ * rings.c  -  routines dealing specifically with rings
+ * 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.
+ */
+
+#include "curses.h"
+#include "rogue.h"
+
+/*
+ * routines dealing specifically with rings
+ */
+
+
+/*
+ * 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(item)
+register struct linked_list *item;
+{
+    register struct object *obj;
+    register int save_max;
+
+    obj = OBJPTR(item);
+
+    /*
+     * 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(TRUE, TRUE);
+	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) {
+	nameitem(item, FALSE);
+    }
+}
+
+/*
+ * 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_CARRY:
+	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/arogue7/rip.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,889 @@
+/*
+ * rip.c - File for the fun ends Death or a total win
+ *
+ * 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.
+ */
+
+/* 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 */
+
+#define NAMELEN	80
+
+/*
+ * File for the fun ends
+ * Death or a total win
+ *
+ */
+
+#include "curses.h"
+#ifdef BSD
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#include <signal.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include "mach_dep.h"
+#include "network.h"
+#include "rogue.h"
+#ifdef PC7300
+#include "sys/window.h"
+extern struct uwdata wdata, oldwin;
+extern char oldtext[WTXTNUM][WTXTLEN];
+#endif
+
+#ifdef NUMNET
+/* Network machines (for mutual score keeping) */
+static struct network Network[NUMNET] = {
+    { "ihwpt", "/t1/michael/bin/rg" },
+};
+#endif
+
+/*
+ * 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[NAMELEN];
+    char	sc_system[SYSLEN];
+    char	sc_login[LOGLEN];
+    short	sc_flags;
+    short	sc_level;
+    short	sc_ctype;
+    short	sc_monster;
+    short	sc_quest;
+};
+#define SCORELEN \
+    (sizeof(unsigned long) + NAMELEN + SYSLEN + LOGLEN + 5*sizeof(short))
+
+static char *rip[] = {
+"                       __________",
+"                      /          \\",
+"                     /    REST    \\",
+"                    /      IN      \\",
+"                   /     PEACE      \\",
+"                  /                  \\",
+"                  |                  |",
+"                  |                  |",
+"                  |    killed by     |",
+"                  |                  |",
+"                  |       1984       |",
+"                 *|     *  *  *      | *",
+"         ________)/\\\\_//(\\/(/\\)/\\//\\/|_)_______",
+    0
+};
+
+char	*killname();
+
+
+
+
+
+void
+byebye(sig)
+int sig;
+{
+    if (!isendwin()) {
+        clear();
+	endwin();
+    }
+#ifdef PC7300
+    endhardwin();
+#endif
+    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[LINELEN];
+    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);
+    endwin();
+#ifdef PC7300
+    endhardwin();
+#endif
+    exit(0);
+}
+
+#ifdef PC7300
+/*
+ * Restore window characteristics on a hard window terminal (PC7300).
+ */
+endhardwin()
+{
+    register int i;
+    struct utdata labelbuf;
+
+    /* Restore the old window size */
+    if (oldwin.uw_width) ioctl(1, WIOCSETD, &oldwin);
+
+    /* Restore the old window text */
+    for (i=0; i<WTXTNUM; i++) {
+	labelbuf.ut_num = i;
+	strcpy(labelbuf.ut_text, oldtext[i]);
+	ioctl(1, WIOCSETTEXT, &labelbuf);
+    }
+}
+#endif
+
+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 int outfd;
+    register char *killer;
+    register int prflags = 0;
+    register int fd;
+    short upquest, wintype, uplevel, uptype;	/* 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 */
+    char scoreline[100];
+#define REASONLEN 3
+    static char *reason[] = {
+	"killed",
+	"quit",
+	"A total winner",
+	"somehow left",
+    };
+    char *packend;
+
+    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();
+	    getstr(prbuf);
+	}
+	 showpack(packend);
+    }
+    purse = 0;	/* Steal all the gold */
+
+    /*
+     * Open file and read list
+     */
+
+    if ((fd = open(score_file, O_RDWR | O_CREAT, 0666)) < 0) return;
+    outfd = fd;
+
+#ifndef SYSTEM
+    thissys = md_gethostname();
+#else
+    thissys = SYSTEM;
+#endif
+
+    for (scp = top_ten; scp <= &top_ten[NUMSCORE-1]; scp++)
+    {
+	scp->sc_score = 0L;
+	for (i = 0; i < NAMELEN; i++)
+	    scp->sc_name[i] = rnd(255);
+	scp->sc_quest= RN;
+	scp->sc_flags = 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);
+	getstr(prbuf);
+    }
+
+    /* 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 */
+    for(i = 0; i < NUMSCORE; i++)
+    {
+	encread(top_ten[i].sc_name, NAMELEN, fd);
+	encread(top_ten[i].sc_system, SYSLEN, fd);
+	encread(top_ten[i].sc_login, LOGLEN, fd);
+	encread(scoreline, 100, fd);
+	sscanf(scoreline, " %lu %hd %hd %hd %hd %hd \n",
+	    &top_ten[i].sc_score, &top_ten[i].sc_flags, 
+	    &top_ten[i].sc_level, &top_ten[i].sc_ctype,
+	    &top_ten[i].sc_monster, &top_ten[i].sc_quest
+	    );
+    }
+
+    /* Get some values if this is an update */
+    if (flags == UPDATE) {
+	unsigned long netread();
+	int errcheck, errors = 0;
+
+	upquest = (short) netread(&errcheck, sizeof(short), stdin);
+	if (errcheck) errors++;
+
+	if (fread(whoami, 1, NAMELEN, stdin) != NAMELEN) 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) {
+	    close(outfd);
+	    free(compatstr);
+	    return;
+	}
+    }
+
+    /*
+     * Insert player in list if need be
+     */
+    if (!waswizard) {
+	char *login;
+
+	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[LINELEN];
+
+		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, NAMELEN);
+
+		/* 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);
+		for (i=0; i<NUM_CHARTYPES; i++) {
+		    if (EQSTR(buffer, char_class[i].name, strlen(buffer)))
+			break;
+		}
+		player.t_ctype = i;
+
+		/* 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')
+			do {
+			    monst = makemonster(TRUE, "Editing", "choose");
+			} while (monst < 0); /* Force a choice */
+		    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, NETCOMMAND,
+				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<NAMELEN; 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++) {
+	    const char *class;
+
+	    if (scp->sc_score != 0) {
+		class = char_class[scp->sc_ctype].name;
+
+		/* Make sure we have an in-bound reason */
+		if (scp->sc_flags > REASONLEN) scp->sc_flags = 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_flags],
+			    scp->sc_level);
+
+		switch (scp->sc_flags) {
+		    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);
+		    getstr(prbuf);
+		    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 < NAMELEN; i++)
+			    top_ten[NUMSCORE-1].sc_name[i] = rnd(255);
+			top_ten[NUMSCORE-1].sc_flags = RN;
+			    top_ten[NUMSCORE-1].sc_level = RN;
+			    top_ten[NUMSCORE-1].sc_monster = RN;
+			    scp--;
+		    }
+		    else if (prbuf[0] == 'e') {
+			printf("Death type: ");
+			getstr(prbuf);
+			if (prbuf[0] == 'M' || prbuf[0] == 'm')
+			    do {
+			        scp->sc_monster =
+				    makemonster(TRUE, "Editing", "choose");
+			    } while (scp->sc_monster < 0); /* Force a choice */
+			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 */
+    }
+    lseek(outfd, 0L, 0);
+    /*
+     * Update the list file
+     */
+
+    for(i = 0; i < NUMSCORE; i++)
+    {
+          memset(scoreline,0,100);
+          encwrite(top_ten[i].sc_name, NAMELEN, outfd);
+          encwrite(top_ten[i].sc_system, SYSLEN, outfd);
+          encwrite(top_ten[i].sc_login, LOGLEN, outfd);
+          sprintf(scoreline, " %lu %hd %hd %hd %hd %hd \n",
+              top_ten[i].sc_score, top_ten[i].sc_flags, 
+	      top_ten[i].sc_level, top_ten[i].sc_ctype,
+	      top_ten[i].sc_monster, top_ten[i].sc_quest);
+          encwrite(scoreline,100,outfd);
+    }
+
+    close(outfd);
+}
+
+/*
+ * scorein:
+ *	Convert a character string that has been translated from a
+ * score file by scoreout() back to a score file structure.
+ */
+scorein(input, scores, num_bytes)
+unsigned char *input;
+struct sc_ent scores[];
+int num_bytes;	/* Number of bytes of input that we want to convert */
+{
+    register int i, j;
+    unsigned long *lptr;
+    unsigned short *sptr;
+    unsigned char *cptr;
+
+    /* Convert a maximum of NUMSCORE entries */
+    for (i=0; num_bytes > 0 && i < NUMSCORE; num_bytes -= SCORELEN, i++) {
+	/* The long fields are first -- ordered low to high byte in input */
+	lptr = &scores[i].sc_score;
+	*lptr  = ((unsigned long) *input++) & 0x000000ffL;
+	*lptr |= (((unsigned long) *input++) << 8) & 0x0000ff00L;
+	*lptr |= (((unsigned long) *input++) << 16) & 0x00ff0000L;
+	*lptr |= (((unsigned long) *input++) << 24) & 0xff000000L;
+
+	/* The short fields are next -- ordered low to high byte in input */
+	sptr = (unsigned short *) &scores[i].sc_flags;
+	*sptr = ((unsigned short) *input++) & 0xff;
+	*sptr |= (((unsigned short) *input++) << 8) & 0xff00;
+
+	sptr = (unsigned short *) &scores[i].sc_level;
+	*sptr = ((unsigned short) *input++) & 0xff;
+	*sptr |= (((unsigned short) *input++) << 8) & 0xff00;
+
+	sptr = (unsigned short *) &scores[i].sc_ctype;
+	*sptr = ((unsigned short) *input++) & 0xff;
+	*sptr |= (((unsigned short) *input++) << 8) & 0xff00;
+
+	sptr = (unsigned short *) &scores[i].sc_monster;
+	*sptr = ((unsigned short) *input++) & 0xff;
+	*sptr |= (((unsigned short) *input++) << 8) & 0xff00;
+
+	sptr = (unsigned short *) &scores[i].sc_quest;
+	*sptr = ((unsigned short) *input++) & 0xff;
+	*sptr |= (((unsigned short) *input++) << 8) & 0xff00;
+
+	/* Finally comes the char fields -- they're easy */
+	cptr = (unsigned char *) scores[i].sc_name;
+	for (j = 0; j < NAMELEN; j++) *cptr++ = *input++;
+
+	cptr = (unsigned char *) scores[i].sc_system;
+	for (j = 0; j < SYSLEN; j++) *cptr++ = *input++;
+
+	cptr = (unsigned char *) scores[i].sc_login;
+	for (j = 0; j < LOGLEN; j++) *cptr++ = *input++;
+    }
+}
+
+/*
+ * 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, output)
+struct sc_ent scores[];
+unsigned char *output;
+{
+    register int i, j;
+    unsigned long *lptr;
+    unsigned short *sptr;
+    unsigned char *cptr;
+
+    for (i=0; i<NUMSCORE; i++) {
+	/* The long fields are first -- ordered low to high byte in input */
+	lptr = &scores[i].sc_score;
+	for (j = 0; j < sizeof(unsigned long); j++)
+	    *output++ = (unsigned char) ((*lptr >> 8*j) & 0xff);
+
+	/* The short fields are next -- ordered low to high byte in input */
+	sptr = (unsigned short *) &scores[i].sc_flags;
+	*output++ = (unsigned char) (*sptr & 0xff);
+	*output++ = (unsigned char) ((*sptr >> 8) & 0xff);
+
+	sptr = (unsigned short *) &scores[i].sc_level;
+	*output++ = (unsigned char) (*sptr & 0xff);
+	*output++ = (unsigned char) ((*sptr >> 8) & 0xff);
+
+	sptr = (unsigned short *) &scores[i].sc_ctype;
+	*output++ = (unsigned char) (*sptr & 0xff);
+	*output++ = (unsigned char) ((*sptr >> 8) & 0xff);
+
+	sptr = (unsigned short *) &scores[i].sc_monster;
+	*output++ = (unsigned char) (*sptr & 0xff);
+	*output++ = (unsigned char) ((*sptr >> 8) & 0xff);
+
+	sptr = (unsigned short *) &scores[i].sc_quest;
+	*output++ = (unsigned char) (*sptr & 0xff);
+	*output++ = (unsigned char) ((*sptr >> 8) & 0xff);
+
+	/* Finally comes the char fields -- they're easy */
+	cptr = (unsigned char *) scores[i].sc_name;
+	for (j = 0; j < NAMELEN; j++) *output++ = *cptr++;
+
+	cptr = (unsigned char *) scores[i].sc_system;
+	for (j = 0; j < SYSLEN; j++) *output++ = *cptr++;
+
+	cptr = (unsigned char *) scores[i].sc_login;
+	for (j = 0; j < LOGLEN; j++) *output++ = *cptr++;
+    }
+}
+
+/*
+ * 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(' ');
+			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("fighter's guild.\n");
+	when C_RANGER:	addstr("ranger's guild.\n");
+	when C_CLERIC:	addstr("monastery.\n");
+	when C_PALADIN:	addstr("monastery.\n");
+	when C_MONK:	addstr("monastery.\n");
+	when C_DRUID:	addstr("monastery.\n");
+	when C_THIEF:	addstr("thief's guild.\n");
+	when C_ASSASIN:	addstr("assassin's guild.\n");
+	otherwise:	addstr("tavern.\n");
+    }
+    mvaddstr(lines - 1, 0, spacemsg);
+    refresh();
+    wait_for(' ');
+    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');
+    endwin();
+#ifdef PC7300
+    endhardwin();
+#endif
+    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, NAMELEN);
+	scp->sc_flags = 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/arogue7/rogue.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,1689 @@
+/*
+ * rogue.c  -  Global game variables
+ *
+ * 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.
+ */
+
+#include <ctype.h>
+#include "curses.h"
+#include "rogue.h"
+#ifdef PC7300
+#include <sys/window.h>
+#endif
+
+#ifdef BSD
+char
+tolower(c)
+{
+    if (isupper(c)) return(_tolower(c));
+    else return(c);
+}
+char
+toupper(c)
+{
+    if (islower(c)) return(_toupper(c));
+    else return(c);
+}
+#endif
+
+/*
+ * 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 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 mpos = 0;
+int level = 0;
+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 = STOMACHSIZE-MORETIME-1;
+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 chant_time = 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 */
+int cols = 0;				/* number of columns in terminal */
+int lines = 0;				/* number of lines on the terminal */
+char nfloors = -1;			/* Number of floors in this dungeon */
+char curpurch[LINELEN];			/* 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 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 monsters */
+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 menu_overlay = 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;
+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]";
+#ifdef PC7300
+struct uwdata wdata, oldwin;	/* Static window information */
+char oldtext[WTXTNUM][WTXTLEN]; /* Saved window text */
+#endif
+
+/* 
+ * This lays out all the class specific details
+ *
+ * Here are the beginning experience levels for all players.
+ * All further experience levels are computed by muliplying by 2
+ * up through MAXDOUBLE. Then exp pts are calculated by adding
+ * in the cap figure. You must change MAXDOUBLE if you change the 
+ * cap figure. 
+ */
+struct character_types char_class[NUM_CHARTYPES] = {
+/* name		exppts	cap	hitpts	Base	Maxlvl,	Factor,	Offset,	Range */
+{ "fighter",	80,	1310720, 12,	10,	30,	2,	1,	2 },
+{ "ranger",	140,	2293760,  8,	10,	20,	2,	1,	2 },
+{ "paladin",	120,	1966080, 10,	10,	23,	2,	1,	2 },
+{ "magic user",	130,	2129920,  6,	9,	18,	2,	1,	5 },
+{ "cleric",	110,	1802240,  8,	10,	19,	2,	1,	3 },
+{ "thief",	75,	1228800,  6,	10,	25,	2,	1,	4 },
+{ "assassin",	85,	1392640,  6,	10,	25,	2,	1,	4 },
+{ "druid",	100,	1638400,  8,	10,	19,	2,	1,	3 },
+{ "monk",	95,	1556480,  6,	10,	25,	2,	1,	3 },
+{ "monster",	0,	0,	  8,	7,	30,	1,	0,	2 },
+};
+
+
+/*
+ * This array lists the names of the character's abilities.  It must be ordered
+ * according to the ability definitions in rogue.h.
+ */
+
+char *abilities[NUMABILITIES] = {
+  "Intelligence", "Strength", "Wisdom", "Dexterity", "Constitution", "Charisma"
+};
+
+/*
+ * 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"},
+    { D_STARVATION,	"starvation"},
+    { D_FOOD_CHOKE,	"choking on food"},
+    { D_SCROLL,		"reading a scroll"},
+};
+
+
+/*
+ * weapons and their attributes
+ */
+struct init_weps weaps[MAXWEAPONS] = {
+    { "mace",		"2d4",  "1d3", NONE,	ISMETAL, 3, 100, 8 },
+    { "long sword",	"1d12", "1d2", NONE,	ISMETAL, 4, 60, 18 },
+    { "short bow",	"1d1",  "1d1", NONE,	0, 6, 40, 15 },
+    { "arrow",		"1d1",  "1d6", BOW,	ISMANY|ISMISL, 1, 5, 1 },
+    { "dagger",		"1d6",  "1d4", NONE,	ISMETAL|ISMISL|ISMANY,1,7,2},
+    { "rock",		"1d2",  "1d4", SLING,	ISMANY|ISMISL, 1, 5, 1 },
+    { "two-handed sword","3d6",  "1d2", NONE,	ISMETAL, 5, 250, 40 },
+    { "sling",		"0d0",  "0d0", NONE,  	0, 1, 5, 1 },
+    { "dart",		"1d1",  "1d3", NONE,  	ISMANY|ISMISL, 1, 5, 1 },
+    { "crossbow",	"1d1",  "1d1", NONE,  	0, 6, 100, 15 },
+    { "crossbow bolt",	"1d2", "1d12", CROSSBOW,ISMANY|ISMISL, 1, 7, 1 },
+    { "spear",		"1d8",  "2d6", NONE,	ISMANY|ISMETAL|ISMISL,2,20,8},
+    { "trident",	"3d4",  "1d4", NONE,	ISMETAL, 4, 50, 20 },
+    { "spetum",		"2d6",  "1d3", NONE,	ISMETAL, 4, 50, 20 },
+    { "bardiche",	"3d4",  "1d2", NONE,	ISMETAL, 4, 125, 20 },
+    { "pike",		"1d12", "1d8", NONE,	ISMETAL, 4, 80, 18 },
+    { "bastard sword",	"2d8",  "1d2", NONE,	ISMETAL, 5, 100, 30 },
+    { "halberd",	"2d6",  "1d3", NONE,	ISMETAL, 4, 175, 10 },
+    { "battle axe", 	"1d8",	"1d3", NONE,	ISMETAL, 3, 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",	 50, 125, 0, 0 },
+    { "magic mapping",		 50, 150, 0, 0 },
+    { "light",			 70, 100, 21, 15 },
+    { "hold monster",		 30, 200, 33, 20 },
+    { "sleep",			 20, 150, 20, 0 },
+    { "enchantment",		170, 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, 700, 0, 0 },
+    { "protection",		 30, 190, 20, 0 },
+    { "trap finding",		 10, 180, 0, 0 },
+    { "runes",			 10,  50, 0, 0 },
+    { "charm monster",		 20, 275, 0, 15 },
+};
+
+struct magic_item p_magic[MAXPOTIONS] = {
+    { "clear thought",		 50, 180, 27, 10 },
+    { "gain ability",		160, 210, 15, 15 },
+    { "see invisible",		 50, 150, 25, 15 },
+    { "healing",		160, 130, 27, 27 },
+    { "monster detection",	 60, 120, 0, 0 },
+    { "magic detection",	 60, 105, 0, 0 },
+    { "raise level",		 10, 450, 11, 10 },
+    { "haste self",		 90, 180, 30, 5 },
+    { "restore abilities",	140, 140, 0, 10 },
+    { "phasing",		 50, 210, 21, 20 },
+    { "invisibility",		 50, 230, 0, 15 },
+    { "flying",			 40, 130, 0, 20 },
+    { "food detection",		 10, 150, 0, 0 },
+    { "skill",			 10, 200, 20, 10 },
+    { "fire resistance",	 10, 250, 0, 10 },
+    { "cold resistance",	 10, 250, 0, 10 },
+    { "lightning protection",	 10, 250, 0, 10 },
+    { "poison",			 30, 205, 0, 0 },
+};
+
+struct magic_item r_magic[MAXRINGS] = {
+    { "protection",		 50, 200, 33, 25 },
+    { "add strength",		 60, 200, 33, 25 },
+    { "sustain ability",	 50, 500, 0, 0 },
+    { "searching",		 50, 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",		 30, 300, 0, 0 },
+    { "add intelligence",	 60, 240, 33, 25 },
+    { "increase wisdom",	 60, 220, 33, 25 },
+    { "sustain health",		 80, 500, 0,  0 },
+    { "carrying",		 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},
+    { "free action",		 10, 370, 0, 0},
+    { "teleport control",	 10, 700, 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",			 80, 220, 25, 20 },
+    { "drain life",		 80, 210, 20, 0 },
+    { "charging",		 70, 400, 0,  0 },
+    { "teleport",		 90, 140, 25, 20 },
+    { "cancellation",		 40, 130, 0,  0 },
+    { "confusion",	   	 35, 100, 15,  0},
+    { "disintegration",	  	 10, 300, 33, 0},
+    { "petrification",		 30, 240, 0,  0},
+    { "paralyzation",		 30, 180, 15,  0},
+    { "degeneration",		 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},
+    { "Eye of Vecna",		   0, 50000,  0, 0},
+    { "Axe of Aklad",		   0, 50000,  0, 0},
+    { "Quill of Nagrom",	   0, 50000,  0, 0},
+    { "Amulet of Stonebones",	   0, 50000,  0, 0},
+    { "Ring of Surtur",		   0, 50000,  0, 0},
+};
+/*
+ * food and fruits that you get
+ */
+struct magic_item foods[MAXFOODS] = {
+    { "food ration",	800, 50, 750,  0},
+    { "apple",		 10, 20, 300,  0},
+    { "banana",		 10, 20, 300,  0},
+    { "blueberry",	 10, 20, 300,  0},
+    { "candleberry",	 10, 20, 300,  0},
+    { "caprifig",	 10, 20, 300,  0},
+    { "dewberry",	 10, 20, 300,  0},
+    { "elderberry",	 10, 20, 300,  0},
+    { "gooseberry",	 10, 20, 300,  0},
+    { "guanabana",	 10, 20, 300,  0},
+    { "hagberry",	 10, 20, 300,  0},
+    { "jaboticaba",	 10, 20, 300,  0},
+    { "peach",		 10, 20, 300,  0},
+    { "pitanga",	 10, 20, 300,  0},
+    { "prickly pear",	 10, 20, 300,  0},
+    { "rambutan",	 10, 20, 300,  0},
+    { "sapodilla",	 10, 20, 300,  0},
+    { "soursop",	 10, 20, 300,  0},
+    { "strawberry",	 10, 20, 300,  0},
+    { "sweetsop",	 10, 20, 300,  0},
+    { "whortleberry",	 10, 20, 300,  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	  },
+	{ WS_MISSILE,		15,	TYP_STICK,	0	  },
+	{ S_TELEP,		20,	TYP_SCROLL,	0	  },
+	{ S_SLEEP,		20,	TYP_SCROLL,	0	  },
+	{ P_FLY,		20,	TYP_POTION,	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	  },
+	{ WS_CHARGE,		55,	TYP_STICK,	ISBLESSED },
+	{ 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_LIGHT,		10,	TYP_SCROLL,	ISBLESSED },
+	{ S_REMOVE,		15,	TYP_SCROLL,	0	  },
+	{ P_HEALING,		20,	TYP_POTION,	0	  },
+	{ P_FFIND,		24,	TYP_POTION,	0	  },
+	{ S_FINDTRAPS,		26,	TYP_SCROLL,	0	  },
+	{ S_CURING,		27,	TYP_SCROLL,	0	  },
+	{ WS_PARALYZE,		30,	TYP_STICK,	ISBLESSED },
+	{ S_MAP,		31,	TYP_SCROLL,	0	  },
+	{ P_CLEAR,		32,	TYP_POTION,	0	  },
+	{ WS_FEAR,		33,	TYP_STICK,	ISBLESSED },
+	{ P_SEEINVIS,		35,	TYP_POTION,	0	  },
+	{ P_RESTORE,		40,	TYP_POTION,	0	  },
+	{ P_PHASE,		43,	TYP_POTION,	0	  },
+	{ S_TELEP,		45,	TYP_SCROLL,	0	  },
+	{ WS_CURING,		50,	TYP_STICK,	ISBLESSED },
+	{ WS_DRAIN,		50,	TYP_STICK,	0	  },
+};
+
+/*
+ * these are the spells that a druid can chant
+ */
+struct spells druid_spells[MAXCHANTS] = {
+	{ P_TFIND,		3,	TYP_POTION,	0	  },
+	{ P_MFIND,		3,	TYP_POTION,	0	  },
+	{ S_LIGHT,		7,	TYP_SCROLL,	ISBLESSED },
+	{ S_CONFUSE,		10,	TYP_SCROLL,	0	  },
+	{ S_MAP,		10,	TYP_SCROLL,	0	  },
+	{ P_FFIND,		15,	TYP_POTION,	0	  },
+	{ P_HEALING,		20,	TYP_POTION,	0	  },
+	{ S_CURING,		25,	TYP_SCROLL,	0	  },
+	{ P_FLY,		27,	TYP_POTION,	ISBLESSED },
+	{ P_FIRE,		30,	TYP_POTION,	ISBLESSED },
+	{ P_COLD,		30,	TYP_POTION,	ISBLESSED },
+	{ P_LIGHTNING,		30,	TYP_POTION,	ISBLESSED },
+	{ S_HOLD,		35,	TYP_SCROLL,	0	  },
+	{ WS_CURING,		40,	TYP_STICK,	ISBLESSED },
+	{ P_PHASE,		45,	TYP_POTION,	0	  },
+	{ S_CHARM,		50,	TYP_SCROLL,	ISBLESSED },
+};
+
+
+/*
+ * these are the scrolls that a quill can write
+ */
+struct quill quill_scrolls[MAXQUILL] = {
+	{ S_GFIND,		4,	},
+	{ S_IDENT,		5,	},
+	{ S_LIGHT,		6,	},
+	{ S_REMOVE,		7,	},
+	{ S_MAP,		10,	},
+	{ S_SLEEP,		20,	},
+	{ S_TELEP,		30,	},
+	{ S_CONFUSE,		40,	},
+	{ S_CURING,		50,	},
+	{ S_HOLD,		70,	},
+	{ S_PROTECT,		90,	},
+	{ S_SCARE,		110,	},
+	{ S_ALLENCH,		130,	},
+};
+
+char *cnames[NUM_CHARTYPES-1][NUM_CNAMES] = {
+{	"Veteran",			"Warrior",		/* Fighter */
+	"Swordsman",			"Hero",
+	"Swashbuckler",			"Myrmidon",
+	"Champion",			"Superhero",
+	"Lord",				"Lord",
+	"Lord",				"Lord",
+	"Lord",				"Lord",
+	"Lord",				"Lord",
+	"Lord"
+},
+{	"Runner",			"Strider",		/* Ranger */
+	"Scout",			"Courser",
+	"Tracker",			"Guide",
+	"Pathfinder",			"Ranger",
+	"Ranger Knight",		"Ranger Lord",
+	"Ranger Lord",			"Ranger Lord",
+	"Ranger Lord",			"Ranger Lord",
+	"Ranger Lord",			"Ranger Lord",
+	"Ranger Lord"
+},
+{	"Gallant",			"Keeper",		/* Paladin */
+	"Protector",			"Defender",
+	"Warder",			"Guardian",
+	"Chevalier",			"Justiciar",
+	"Paladin",			"Paladin",
+	"Paladin",			"Paladin",
+	"Paladin",			"Paladin",
+	"Paladin",			"Paladin",
+	"Paladin"
+},
+{	"Prestidigitator",		"Evoker",		/* Magic User */
+	"Conjurer",			"Theurgist",		
+	"Thaumaturgist",		"Magician",
+	"Enchanter",			"Warlock",
+	"Sorcerer",			"Necromancer",
+	"Wizard I",			"Wizard II",
+	"Wizard III",			"Wizard IV",
+	"Wizard V",			"Wizard VI",
+	"High Wizard"
+},
+{	"Acolyte",			"Adept",		/* Cleric */
+	"Priest",			"Curate",
+	"Prefect",			"Canon",
+	"Lama",				"Patriarch",
+	"High Priest",			"High Priest",
+	"High Priest",			"High Priest",
+	"High Priest",			"High Priest",
+	"High Priest",			"High Priest",
+	"High Priest"
+},
+{	"Rogue",			"Footpad",		/* Thief */
+	"Cutpurse",			"Robber",
+	"Burglar",			"Filcher",
+	"Sharper",			"Magsman",
+	"Thief",			"Master Thief",
+	"Master Thief",			"Master Thief",
+	"Master Thief",			"Master Thief",
+	"Master Thief",			"Master Thief",
+	"Master Thief"
+},
+{	"Bravo",			"Rutterkin",		/* Assassin */
+	"Waghalter",			"Murderer",
+	"Thug",				"Killer",
+	"Cutthroat",			"Executioner",
+	"Assassin",			"Expert Assassin",
+	"Senior Assassin",		"Chief Assassin",
+	"Prime Assassin",		"Guildmaster Assassin",
+	"Grandfather Assassin",		"Grandfather Assassin",
+	"Grandfather Assassin"
+},
+{	"Aspirant",			"Ovate",		/* Druid */
+	"Initiate 1st Circle",		"Initiate 2nd Circle",
+	"Initiate 3rd Circle",		"Initiate 4th Circle",
+	"Initiate 5th Circle",		"Initiate 6th Circle",
+	"Initiate 7th Circle",		"Initiate 8th Circle",
+	"Initiate 9th Circle",		"Druid",
+	"Archdruid",			"The Great Druid",
+	"The Great Druid",		"The Great Druid",
+	"The Great Druid",
+},
+{	"Novice",			"Initiate",		/* Monk */
+	"Brother",			"Disciple",
+	"Immaculate",			"Master",
+	"Superior Master",		"Master of Dragons",
+	"Master of North Wind",		"Master of West Wind",
+	"Master of South Wind",		"Master of East Wind",
+	"Master of Winter",		"Master of Autumn",
+	"Master of Summer",		"Master of Spring",
+	"Grand Master"
+}
+} ;
+
+struct h_list helpstr[] = {
+    '?',	"	prints help",
+    '/',	"	identify object",
+    '=',	"	identify screen character",
+    '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)",
+    CTRL('N'),	"	name object or monster",
+    'm',	"	mark object (specific)",
+    'o',	"	examine/set options",
+    'c',	"	chant",
+    'C',	"	cast a spell",
+    'p',	"	pray",
+    'a',	"	affect the undead",
+    '^',	"	set a trap",
+    'G',	"	sense gold",
+    'D',	"	dip something (into a pool)",
+    '*',	"	count up gold pieces",
+    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('M'),	"	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	dex,	move,	exp,	level,	"armor", hit_points,
+		"damage"}}, */
+{"unknown",
+		0,	FALSE,	FALSE,	'\0',	"",
+		{0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+		0,
+		0, 0,
+		{0,	0,	0,	0,	0,	0,	HPT(""),
+		""}},
+{"giant rat",
+		0,	TRUE,	TRUE,	'R',	"2-4",
+		{ISMEAN, CANDISEASE},
+		0, 0,
+		1,
+		{10,	10,	6,	7,	1,	7,	HPT("1d4"),
+		"1d3"}},
+{"kobold",
+		10,	TRUE,	TRUE,	'K',	"8",
+		{ISMEAN, CANSHOOT, CARRYWEAPON},
+		0, 0,
+		1,
+		{9,	10,	6,	5,	1,	7,	HPT("1d4"),
+		"1d4"}},
+{"gnome",
+		10,	TRUE,	FALSE,	'G',	"11-12",
+		{CANSHOOT, CARRYPOTION, CARRYWEAPON},
+		0, 0,
+		1,
+		{10,	10,	6,	8,	1,	5,	HPT("1d6"),
+		"1d6"}},
+{"bat",
+		0,	TRUE,	TRUE,	'b',	"2-4",
+		{ISMEAN, CANDISEASE, ISFLY, AREMANY},
+		0, 0,
+		0,
+		{10,	10,	6,	5,	1,	10,	HPT("1d4"),
+		"1d1"}},
+{"halfling",
+		10,	TRUE,	FALSE,	'H',	"11-12",
+		{CANSHOOT, CARRYPOTION, CARRYWEAPON},
+		0, 0,
+		1,
+		{8,	10,	6,	9,	1,	4,	HPT("1d6"),
+		"1d6"}},
+{"dwarf",
+		15,	TRUE,	FALSE,	'D',	"11-12",
+		{CANSHOOT, CARRYPOTION, CARRYWEAPON},
+		0, 0,
+		1,
+		{10,	10,	6,	10,	1,	4,	HPT("1d8"),
+		"1d8"}},
+{"orc",
+		15,	TRUE,	TRUE,	'O',	"8",
+		{ISMEAN, CANSHOOT, CARRYGOLD, CARRYWEAPON},
+		0, 0,
+		1,
+		{12,	10,	6,	10,	1,	6,	HPT("1d8"),
+		"1d8"}},
+{"xvart",
+		100,	TRUE,	TRUE,	'x',	"14-15",
+		{ISMEAN, CARRYDAGGER, AREMANY},
+		0, 0,
+		1,
+		{8,	10,	6,	7,	1,	7,	HPT("1d4"),
+		"1d4"}},
+{"manes",
+		0,	TRUE,	TRUE,	'M',	"2-4",
+		{ISMEAN, MAGICHIT, ISUNDEAD, TURNABLE},
+		0, 0,
+		1,
+		{10,	10,	6,	18,	1,	7,	HPT("1d8"),
+		"1d2/1d2/1d4"}},
+{"elf",
+		50,	TRUE,	FALSE,	'E',	"13-20",
+		{CANSHOOT, CARRYPOTION, CARRYSCROLL, CARRYWEAPON},
+		0, 0,
+		2,
+		{12,	10,	6,	20,	1,	5,	HPT("1d8+1"),
+		"1d10"}},
+{"hobgoblin",
+		10,	TRUE,	TRUE,	'h',	"8-10",
+		{ISMEAN, CANSHOOT, CARRYWEAPON},
+		0, 0,
+		2,
+		{14,	10,	6,	20,	1,	5,	HPT("1d8+1"),
+		"1d8"}},
+{"fire beetle", 
+		0,	TRUE,	TRUE,	'B',	"0",
+		{ISMEAN, HASFIRE},
+		0, 0,
+		2,
+		{10,	10,	6,	20,	1,	4,	HPT("1d8+2"),
+		"2d4"}},
+{"giant ant",
+		0,	TRUE,	TRUE,	'A',	"1",
+		{ISMEAN, CANPOISON},
+		0, 0,
+		3,
+		{10,	10,	6,	40,	2,	3,	HPT("2d8"),
+		"1d6/1d6"}},
+{"zombie",
+		0,	TRUE,	TRUE,	'Z',	"0",
+		{ISMEAN, ISUNDEAD, TURNABLE},
+		0, 0,
+		2,
+		{10,	10,	6,	20,	2,	8,	HPT("2d8"),
+		"1d8"}},
+{"ear seeker",
+		0,	TRUE,	TRUE,	'e',	"0",
+		{ISMEAN, CANINFEST, AREMANY, CANSURPRISE},
+		0, 0,
+		0,
+		{10,	10,	6,	5,	1,	9,	HPT("1d1"),
+		"1d1"}},
+{"shrieker",
+		0,	TRUE,	FALSE,	'S',	"0",
+		{CANSHRIEK, NOMOVE, NOSTAB},
+		0, 0,
+		1,
+		{10,	10,	6,	10,	3,	7,	HPT("3d8"),
+		"0d0"}},
+{"stirge",
+		0,	TRUE,	TRUE,	's',	"1",
+		{ISMEAN, CANDRAW, ISFLY},
+		0, 0,
+		2,
+		{10,	10,	6,	36,	4,	8,	HPT("1d8+1"),
+		"1d3"}},
+{"gas spore",
+		0,	TRUE,	FALSE,	'a',	"0",
+		{ISMEAN, CANEXPLODE, CANINFEST, ISFLY},
+		0, 0,
+		5,
+		{10,	10,	18,	90,	1,	9,	HPT("1d1"),
+		"1d1"}},
+{"troglodyte",
+		5,	TRUE,	TRUE,	'T',	"5-7",
+		{ISMEAN, CANSMELL, CANSHOOT, CARRYGOLD, CARRYWEAPON},
+		0, 0,
+		2,
+		{10,	10,	6,	36,	2,	5,	HPT("2d8"),
+		"1d3/1d3/2d5"}},
+{"lemure",
+		0,	TRUE,	FALSE,	'L',	"2-4",
+		{ISMEAN, ISREGEN, MAGICHIT, ISUNDEAD, TURNABLE},
+		0, 0,
+		3,
+		{10,	10,	9,	65,	3,	7,	HPT("3d8"),
+		"1d3"}},
+{"bugbear",
+		5,	TRUE,	TRUE,	'b',	"5-8",
+		{ISMEAN, CANSHOOT, CANSURPRISE, CARRYGOLD, CARRYPOTION,
+		 CARRYWEAPON},
+		0, 0,
+		4,
+		{16,	10,	6,	135,	3,	5,	HPT("3d8+1"),
+		"2d4"}},
+{"wererat",
+		20,	TRUE,	TRUE,	'r',	"11-12",
+		{ISMEAN, MAGICHIT, CARRYFOOD, CANSUMMON},
+		"giant rat", 2,
+		4,
+		{10,	10,	6,	150,	3,	6,	HPT("3d8+1"),
+		"1d8"}},
+{"ghoul",
+		0,	TRUE,	TRUE,	'g',	"5-7",
+		{ISMEAN, CANPARALYZE, ISUNDEAD, TURNABLE},
+		0, 0,
+		2,
+		{10,	10,	6,	65,	2,	6,	HPT("2d8"),
+		"1d3/1d3/1d6"}},
+{"leprechaun",
+		100,	TRUE,	FALSE,	'l',	"15-16",
+		{CARRYGOLD, STEALGOLD},
+		0, 0,
+		1,
+		{10,	10,	3,	80,	6,	3,	HPT("1d4+1"),
+		"0d0"}},
+{"gray ooze", 
+		50,	TRUE,	FALSE,	'o',	"1",
+		{ISMEAN, CANRUST, ISSCAVENGE, NOCOLD, NOFIRE, NOSTAB,CARRYFOOD},
+		0, 0,
+		5,
+		{10,	10,	10,	200,	3,	8,	HPT("3d8+3"),
+		"2d8"}},
+{"giant tick",
+		0,	TRUE,	TRUE,	't',	"0",
+		{ISMEAN, CANDRAW, CANDISEASE},
+		0, 0,
+		2,
+		{10,	10,	9,	105,	3,	3,	HPT("3d8"),
+		"1d4"}},
+{"ogre",
+		50,	TRUE,	TRUE,	'O',	"5-7",
+		{ISMEAN, CARRYGOLD, CARRYWEAPON},
+		0, 0,
+		5,
+		{18,	10,	7,	90,	4,	5,	HPT("4d8+1"),
+		"1d10"}},
+{"very young dragon", 
+		10,	TRUE,	FALSE,	'd',	"15-16",
+		{ISMEAN, CANBRANDOM, ISGREED, CARRYGOLD},
+		0, 0,
+		9,
+		{10,	10,	6,	100,	9,	-1,	HPT("9d1"),
+		"1d4/1d4/2d4"}},
+{"centaur",
+		15,	TRUE,	FALSE,	'C',	"5-10",
+		{CANSHOOT, CARRYPOTION, CARRYGOLD, CARRYWEAPON},
+		0, 0,
+		4,
+		{10,	10,	2,	85,	4,	4,	HPT("4d8"),
+		"1d6/1d6"}},
+{"nymph",
+		100,	TRUE,	FALSE,	'N',	"15-16",
+		{STEALMAGIC, CARRYSCROLL, CARRYPOTION, CARRYSTICK},
+		0, 0,
+		3,
+		{10,	10,	6,	350,	4,	9,	HPT("3d8"),
+		"0d0"}},
+{"violet fungi", 
+		0,	TRUE,	FALSE,	'F',	"0",
+		{ISMEAN, CANHOLD, NOMOVE, CANROT, NOSTAB},
+		0, 0,
+		4,
+		{10,	10,	6,	135,	3,	7,	HPT("3d8"),
+		"5d1"}},
+{"gelatinous cube", 
+		90,	TRUE,	TRUE,	'c',	"0",
+		{ISMEAN, ISSCAVENGE, CANPARALYZE, NOSTAB, CARRYFOOD},
+		0, 0,
+		4,
+		{10,	10,	8,	150,	4,	8,	HPT("4d8"),
+		"2d4"}},
+{"fire toad", 
+		0,	TRUE,	TRUE,	'f',	"5-7",
+		{ISMEAN, CANBFIRE, NOFIRE},
+		0, 0,
+		4,
+		{10,	10,	6,	150,	4,	10,	HPT("4d8+1"),
+		"2d4"}},
+{"blink dog",
+		0,	TRUE,	TRUE,	'B',	"8-10",
+		{ISMEAN, CANBLINK},
+		0, 0,
+		5,
+		{10,	10,	6,	170,	4,	5,	HPT("4d8"),
+		"1d6"}},
+{"rust monster", 
+		0,	TRUE,	TRUE,	'R',	"1",
+		{ISMEAN, CANRUST},
+		0, 0,
+		4,
+		{10,	10,	6,	185,	5,	2,	HPT("3d8"),
+		"0d0/0d0"}},
+{"ghast",
+		0,	TRUE,	TRUE,	'G',	"11-12",
+		{CANPARALYZE, CANSTINK, ISMEAN, ISUNDEAD, TURNABLE},
+		0, 0,
+		4,
+		{10,	10,	6,	190,	4,	4,	HPT("4d8"),
+		"1d4/1d4/1d8"}},
+{"blindheim",
+		0,	TRUE,	FALSE,	'b',	"1",
+		{CANBLIND, ISMEAN},
+		0, 0,
+		4,
+		{8,	10,	6,	200,	2,	1,	HPT("4d8+2"),
+		"1d8"}},
+{"shadow",
+		0,	TRUE,	TRUE,	'S',	"5-7",
+		{ISSHADOW, ISMEAN, CANCHILL, ISUNDEAD, TURNABLE},
+		0, 0,
+		4,
+		{10,	10,	6,	255,	3,	7,	HPT("3d8+3"),
+		"1d4+1"}},
+{"gargoyle",
+		5,	TRUE,	TRUE,	'g',	"5-7",
+		{ISMEAN, MAGICHIT},
+		0, 0,
+		5,
+		{10,	10,	6,	165,	4,	5,	HPT("4d8+4"),
+		"1d3/1d3/1d6/1d4"}},
+{"quasit",
+		30,	TRUE,	TRUE,	'Q',	"5-7",
+		{ISMEAN, ISREGEN, MAGICHIT, CANSURPRISE, CANITCH, CARRYSTICK,
+		 CARRYSCROLL, CARRYGOLD, CARRYPOTION, NOCOLD, NOFIRE, NOBOLT},
+		0, 0,
+		3,
+		{10,	10,	6,	325,	7,	2,	HPT("3d8"),
+		"1d2/1d2/1d4"}},
+{"imp", 
+		25,	TRUE,	TRUE,	'I',	"8-10",
+		{ISMEAN, ISREGEN, MAGICHIT, CANPOISON, CANSURPRISE,
+		 CANTELEPORT, CARRYRING, CARRYSTICK, NOCOLD, NOBOLT, NOFIRE},
+		0, 0,
+		3,
+		{10,	10,	6,	275,	2,	2,	HPT("2d8+2"),
+		"1d4"}},
+{"su-monster", 10,	TRUE,	TRUE,	's',	"8-10",
+		{ISMEAN, CARRYSCROLL, CARRYGOLD, CARRYFOOD},
+		0, 0,
+		6,
+		{10,	10,	5,	225,	5,	6,	HPT("5d8+5"),
+		"4d4/2d4"}},
+{"owlbear",
+		5,	TRUE,	TRUE,	'O',	"5-7",
+		{ISMEAN, CANHUG, CARRYRING, CARRYFOOD},
+		0, 0,
+		8,
+		{10,	10,	8,	225,	5,	5,	HPT("5d8+2"),
+		"1d6/1d6/2d6"}},
+{"doppleganger", 
+		0,	TRUE,	TRUE,	'D',	"11-12",
+		{ISMEAN, CANSURPRISE},
+		0, 0,
+		4,
+		{10,	10,	6,	330,	10,	5,	HPT("4d8"),
+		"1d12"}},
+{"yeti",	
+		30,	TRUE,	TRUE,	'Y',	"8-10",
+		{ISMEAN, CANPARALYZE, CANHUG, NOCOLD, CANSURPRISE,
+		 CARRYGOLD, CARRYPOTION},
+		0, 0,
+		8,
+		{13,	10,	6,	500,	6,	6,	HPT("4d8+4"),
+		"1d6/1d6"}},
+{"leucrotta", 
+		0,	TRUE,	FALSE,	'L',	"8-10",
+		{ISMEAN},
+		0, 0,
+		8,	
+		{10,	10,	2,	475,	6,	4,	HPT("6d8+1"),
+		"3d6/1d6/1d6"}},
+{"cockatrice", 
+		0,	TRUE,	TRUE,	'C',	"1",
+		{ISMEAN, TOUCHSTONE},
+		0, 0,
+		5,
+		{10,	10,	5,	315,	5,	6,	HPT("5d8"),
+		"1d3"}},
+{"wight",
+		0,	TRUE,	TRUE,	'W',	"8-10",
+		{ISMEAN, CANDRAIN, MAGICHIT, ISUNDEAD, TURNABLE},
+		0, 0,
+		5,
+		{10,	10,	6,	540,	4,	5,	HPT("4d8+3"),
+		"1d4"}},
+{"troll",
+		50,	TRUE,	FALSE,	'T',	"5-7",
+		{ISMEAN, ISREGEN, CARRYFOOD, CARRYGOLD},
+		0, 0,
+		8,
+		{18,	10,	8,	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,	10,	6,	800,	4,	4,	HPT("4d8"),
+		"2d4"}},
+{"wraith",
+		0,	TRUE,	TRUE,	'w',	"11-12",
+		{ISMEAN, CANDRAIN, MAGICHIT, ISUNDEAD, TURNABLE},
+		0, 0,
+		6,
+		{10,	10,	6,	575,	5,	4,	HPT("5d8+3"),
+		"1d6"}},
+{"mimic",
+		20,	TRUE,	FALSE,	'M',	"2-10",
+		{ISMEAN, ISDISGUISE, NODETECT, CANHOLD, CARRYFOOD, CARRYRING, 
+		 CARRYGOLD, NOMOVE},
+		0, 0,
+		12,
+		{10,	10,	6,	1300,	9,	7,	HPT("10d8"),
+		"3d4"}},
+{"erinyes",
+		25,	TRUE,	TRUE,	'E',	"8-10",
+		{ISMEAN, CANFRIGHTEN, CANSUMMON, TURNABLE, CANPAIN, CANSEE, 
+		 NOFIRE, CANTELEPORT, CARRYRING, CARRYSTICK},
+		"ghoul", 3, 
+		8,
+		{10,	10,	6,	875,	7,	2,	HPT("6d8+6"),
+		"2d4"}},
+{"lava child", 
+		0,	TRUE,	TRUE,	'l',	"8-10",
+		{ISMEAN, NOMETAL},
+		0, 0,
+		8,	
+		{10,	10,	6,	950,	5,	4,	HPT("5d8+1"),
+		"1d6/1d6/2d12"}},
+{"basilisk",
+		0,	TRUE,	FALSE,	'B',	"1",
+		{ISMEAN, LOOKSTONE},
+		0, 0,
+		8,
+		{10,	10,	6,	1000,	6,	4,	HPT("6d8+1"),
+		"1d10"}},
+{"mummy",
+		20,	TRUE,	FALSE,	'm',	"5-7",
+		{ISMEAN,CANINFEST, MAGICHIT, CANFRIGHTEN, HALFDAMAGE, ISUNDEAD, 
+		 TURNABLE, CARRYRING},
+		0, 0,
+		8,
+		{10,	10,	6,	1150,	6,	3,	HPT("6d8+3"),
+		"1d12"}},
+{"otyugh",
+		0,	TRUE,	TRUE,	'o',	"5-10",
+		{ISMEAN, CANDISEASE},
+		0, 0,
+		8,
+		{10,	10,	6,	700,	7,	3,	HPT("7d8"),
+		"1d8/1d8/1d4+1"}},
+{"adult dragon", 
+		30,	TRUE,	FALSE,	'd',	"15-16",
+		{ISMEAN, CANBRANDOM, ISGREED, CANFRIGHTEN, CARRYGOLD,
+		 CARRYPOTION},
+		0, 0,
+		9,
+		{10,	10,	6,	1000,	9,	-1,	HPT("45d1"),
+		"1d6/1d6/2d6"}},
+{"invisible stalker", 
+		0,	TRUE,	TRUE,	'i',	"13-14",
+		{ISMEAN, ISINVIS},
+		0, 0,
+		10,
+		{10,	10,	4,	1090,	8,	3,	HPT("8d8"),
+		"4d4"}},
+{"xorn",
+		0,	TRUE,	TRUE,	'X',	"8-10",
+		{ISMEAN, CANINWALL, NOCOLD, NOFIRE, CANSURPRISE, NOBOLT},
+		0, 0,
+		10,
+		{10,	10,	6,	1275,	7,	-2,	HPT("7d8+7"),
+		"1d3/1d3/1d3/4d6"}},
+{"chimera",
+		0,	TRUE,	FALSE,	'c',	"2-4",
+		{ISMEAN, CANBFIRE, NOFIRE},
+		0, 0,
+		12,
+		{10,	10,	6,	1000,	9,	6,	HPT("9d8"),
+		"1d3/1d3/1d4/1d4/2d4/3d4"}},
+{"horned devil", 
+		5,	TRUE,	TRUE,	'H',	"13-14",
+		{ISMEAN, CANFRIGHTEN, CANINFEST, CANPOISON, MAGICHIT, CANSUMMON,
+		 NOFIRE, CANTELEPORT, CARRYGOLD, CARRYRING, CARRYSTICK},
+		"wight", 2, 
+		6,
+		{10,	10,	6,	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,	10,	6,	1650,	7,	2,	HPT("7d8+3"),
+		"1d8"}},
+{"will-o-wisp", 100,	TRUE,	FALSE,	'W',	"15-16",
+		{ISMEAN, CANSURPRISE, ISFLY, CARRYGOLD, CARRYMISC, NOBOLT},
+		0, 0,
+		12,
+		{10,	10,	5,	2000,	9,	-8,	HPT("9d8"),
+		"2d8"}},
+{"lamia", 
+		0,	TRUE,	TRUE,	'L',	"13-14",
+		{ISMEAN, TAKEWISDOM},
+		0, 0,
+		9,	
+		{10,	10,	2,	1500,	9,	3,	HPT("9d8"),
+		"1d4/1d4"}},
+{"neo-otyugh",
+		0,	TRUE,	TRUE,	'N',	"10-12",
+		{ISMEAN, CANDISEASE},
+		0, 0,
+		10,
+		{12,	10,	6,	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,	10,	6,	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,	10,	6,	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,	10,	7,	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,	10,	6,	1700,	8,	2,	HPT("8d8+8"),
+		"3d4/3d4/2d5"}},
+{"ettin",
+		0,	TRUE,	TRUE,	'e',	"5-7",
+		{ISMEAN, CANSHOOT, AREMANY},
+		0, 0,
+		14,
+		{10,	10,	6,	1950,	10,	3,	HPT("10d8"),
+		"2d8/3d6"}},
+{"black pudding", 
+		30,	TRUE,	FALSE,	'P',	"0",
+		{ISMEAN, CANRUST, NOCOLD, BOLTDIVIDE, BLOWDIVIDE, ISSCAVENGE, 
+		 NOSTAB, CARRYSCROLL, CARRYPOTION, CARRYRING},
+		0, 0,
+		14,
+		{10,	10,	6,	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,	10,	6,	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,	10,	6,	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,	10,	6,	2800,	9,	-1,	HPT("9d8"),
+		"2d4"}},
+{"white pudding", 
+		30,	TRUE,	FALSE,	'w',	"0",
+		{ISMEAN, CANDISSOLVE, NOCOLD, BOLTDIVIDE, BLOWDIVIDE, 
+		 ISSCAVENGE, NOSTAB, CARRYRING, CARRYSCROLL,
+		 CARRYPOTION},
+		0, 0,
+		14,
+		{10,	10,	6,	2200,	9,	8,	HPT("10d8"),
+		"7d4"}},
+{"vampire",
+		20,	TRUE,	TRUE,	'v',	"15-16",
+		{ISMEAN, ISREGEN, CANSUCK, ISUNDEAD, TURNABLE, CARRYMISC},
+		0, 0,
+		12,
+		{20,	10,	6,	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,	10,	5,	5000,	12,	0,	HPT("10d8"),
+		"1d12"}},
+{"intellect devourer",
+		0,	TRUE,	FALSE,	'D',	"11-12",
+		{ISMEAN, TAKEINTEL, CMAGICHIT, HALFDAMAGE, CANSURPRISE, NOFIRE, 
+		 NOCOLD},
+		0, 0,
+		9,
+		{10,	10,	4,	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, TOUCHSLOW, CANTELEPORT, CARRYSCROLL, CARRYRING,
+		 CARRYSTICK},
+		"bone devil", 2, 
+		16,
+		{20,	10,	6,	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,	10,	6,	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,	10,	6,	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, ISFLY},
+		"barbed devil", 3, 
+		18,
+		{22,	10,	6,	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,	10,	6,	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,	10,	6,	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, CARRYSTICK},
+		"specter", 2,
+		16,
+		{10,	10,	6,	20000,	17,	0,	HPT("11d8"),
+		"1d10"}},
+{"titan",
+		80,	TRUE,	FALSE,	't',	"17-20",
+		{ISMEAN, ISSHADOW, CANSEE, CANMISSILE, CARRYRING, CARRYSTICK, 
+		 CANTELEPORT},
+		0, 0,
+		30,
+		{13,	10,	5,	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,	10,	6,	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,	10,	6,	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,	10,	6,	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,	10,	6,	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,	10,	6,	20000,	11,	-1,	HPT("0d8+88"),
+		"1d6/1d6/5d6"}},
+{"frost giant",
+		50,	TRUE,	TRUE,	'F',	"5-10",
+		{ISMEAN, NOCOLD, CARRYGOLD, AREMANY},
+		0, 0,
+		40,
+		{25,	10,	5,	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,	10,	6,	20000,	11,	-1,	HPT("0d8+88"),
+		"1d8/1d8/3d10"}},
+{"ancient gold dragon", 
+		50,	TRUE,	FALSE,	'G',	"17-18",
+		{CANBFIRE, CANBGAS, ISGREED, CANSEE, CANMISSILE, NOFIRE, NOGAS,
+		 CARRYGOLD, CARRYPOTION, CARRYRING, CARRYSTICK, CANTELEPORT},
+		0, 0,
+		50,
+		{10,	10,	6,	20000,	12,	-2,	HPT("0d8+96"),
+		"1d8/1d8/6d6"}},
+{"fire giant",
+		30,	TRUE,	TRUE,	'f',	"6-10",
+		{ISMEAN, CARRYGOLD, NOFIRE, AREMANY},
+		0, 0,
+		45,
+		{27,	10,	5,	26000,	15,	4,	HPT("11d8+5"),
+		"5d6"}},
+{"storm giant",
+		30,	TRUE,	TRUE,	's',	"8-10",
+		{ISMEAN, NOBOLT, CANBBOLT, CARRYRING},
+		0, 0,
+		50,
+		{30,	10,	5,	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,
+		 CARRYMDAGGER, CARRYMISC, CARRYPOTION, CANBSTAB, ISSCAVENGE,
+		 NODETECT},
+		0, 0,
+		0,
+		{9,	18,	8,	300000,	22,	-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, CANSMELL, CANSTINK,
+		 NOFIRE},
+		"black pudding", 4, 
+		0,
+		{18,	18,	5,	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, NOFIRE,
+		 CARRYMISC, CARRYHORN},
+		"ice devil", 5, 
+		0,
+		{18,	18,	5,	110000,	30,	-3,	HPT("0d8+133"),
+		"3d6/3d6/2d4"}},
+{"arch devil (Dispater)", 
+		100,	TRUE,	FALSE,	'd',	"18",
+		{ISMEAN, ISUNIQUE, CANSEE, CANFRIGHTEN, CANHUH, BMAGICHIT, 
+		 CANSUMMON, CARRYSTICK, NOFIRE, CANTELEPORT, CARRYMISC},
+		"ghost", 9, 
+		0,
+		{18,	18,	5,	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, NOFIRE},
+		"lich", 5, 
+		0,
+		{18,	18,	5,	130000,	23,	-5,	HPT("0d8+100"),
+		"3d6/3d6"}},
+{"witch (Emori)",
+		50,	TRUE,	TRUE,	'w',	"18",
+		{ISMEAN, CANMISSILE, ISINVIS, CANBBOLT, CANBFIRE, CANBICE,
+		 CANSEE, CANSUMMON, ISUNIQUE, CANSNORE, ISFLY, TAKEINTEL,
+		 CANDANCE, CANDISEASE, NOBOLT, NOCOLD, NOFIRE, CARRYCLOAK,
+		 ISCLEAR, CARRYSCROLL, CARRYSTICK, CANTELEPORT, CANSLOW},
+		"shambling mound", 7,
+		0,
+		{21,	12,	6,	140000,	25,	 0,	HPT("0d8+102"),
+		"1d4/1d4"}},
+{"cleric of Thoth (Heil)",
+		100,	TRUE,	TRUE,	'h',	"16",
+		{ISMEAN, CANSEE, NOFEAR, ISREGEN, CANHOLD, CANBFIRE, ISUNIQUE, 
+		 DOUBLEDRAIN, CANSUMMON, NOFIRE, TOUCHFEAR, CANDISEASE, CANSUCK,
+		 CANSEE, TAKEWISDOM, CARRYANKH, CARRYRING, ISINVIS, ISFLY},
+		 "vampire", 9,
+		 0,
+		 {25,	15,	6,	150000,	25,	-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, CANTELEPORT,
+		 CARRYSTAFF, CARRYSTICK, NOSLOW, NOBOLT, NOCOLD},
+		 "ancient black dragon", 5,
+		 0,
+		 {18,	16,	6,	160000,	21,	  -4,	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,	18,	5,	170000,	20,	-2,	HPT("0d8+156"),
+		"8d8+48/4d4+36"}},
+{"lesser god (Hruggek)",
+		100,	TRUE,	FALSE,	'H',	"17",
+		{ISMEAN, CANSEE, ISUNIQUE, CANSUMMON, ISREGEN, CANFRIGHTEN,
+		 CANTELEPORT, CARRYMISC, CARRYMSTAR, CANSMELL, CANBLINK},
+		"purple worm", 6,
+		0,
+		{19,	18,	5,	180000,	25,	0,	HPT("0d8+221"),
+		"2d8/2d8"}},
+{"lesser god (Kurtulmak)",
+		100,	TRUE,	TRUE,	'K',	"19",
+		{ISMEAN, CANFRIGHTEN, CANPOISON, CANSEE, ISUNIQUE, CANSUMMON,
+		 CANTELEPORT, CARRYMISC, CANBLINK},
+		"lich", 3,
+		0,
+		{19,	18,	5,	190000,	27,	0,	HPT("0d8+219"),
+		"2d12/1d6"}},
+{"demigod (Vaprak \"The Destroyer\")",
+		100,	TRUE,	TRUE,	'v',	"18",
+		{ISMEAN, ISUNIQUE, ISREGEN, MAGICHIT, CANSEE, CANSUMMON,
+		 CANTELEPORT, CARRYMISC, CANSMELL},
+		"troll", 9,
+		0,
+		{18,	18,	5,	200000,	26,	0,	HPT("0d8+198"),
+		"2d10/2d10/1d12"}},
+{"hero (Aklad)",
+		100,	TRUE,	FALSE,	'k',	"16",
+		{ISMEAN, ISUNIQUE, CANSUMMON, ISREGEN, NOCOLD, NOBOLT, NOFIRE, 
+		 NOPARALYZE, NOFEAR, CANSEE, ISCLEAR, CARRYAXE, CARRYRING, 
+		 CARRYMISC, CANBLINK},
+		"ancient green dragon", 4,
+		0,
+		{25,	16,	4,	210000,	25,	-10,	HPT("0d8+196"),
+		"2d8+23/2d8+23/1d6+19/1d6+19"}},
+{"magician/thief (Nagrom)",
+		100,	TRUE,	TRUE,	'N',	"19",
+		{ISMEAN, ISUNIQUE, STEALMAGIC, ISINVIS, CANSUMMON, ISREGEN,
+		 CANMISSILE, CANSEE, CARRYQUILL, CARRYSCROLL, CARRYRING, ISFLY,
+		 CANBSTAB, CANBFIRE, CANBBOLT, CANBICE, NOCOLD, NOBOLT, NOFIRE,
+		 CANSURPRISE, NODETECT, CANTELEPORT, CANSLOW, 
+		 CARRYSTICK},
+		"ancient blue dragon", 5,
+		0,
+		{18,	18,	8,	220000,	26,	-2,	HPT("0d8+150"),
+		"1d10+3/1d4+3"}},
+{"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,
+		 CARRYMISC, CANTELEPORT, ISFLY},
+		"ancient gold dragon", 4,
+		0,
+		{18,	18,	5,	230000,	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, CARRYSTICK, CANDRAIN},
+		"ice devil", 9, 
+		0,
+		{18,	18,	5,	240000,	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, ISFLY},
+		"ancient red dragon", 6,
+		0,
+		{18,	18,	5,	250000,	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, NOFIRE,
+		 CARRYMISC, ISFLY, CARRYSTICK},
+		"vampire", 9, 
+		0,
+		{18,	18,	5,	260000,	27,	-6,	HPT("0d8+120"),
+		"1d10+3/2d4"}},
+{"arch devil (Asmodeus)", 
+		100,	TRUE,	FALSE,	'A',	"20",
+		{ISMEAN, ISUNIQUE, CANSEE, ISSHADOW, CANHOLD, BMAGICHIT, 
+		 CANFRIGHTEN, CANHUH, TOUCHSLOW, CANSUMMON, NOFIRE,
+		 CANTELEPORT, CARRYROD, CARRYMISC, CARRYSTICK, CANDRAIN},
+		"pit fiend", 5, 
+		0,
+		{18,	18,	5,	270000,	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, NOFIRE,
+		 CANDISEASE, CARRYMISC, CANSUCK, CARRYSTICK},
+		"pit fiend", 9, 
+		0,
+		{18,	18,	5,	280000,	45,	-8,	HPT("0d8+200"),
+		"1d6/1d6"}},
+{"greater god (Maglubiyet)",
+		100,	TRUE,	FALSE,	'M',	"19",
+		{ISMEAN, ISUNIQUE, CMAGICHIT, CANSEE, ISREGEN, CANSUMMON,
+		 CANTELEPORT, CARRYMISC, CANFRIGHTEN, CARRYSTICK},
+		"lich", 6,
+		0,
+		{19,	18,	5,	290000,	45,	-1,	HPT("0d8+350"),
+		"2d10/2d10"}},
+{"greater god (Gruumsh)",
+		100,	TRUE,	FALSE,	'G',	"19",
+		{ISMEAN, ISUNIQUE, CMAGICHIT, CANSEE, ISREGEN, CANSUMMON,
+		 CANTELEPORT, CARRYMISC, CANFRIGHTEN, CARRYSTICK},
+		"lich", 9,
+		0,
+		{19,	18,	5,	300000,	45,	-1,	HPT("0d8+350"),
+		"3d10/3d10"}},
+{"lesser god (Thrym)",
+		100,	TRUE,	FALSE,	'T',	"16",
+		{ISMEAN, NOCOLD, ISUNIQUE, ISREGEN, CMAGICHIT, CANSEE, 
+		 CANSUMMON, CARRYMISC, CANTELEPORT, CANFRIGHTEN, CARRYSTICK},
+		"frost giant", 9,
+		0,
+		{25,	18,	5,	310000,	45,	-2,	HPT("0d8+360"),
+		"4d10/4d10"}},
+{"lesser god (Surtur)",
+		100,	TRUE,	FALSE,	't',	"19",
+		{ISMEAN, NOFIRE, ISUNIQUE, ISREGEN, CMAGICHIT, CANSEE, 
+		 CANFRIGHTEN, CANSUMMON, CANMISSILE, CANTELEPORT, CARRYMISC, 
+		 CARRYSTICK, CARRYFOOD, CARRYSURTURRING},
+		"fire giant", 9,
+		0,
+		{25,	18,	5,	320000,	45,	-2,	HPT("0d8+380"),
+		"5d10/5d10"}},
+{"lesser god (Skoraeus Stonebones)",
+		100,	TRUE,	FALSE,	'b',	"19",
+		{ISMEAN, ISUNIQUE, ISREGEN, CMAGICHIT, CANSEE, CANSUMMON, ISFLY,
+		 CANMISSILE, CANINWALL, CANTELEPORT, CARRYMISC, CARRYSTICK,
+		 CANFRIGHTEN, CARRYBAMULET},
+		"storm giant", 9,
+		0,
+		{25,	25,	6,	330000,	45,	-1,	HPT("0d8+380"),
+		"6d10/6d10"}},
+{"ruler of greater titans (Yendor)",
+		100,	TRUE,	TRUE,	'y',	 "25",
+		{ISMEAN, CANINWALL, ISUNIQUE, ISREGEN, CMAGICHIT,ISFLY,
+		 CANSUMMON, CANMISSILE, CANFRIGHTEN, CANBFIRE, NOFIRE, 
+		 CANHOLD, CARRYYAMULET, CANSEE, CANDANCE, ISSHADOW,
+		 CANTELEPORT, CARRYMISC, CARRYRING, CARRYSTICK},
+		"titan", 15,
+		0,
+		{25,	25,	6,	340000, 45,	-6,	HPT("0d8+400"),
+		"7d10/7d10"}},
+{"the creator of liches (Vecna)",
+		100,	TRUE,	TRUE,	'V',	 "25",
+		{ISMEAN, CANINWALL, ISUNIQUE, ISREGEN, CMAGICHIT, CANSNORE,
+		 CANSUMMON, CANMISSILE, CANFRIGHTEN, CANBFIRE, NOFIRE, ISFLY,
+		 CANHOLD, CARRYEYE, CANSEE, CANDANCE, ISINVIS, HALFDAMAGE,
+		 CANTELEPORT, CARRYMISC, CARRYRING, CARRYSTICK, LOOKSTONE,
+		 CANSLOW, CANBLIND},
+		"lich", 15,
+		0,
+		{25,	25,	6,	350000, 47,	-8,	HPT("0d8+450"),
+		"6d10/6d10"}},
+{"quartermaster", 
+		0,	FALSE,	TRUE,	'q',	"18",
+		{CANSELL, ISCLEAR, CANTELEPORT, ISFLY, CANSEE, STEALMAGIC,
+		 NOFEAR, CANBSTAB},
+		0, 0,
+		50,
+		{25,	18,	12,	20,	1,	-4, 	HPT("1d8+1"),
+		"1d10"}},
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/rogue.h	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,1297 @@
+/*
+ * rogue.h - Rogue definitions and variable declarations
+ *
+ * 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.
+ */
+
+/*
+ * Rogue definitions and variable declarations
+ *
+ */
+
+#define reg register
+#undef lines /* AIX's term.h defines this, causing a conflict */
+#ifdef BSD
+#undef tolower(c)
+#define _tolower(c)	((c)-'A'+'a')
+extern char tolower();
+#undef toupper(c)
+#define _toupper(c)	((c)-'a'+'A')
+extern char toupper();
+#define strchr index
+
+#define exfork vfork	/* Better way to do a fork followed by an exec */
+#else
+#define exfork fork	/* Standard fork with no paging available */
+#endif
+
+/*
+ * Maximum number of different things
+ */
+#define MAXDAEMONS	10
+#define MAXFUSES	20
+#define	MAXROOMS	9
+#define	MAXTHINGS	9
+#define	MAXOBJ		9
+#define MAXSTATS	72	/* max total of all stats at startup */
+#define	MAXPACK		23
+#define MAXDOUBLE	14	/* Maximum number of times exppts is doubled */
+#define	MAXCONTENTS	10
+#define MAXENCHANT	10	/* max number of enchantments on an item */
+#define	MAXTREAS	15	/* number monsters/treasure in treasure room */
+#define	MAXTRAPS	25
+#define	MAXTRPTRY	8	/* attempts/level allowed for setting traps */
+#define	MAXDOORS	4	/* Maximum doors to a room */
+#define	MAXCHANTS	16	/* Maximum number of chants for a druid */
+#define	MAXPRAYERS	18	/* Maximum number of prayers for cleric */
+#define	MAXSPELLS	20	/* Maximum number of spells (for magician) */
+#define MAXQUILL	13	/* scrolls the Quill of Nagrom can write */
+#define QUILLCHARGES	160	/* max num of charges in the Quill of Nagrom */
+#define	NUMMONST	125	/* Current number of monsters */
+#define NUM_CNAMES	17	/* number of names per character level */
+#define NUMUNIQUE	27	/* number of UNIQUE creatures */
+#define	NLEVMONS	3	/* Number of new monsters per level */
+#define NUMSCORE	10	/* number of entries in score file */
+#define HARDER		35	/* at this level start making things harder */
+#define LINELEN		256	/* characters in a buffer */
+#define JUG_EMPTY	-1	/* signifys that the alchemy jug is empty */
+#define MAXPURCH	(pstats.s_charisma/3) /* # of purchases at post */
+
+/* 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
+#define READABLE	-10
+#define QUAFFABLE	-11
+
+/*
+ * stuff to do with encumberance
+ */
+#define NORMENCB	1500	/* normal encumberance */
+#define F_SATIATED	 0	/* player's stomach is very full */
+#define F_OKAY		 1	/* have plenty of food in stomach */
+#define F_HUNGRY	 2	/* player is hungry */
+#define F_WEAK		 3	/* weak from lack of food */
+#define F_FAINT		 4	/* fainting from lack of food */
+
+/*
+ * actions a player/monster will take
+ */
+#define A_MOVE		0200	/* normal movement */
+#define A_FREEZE	0201	/* frozen in place */
+#define A_ATTACK	0202	/* trying to hit */
+#define A_SELL		0203	/* trying to sell goods */
+#define A_NIL		0204	/* not doing anything */
+#define A_BREATHE	0205	/* breathing */
+#define A_MISSILE	0206	/* Firing magic missiles */
+#define A_SONIC		0207	/* Sounding a sonic blast */
+#define A_SUMMON	0210	/* Summoning help */
+#define A_USERELIC	0211	/* Monster uses a relic */
+#define A_SLOW		0212	/* monster slows the player */
+#define A_ZAP		0213	/* monster shoots a wand */
+#define A_PICKUP	0214	/* player is picking something up */
+#define A_USEWAND	0215	/* monster is shooting a wand */
+#define A_THROW		't'
+#define C_CAST		'C'
+#define C_COUNT		'*'
+#define C_DIP		'D'
+#define C_DROP		'd'
+#define C_EAT		'e'
+#define C_PRAY		'p'
+#define C_CHANT		'c'
+#define C_QUAFF		'q'
+#define C_READ		'r'
+#define C_SEARCH	's'
+#define C_SETTRAP	'^'
+#define C_TAKEOFF	'T'
+#define C_USE		CTRL('U')
+#define C_WEAR		'W'
+#define C_WIELD		'w'
+#define C_ZAP		'z'
+
+/* Possible ways for the hero to move */
+#define	H_TELEPORT 0
+
+/*
+ * 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_RANGER	1
+#define C_PALADIN	2
+#define	C_MAGICIAN	3
+#define	C_CLERIC	4
+#define	C_THIEF		5
+#define C_ASSASIN	6
+#define C_DRUID		7
+#define C_MONK		8
+#define	C_MONSTER	9
+#define NUM_CHARTYPES	10
+
+/*
+ * define the ability types
+ */
+#define	A_INTELLIGENCE	0
+#define	A_STRENGTH	1
+#define	A_WISDOM	2
+#define	A_DEXTERITY	3
+#define	A_CONSTITUTION	4
+#define	A_CHARISMA	5
+#define	NUMABILITIES	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;
+ *	it is also OK if the stepper is a friendly monster and
+ *	is in a fighting mood.
+ */
+#define MONSTOK 1
+#define NOMONST 2
+#define	FIGHTOK 3
+
+/*
+ * 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 r_free_list(a) _r_free_list(&a)
+#define t_free_list(a) _t_free_list(&a)
+#ifndef max
+#define max(a, b) ((a) > (b) ? (a) : (b))
+#define min(a, b) ((a) < (b) ? (a) : (b))
+#endif
+#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	o_kind o_ac
+#define ISMULT(type) (type == FOOD)
+#define isrock(ch) ((ch == WALL) || (ch == '-') || (ch == '|') || (ch == SECRETDOOR))
+#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
+#define mi_food mi_curse
+
+/*
+ * 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 D_STARVATION	-18
+#define D_FOOD_CHOKE	-19
+#define D_SCROLL	-20
+#define DEATHNUM	20	/* 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		"mTdNfNGDrwAZ."
+#define FIGHTBASE	10
+#define SPELLTIME	((max(30-pstats.s_lvl,5)))
+#define	BEARTIME	17
+#define CLOAK_TIME	(roll(20,20))
+#define	SLEEPTIME	7
+#define	FREEZETIME	11
+#define PAINTIME	(roll(2, 12))
+#define	HEALTIME	30
+#define	CHILLTIME	(roll(20, 4))
+#define	SMELLTIME	20
+#define	STONETIME	(roll(10,2))
+#define HASTETIME	11
+#define	SICKTIME	25
+#define	WANDERTIME	(max(5, (HARDER*2)-rnd(vlevel)))
+#define	BEFORE		1
+#define	AFTER		2
+#define	HUHDURATION	(50+rnd(30))
+#define	SEEDURATION	850
+#define SKILLDURATION	(100+rnd(50))
+#define	CLRDURATION	50
+#define GONETIME	200
+#define FIRETIME	(200+roll(5,5))
+#define COLDTIME	(200+roll(5,5))
+#define BOLTTIME	(200+roll(5,5))
+#define FLYTIME		300
+#define DUSTTIME	(30+roll(5,10))
+#define	PHASEDURATION	300
+#define	MORETIME	100
+#define	STINKTIME	16
+#define	STOMACHSIZE	1500
+#define	ESCAPE		27
+#define	BOLT_LENGTH	10
+#define	MARKLEN		20
+#define DAYLENGTH	400
+#define ALCHEMYTIME	(400+rnd(150))
+
+/*
+ * 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 ISPOISON	     0100
+#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 CARRYMDAGGER	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	CARRYYAMULET	0x40800000	/* Amulet of Yendor */
+#define	CARRYMANDOLIN	0x41000000	/* Mandolin of Brian */
+#define MISSEDDISP	0x42000000	/* Missed Cloak of Displacement */
+#define CANBSTAB	0x44000000	/* Can backstab */
+#define ISGUARDIAN	0x48000000	/* Guardian of a treasure room */
+
+
+#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 CARRYDAGGER	0x50000020	/* carry's a dumb old dagger */
+#define AREMANY		0x50000040	/* they come in droves */
+#define CARRYEYE	0x50000080	/* has the eye of Vecna */
+#define HASSUMMONED	0x50000100	/* has already summoned */
+#define ISSTONE		0x50000200	/* has been turned to stone */
+#define NODETECT	0x50000400	/* detect monster will not show him */
+#define NOSTONE		0x50000800	/* creature made its save vrs stone */
+#define CARRYQUILL	0x50001000	/* has the quill of Nagrom */
+#define CARRYAXE	0x50002000	/* has the axe of Aklad */
+#define TOUCHSLOW	0x50004000	/* touch will slow hero */
+#define WASDISRUPTED	0x50008000	/* creature was disrupted by player */
+#define	CARRYARMOR	0x50010000	/* creature will pick up armor */
+#define CARRYBAMULET	0x50020000	/* amulet of skoraus stonebones */
+#define CARRYSURTURRING	0x50040000	/* ring of Surtur */
+#define	ISCHARMED	0x50080000	/* is the monster charmed? */
+#define	ISFRIENDLY	0x50080000	/* monster friendly for any reason? */
+
+#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	| \
+			CARRYMDAGGER	| CARRYCLOAK	| CARRYANKH	| \
+			CARRYSTAFF	| CARRYWAND	| CARRYROD	| \
+			CARRYYAMULET	| CARRYMANDOLIN | ISGUARDIAN )
+#define CANC5MASK (	CARRYHORN	| CARRYMSTAR 	| CARRYFLAIL	| \
+			CARRYEYE	| CARRYDAGGER	| HASSUMMONED	| \
+			AREMANY		| CARRYWEAPON	| NOSTONE	| \
+			CARRYQUILL	| CARRYAXE	| WASDISRUPTED	| \
+			CARRYARMOR	| CARRYBAMULET 	| CARRYSURTURRING )
+#define CANC6MASK ( 0 )
+#define CANC7MASK ( 0 )
+#define CANC8MASK ( 0 )
+#define CANC9MASK ( 0 )
+#define CANCAMASK ( 0 )
+#define CANCBMASK ( 0 )
+#define CANCCMASK ( 0 )
+#define CANCDMASK ( 0 )
+#define CANCEMASK ( 0 )
+#define CANCFMASK ( 0 )
+
+/* 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
+/*
+ * food types
+ */
+#define E_RATION	0
+#define E_APPLE		1
+#define E_BANANA	2
+#define E_BLUEBERRY	3
+#define E_CANDLEBERRY	4
+#define E_CAPRIFIG	5
+#define E_DEWBERRY	6
+#define E_ELDERBERRY	7
+#define E_GOOSEBERRY	8
+#define E_GUANABANA	9
+#define E_HAGBERRY	10
+#define E_JABOTICABA	11
+#define E_PEACH		12
+#define E_PITANGA	13
+#define E_PRICKLEY	14
+#define E_RAMBUTAN	15
+#define E_SAPODILLA	16
+#define E_SOURSOP	17
+#define E_STRAWBERRY	18
+#define E_SWEETSOP	19
+#define E_WHORTLEBERRY	20
+#define	MAXFOODS	21
+/*
+ * 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 P_FFIND		12
+#define P_SKILL		13
+#define P_FIRE		14
+#define P_COLD		15
+#define P_LIGHTNING	16
+#define P_POISON	17
+#define	MAXPOTIONS	18
+/*
+ * 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 S_FINDTRAPS	17
+#define S_RUNES		18
+#define S_CHARM		19
+#define	MAXSCROLLS	20
+
+/*
+ * 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_CARRY		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 R_FREEDOM	24
+#define R_TELCONTROL	25
+#define	MAXRINGS	26
+
+/*
+ * 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 EYE_VECNA		11
+#define AXE_AKLAD		12
+#define QUILL_NAGROM		13
+#define STONEBONES_AMULET	14
+#define	SURTUR_RING		15
+#define MAXRELIC		16
+
+
+#define LEVEL  600
+#define vlevel max(level, turns/LEVEL + 1)
+/*
+ * Now we define the structures and types
+ */
+/*
+ * character types
+ */
+struct character_types {
+    char	name[40];	/* name of character class		*/
+    long	start_exp;	/* starting exp pts for 2nd level	*/
+    long	cap;		/* stop doubling here			*/
+    int		hit_pts;	/* hit pts gained per level		*/
+    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	*/
+};
+
+/*
+ * level types
+ */
+typedef enum {
+	NORMLEV,	/* normal level */
+	POSTLEV,	/* trading post level */
+	MAZELEV,	/* maze level */
+	OUTSIDE,	/* outside level */
+	STARTLEV	/* beginning of the game */
+} 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_lvladj;			/* how much level is adjusted */
+    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 */
+    short s_dex;			/* dexterity */
+    short s_move;			/* movement rate */
+    unsigned long s_exp;		/* Experience */
+    short s_lvl;			/* Level of mastery */
+    short 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_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 */
+    short t_movement;			/* Base movement rate */
+    short t_action;			/* Action we're waiting to do */
+    short t_artifact;			/* base chance of using artifact */
+    short t_wand;			/* base chance of using wands */
+    short t_summon;			/* base chance of summoning */
+    short t_cast;			/* base chance of casting a spell */
+    short t_breathe;			/* base chance to swing at player */
+    char  *t_name;			/* name player gave his pet */
+    coord *t_doorgoal;			/* What door are we heading to? */
+    coord *t_dest;			/* Where it is running to */
+    coord t_pos;			/* Position */
+    coord t_oldpos;			/* Last position */
+    coord t_newpos;			/* Where we want to go */
+    unsigned long t_flags[16];		/* State word */
+    struct linked_list *t_pack;		/* What the thing is carrying */
+    struct linked_list *t_using;	/* What the thing is using */
+    int t_selection;
+    struct stats t_stats;		/* Physical description */
+    struct stats maxstats;		/* maximum(or initial) stats */
+    int t_reserved;
+};
+
+/*
+ * Array containing information on all the various types of monsters
+ */
+struct monster {
+    char *m_name;			/* What to call the monster */
+    short m_carry;			/* Probability of carrying something */
+    bool m_normal;			/* Does monster exist? */
+    bool m_wander;			/* Does monster wander? */
+    char m_appear;			/* What does monster look like? */
+    char *m_intel;			/* Intelligence range */
+    long m_flags[MAXFLAGS];		/* Things about the monster */
+    char *m_typesum;			/* type of creature can he summon */
+    short m_numsum;			/* how many creatures can he summon */
+    short m_add_exp;			/* Added experience per hit point */
+    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_rate;		/* rate of fire */
+    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 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 quill {
+    short s_which;		/* which scroll to write */
+    short s_cost;		/* cost of writing it */
+};
+
+struct delayed_action {
+	int d_type;
+	int (*d_func)();
+	union {
+	    int arg;
+	    void *varg;
+	} d_;
+	int d_time;
+} ;
+
+struct linked_list	*find_mons(), *find_obj(), *get_item(), *new_item(),
+			*new_thing(), *wake_monster(), *get_hurl(), 
+			*spec_item(), *creat_item(), *wield_weap();
+struct room		*roomin();
+struct trap		*trap_at();
+
+/* char	*malloc(), *getenv(), *tr_name(), *new(), *sprintf(), */
+char	*getenv(), *tr_name(), *new(),
+	*vowelstr(), *inv_name(), *strcpy(), *strcat();
+char	*num(), *ring_num(), *misc_num(), *blesscurse(), *p_kind(),
+	*typ_name(), *prname(), *monster_name(), *weap_name(), *misc_name();
+coord	*rndmove(), *can_shoot(), *fallpos(), *doorway(), get_coordinates();
+short	randmonster(), id_monst(), movement();
+void    quit(int), auto_save(int), bugkill(int), endit(int), tstp(int), 
+        byebye(int);
+int	nohaste(), spell_recovery(),
+	doctor(), runners(), swander(), unconfuse(), unsee(), fumble(),
+	unclrhead(), unphase(), noslow(), rollwand(), stomach(), sight(),
+	unstink(), suffocate(), cure_disease(), shoot_bolt(), changeclass(),
+	appear(), dust_appear(), unchoke(), alchemy(), trap_look(), strangle(),
+	ring_teleport(), ring_search(), grab(), dsrpt_player(), quill_charge(),
+	make_sell_pack(), unskill(), findmindex(), nobolt(), nofire(), nocold(),
+	usage_time(), eat_gold(), chant_recovery(), prayer_recovery(), 
+	dsrpt_monster();
+bool	blue_light(), can_blink(), creat_mons(), add_pack(),
+	straight_shot(), maze_view(), lit_room(), getdelta(), save_file(),
+	save_game(), m_use_it(), m_use_pack(), get_dir(), need_dir();
+long	lseek(), check_level();
+void	genmonsters(), 
+	add_intelligence(), add_strength(), add_wisdom(), add_dexterity(),
+	add_constitution(), add_charisma(), res_intelligence(), res_strength(int),
+	res_wisdom(), res_dexterity(), res_constitution(), res_charisma();
+
+
+#ifdef CHECKTIME
+int checkout();
+#endif
+
+
+/*
+ * Now all the global variables
+ */
+
+extern struct trap traps[];
+extern struct h_list helpstr[];
+extern struct h_list wiz_help[];
+extern struct character_types char_class[];/* character classes */
+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[NUMMONST+1];	/* 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 magic_item foods[];	/* Names and chances for foods */
+extern struct spells magic_spells[];	/* spells for magic users */
+extern struct spells cleric_spells[];	/* spells for clerics */
+extern struct spells druid_spells[];	/* spells for druids */
+extern struct quill quill_scrolls[];	/* scrolls for quill */
+extern char *cnames[][17];		/* Character level names */
+extern char *abilities[NUMABILITIES];	/* Names of the various abilities */
+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 cols;			/* number of columns on terminal */
+extern int lines;			/* number of lines in terminal */
+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 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 hold_count;			/* Number of monsters holding player */
+extern int trap_tries;			/* Number of attempts to set traps */
+extern int chant_time;			/* Number of chant points/exp level */
+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[];			/* 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;			/* Message window */
+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 menu_overlay;		/* use overlay type menu */
+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 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 void (*add_abil[NUMABILITIES])(); /* Functions to change abilities */
+extern void (*res_abil[NUMABILITIES])(); /* Functions to change abilities */
+extern int  cNCOLORS, cNWOOD, cNMETAL, cNSTONES;
+extern char *rainbow[], *stones[], *wood[], *metal[];
+extern int  land(), wghtchk(), undance(), cloak_charge(struct object *);
+extern struct delayed_action d_list[MAXDAEMONS];
+extern struct delayed_action f_list[MAXFUSES];
+extern int demoncnt, fusecnt, between, chance;
+#define CCHAR(x) ( (char) (x & A_CHARTEXT) )
+extern char *md_gethostname(), *md_getusername(), *md_gethomedir(), *md_getroguedir(), *md_crypt();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/rooms.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,295 @@
+/*
+ * rooms.c - Draw the nine rooms on the screen
+ *
+ * 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.
+ */
+
+/*
+ * Draw the nine rooms on the screen
+ *
+ */
+
+#include "curses.h"
+#include "rogue.h"
+
+do_rooms()
+{
+    register int i;
+    register struct room *rp;
+    register struct linked_list *item;
+    register struct thing *tp;
+    int left_out;
+    int num_monsters;
+    int which_monster;
+    int j;
+    coord top;
+    coord bsze;
+    coord mp;
+    coord *np;
+
+    /*
+     * 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();
+		abort();
+	    }
+	}
+
+	/*
+	 * Put the monster in
+	 */
+	if (rnd(100) < (has_gold ? 80 : 25) + vlevel/2)
+	{
+	    do
+	    {
+		rnd_pos(rp, &mp);
+	    } until(mvwinch(stdscr, mp.y, mp.x) == FLOOR);
+	    which_monster = randmonster(FALSE, FALSE);
+	    num_monsters = 1;
+	    /*
+	     * see if we should make a whole bunch
+	     */
+	    for (j=0; j<MAXFLAGS; j++) {
+		if (monsters[which_monster].m_flags[j] == AREMANY)
+			num_monsters = roll(3,3);
+	    }
+	    for (j=0; j<num_monsters; j++) {
+		    if ((np = fallpos(&mp, FALSE, 2)) != NULL &&
+			 mvwinch(stdscr, np->y, np->x) == FLOOR) {
+			    item = new_item(sizeof *tp);
+			    tp = THINGPTR(item);
+			    new_monster(item, which_monster, np, FALSE);
+			    /*
+			     * See if we want to give it a treasure to 
+			     * carry around.
+			     */
+			    carry_obj(tp, monsters[tp->t_index].m_carry);
+			    tp->t_no_move = movement(tp);
+
+			    /*
+			     * 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;
+			    }
+		    }
+	    }
+	}
+    }
+}
+
+/*
+ * Given a room pointer and a pointer to a door, supposedly in that room,
+ * return the coordinates of the entrance to the doorway.
+ */
+
+coord *
+doorway(rp, door)
+register struct room *rp;
+register coord *door;
+{
+    register int misses = 0;
+    static coord answer;
+
+    /* Do we have decent parameters? */
+    if (rp == NULL || door == NULL) return(NULL);
+
+    /* Initialize the answer to be the door, then calculate the offset */
+    answer = *door;
+
+    /* Calculate the x-offset */
+    if (door->x == rp->r_pos.x) answer.x++;
+    else if (door->x == rp->r_pos.x + rp->r_max.x - 1) answer.x--;
+    else misses++;
+
+    /* Calculate the y-offset */
+    if (door->y == rp->r_pos.y) answer.y++;
+    else if (door->y == rp->r_pos.y + rp->r_max.y - 1) answer.y--;
+    else misses++;
+
+    if (misses <= 1) return(&answer);
+    else return(NULL);
+}
+
+/*
+ * 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/arogue7/save.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,302 @@
+/*
+ * save.c - save and restore routines
+ *
+ * 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.
+ */
+
+/*
+ * save and restore routines
+ *
+ */
+
+#include "curses.h"
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <signal.h>
+#include "rogue.h"
+#include <fcntl.h>
+#include <errno.h>
+#include "mach_dep.h"
+#ifdef PC7300
+#include "sys/window.h"
+extern struct uwdata wdata;
+#endif
+
+#if u370 || uts
+#define ENCREAD(b,n,fd) read(fd,b,n)
+#define ENCWRITE(b,n,fd) write(fd,b,n)
+#endif
+#ifndef ENCREAD
+#define ENCREAD encread
+#define ENCWRITE encwrite
+#endif
+
+typedef struct stat STAT;
+
+extern char version[], encstr[];
+/* extern bool _endwin; */
+extern int errno;
+
+STAT sbuf;
+
+bool
+save_game()
+{
+    register int savefd;
+    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, msgw) == QUIT)
+	{
+	    msg("");
+	    return FALSE;
+	}
+	strcpy(file_name, buf);
+gotfile:
+	if ((savefd = open(file_name, O_WRONLY|O_CREAT|O_TRUNC,0666)) < 0)
+	    msg(strerror(errno));	/* fake perror() */
+    } while (savefd < 0);
+
+    /*
+     * write out encrpyted file (after a stat)
+     */
+    if (save_file(savefd) == FALSE) {
+	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(sig)
+int sig;
+{
+    register int savefd;
+    register int i;
+
+    for (i = 0; i < NSIG; i++)
+	signal(i, SIG_IGN);
+    if (file_name[0] != '\0'	&& 
+	pstats.s_hpt > 0	&&
+	(savefd = open(file_name, O_WRONLY|O_CREAT|O_TRUNC, 0600)) >= 0)
+	save_file(savefd);
+    endwin();
+#ifdef PC7300
+    endhardwin();
+#endif
+    exit(1);
+}
+
+/*
+ * write the saved game on the file
+ */
+bool
+save_file(savefd)
+register int savefd;
+{
+    register unsigned num_to_write, num_written;
+    FILE *savef;
+    int ret;
+
+    wmove(cw, lines-1, 0);
+    draw(cw);
+    lseek(savefd, 0L, 0);
+    fstat(savefd, &sbuf);
+    num_to_write = strlen(version) + 1;
+    num_written = ENCWRITE(version, num_to_write, savefd);
+    sprintf(prbuf,"%d x %d\n", LINES, COLS);
+    ENCWRITE(prbuf,80,savefd);
+    savef = (FILE *) fdopen(savefd,"wb");
+    ret = rs_save_file(savef);
+    fclose(savef);
+    if (num_to_write == num_written && ret == 0) return(TRUE);
+    else return(FALSE);
+}
+
+restore(file, envp)
+register char *file;
+char **envp;
+{
+    register int inf;
+    extern char **environ;
+    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, 0)) < 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);
+
+    initscr();
+ 
+    if (COLS < oldcol || LINES < oldline) {
+	endwin();
+	printf("Cannot restart the game on a smaller screen.\n");
+	return FALSE;
+    }
+
+    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);
+
+    if (rs_restore_file(inf) != 0)
+    {
+	printf("Cannot restore file\n");
+	close(inf);
+	return(FALSE);
+    }
+
+    cols = COLS;
+    lines = LINES;
+    if (cols > 85) cols = 85;
+    if (lines > 24) lines = 24;
+
+    mpos = 0;
+    mvwprintw(msgw, 0, 0, "%s: %s", file, ctime(&sbuf2.st_mtime));
+
+    /*
+     * defeat multiple restarting from the same place
+     */
+    if (!wizard && md_unlink_open_file(file, inf) < 0) {
+	printf("Cannot unlink file\n");
+	return FALSE;
+    }
+
+    environ = envp;
+    strcpy(file_name, file);
+    setup();
+    clearok(curscr, TRUE);
+    touchwin(cw);
+    srand(getpid());
+    playit();
+    /*NOTREACHED*/
+    return(0);
+}
+
+#define ENCWBSIZ	1024
+/*
+ * perform an encrypted write
+ */
+encwrite(start, size, outf)
+register char *start;
+register unsigned size;
+register int outf;
+{
+    register char *ep;
+    register int i = 0;
+    int	num_written = 0;
+    auto char buf[ENCWBSIZ];
+
+    ep = encstr;
+
+    while (size--)
+    {
+	buf[i++] = *start++ ^ *ep++ ;
+	if (*ep == '\0')
+ 	   ep = encstr;
+
+	if (i == ENCWBSIZ || size == 0) {
+	    if (write(outf, buf, (unsigned)i) < i) 
+		 return(num_written);
+	    else {
+		num_written += i;
+		i = 0;
+	    }
+	}
+    }
+    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/arogue7/scrolls.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,841 @@
+/*
+ * scrolls.c - Functions for dealing with scrolls
+ *
+ * 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.
+ */
+
+/*
+ * Read a scroll and let it happen
+ *
+ */
+
+#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 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;
+
+    which_monst = makemonster(FALSE, "Genocide", "wipe out");
+    if (which_monst <= 0) {
+	msg("");
+	return;
+    }
+
+    /* 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, TRUE);
+	}
+    }
+
+    /* 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, *nobj;
+    register struct linked_list *item, *nitem;
+    register int i,j;
+    register char ch, nch;
+    bool cursed, blessed;
+
+    blessed = FALSE;
+    cursed = FALSE;
+    item = NULL;
+
+    if (which < 0) {
+	if (on(player, ISBLIND)) {
+	    msg("You can't see to read anything");
+	    return;
+	}
+	if (on(player, ISINWALL)) {
+	    msg("You can't see the scroll while inside rock!");
+	    return;
+	}
+
+	/* This is a scroll or book. */
+	if (player.t_action != C_READ) {
+	    int units;
+
+	    item = get_item(pack, "read", READABLE, FALSE, FALSE);
+
+	    /*
+	     * Make certain that it is somethings that we want to read
+	     */
+	    if (item == NULL)
+		return;
+
+	    /* How long does it take to read? */
+	    units = usage_time(item);
+	    if (units < 0) return;
+
+	    player.t_using = item;	/* Remember what it is */
+	    player.t_no_move = units * movement(&player);
+	    if ((OBJPTR(item))->o_type == SCROLL) player.t_action = C_READ;
+	    else player.t_action = C_USE;
+	    return;
+	}
+
+	/* We have waited our time, let's quaff the potion */
+	item = player.t_using;
+	player.t_using = NULL;
+	player.t_action = A_NIL;
+
+	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(TRUE, TRUE);
+		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.");
+		    player.t_no_move += movement(&player)*(4 + rnd(SLEEPTIME));
+		    player.t_action = A_FREEZE;
+		}
+	    }
+	    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 += movement(th)*(SLEEPTIME+4);
+				    th->t_action = A_FREEZE;
+				    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
+	     */
+	    {
+		int gtotal = 0;
+
+		wclear(hw);
+		for (nitem = lvl_obj; nitem != NULL; nitem = next(nitem)) {
+		    nobj = OBJPTR(nitem);
+		    if (nobj->o_type == GOLD) {
+			gtotal += nobj->o_count;
+			mvwaddch(hw, nobj->o_pos.y, nobj->o_pos.x, GOLD);
+		    }
+		}
+		for (nitem = mlist; nitem != NULL; nitem = next(nitem)) {
+		    register struct linked_list *gitem;
+		    register struct thing *th;
+
+		    th = THINGPTR(nitem);
+		    if (on(*th, NODETECT)) continue;
+		    for(gitem = th->t_pack; gitem != NULL; gitem = next(gitem)){
+			nobj = OBJPTR(gitem);
+			if (nobj->o_type == GOLD) {
+			    gtotal += nobj->o_count;
+			    mvwaddch(hw, th->t_pos.y, th->t_pos.x, GOLD);
+			}
+		    }
+		}
+		if (gtotal) {
+		    if (is_scroll) s_know[S_GFIND] = TRUE;
+		    msg("You begin to feel greedy and you sense gold.");
+		    waddstr(msgw, morestr);
+		    clearok(msgw, FALSE);
+		    draw(msgw);
+		    overlay(hw, cw);
+		    draw(cw);
+		    wait_for(' ');
+		    msg("");
+		    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(TRUE, TRUE);
+	    }
+	    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 {
+		nitem = get_item(pack, "remove the curse on",ALL,FALSE,FALSE);
+		if (nitem != 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(' ');
+	    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,FALSE,FALSE)) != 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, FALSE, FALSE)) != 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:
+				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));
+			    when MM_PROTECT:
+				if (lb->o_ac + howmuch > MAXENCHANT/2) {
+				   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");
+	    }
+	}
+	when S_FINDTRAPS:
+	    for (i=0; i<ntraps; i++) {
+		if (!(traps[i].tr_flags & ISFOUND)) {
+		    traps[i].tr_flags |= ISFOUND;
+		    if (cansee(traps[i].tr_pos.y, traps[i].tr_pos.x))
+			mvwaddch(cw,traps[i].tr_pos.y,traps[i].tr_pos.x,
+				 traps[i].tr_type);
+		}
+	    }
+	    if (ntraps > 0) {
+		msg("You sense the presence of traps");
+		if (is_scroll) s_know[S_FINDTRAPS] = TRUE;
+	    }
+	    else
+		msg(nothing);
+
+	when S_RUNES:
+	{
+		register struct linked_list *sitem;
+
+		msg("The scroll explodes in a ball of fire!");
+		if (on(player, NOFIRE)) {
+			msg("The fire does not seem to affect you");
+			break;
+		}
+		explode(&player);
+		if (pstats.s_hpt <= 0)
+			death(D_SCROLL);
+		for (sitem = pack; sitem != NULL; sitem = nitem) {
+		    nitem = next(sitem); /* in case we delete it */
+		    nobj = OBJPTR(sitem);
+		    /*
+		     * check for loss of all scrolls and give them
+		     * a save versus fire
+		     */
+		    if (nobj->o_type == SCROLL && roll(1,20) < 19) {
+			msg("%s burns up!", inv_name(nobj, TRUE));
+			inpack--;
+			detach(pack, sitem);
+			o_discard(sitem);
+		    }
+		}
+	}
+
+	when S_CHARM:
+	{
+	    bool spots[9];
+	    int x, y, spot, count, numcharmed, something, bonus;
+	    struct linked_list *item;
+	    register struct thing *tp;
+
+	    /* Initialize the places where we look around us */
+	    for (i=0; i<9; i++) spots[i] = FALSE;
+	    count = 0;	/* No spots tried yet */
+	    numcharmed = 0;	/* Nobody charmed yet */
+	    something = 0;	/* Nothing has been seen yet */
+	    bonus = 0;		/* no bonus yet */
+
+	    /* Now look around us randomly for a charmee */
+	    while (count < 9) {
+		do {
+		    spot = rnd(9);
+		} while (spots[spot] == TRUE);
+
+		/* We found a place */
+		count++;
+		spots[spot] = TRUE;
+		y = hero.y - 1 + (spot / 3);
+		x = hero.x - 1 + (spot % 3);
+
+		/* Be sure to stay on the board! */
+		if (x < 0 || x >= cols || (y < 1) || (y >= lines - 2))
+			continue;
+
+		/* Is there a monster here? */
+		if (!isalpha(mvwinch(mw, y, x))) continue;
+
+		/* What kind is it? */
+		item = find_mons(y, x);
+		if (item == NULL) continue;
+
+		tp = THINGPTR(item);
+		if (on(*tp,ISCHARMED) || on(*tp,ISUNIQUE) || on(*tp,ISUNDEAD)) 
+		    continue;
+
+		/* Will the monster be charmed? */
+		if (blessed) bonus -= 3;
+		bonus -= (pstats.s_charisma - 13) / 3;
+		if ((player.t_ctype==C_PALADIN || player.t_ctype==C_RANGER) &&
+		    off(*tp, ISMEAN))
+			bonus -= 3;
+		if (save(VS_MAGIC, tp, bonus)) continue;
+
+		/* We got him! */
+		numcharmed++;
+
+		/* Let the player know (maybe) */
+    		if ((off(*tp, ISINVIS)     || on(player, CANSEE)) &&
+		    (off(*tp, ISSHADOW)    || on(player, CANSEE)) &&
+		    cansee(y, x)) {
+			if (on(*tp, CANSURPRISE)) {
+			    turn_off(*tp, CANSURPRISE);
+			    msg("Woah!");
+			}
+			msg("The eyes of %s glaze over!",
+			    prname(monster_name(tp), FALSE));
+			something++;
+		}
+
+		/* Charm him and turn off any side effects */
+		turn_on(*tp, ISCHARMED);
+		runto(tp, &hero);
+		tp->t_action = A_NIL;
+
+		/* If monster was suffocating us, 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);
+
+		/* If frightened of this monster, stop */
+		if (on(player, ISFLEE) &&
+		    player.t_dest == &tp->t_pos) turn_off(player, ISFLEE);
+
+		if ((blessed && numcharmed >= 2) || numcharmed > 0) break;
+	    }
+
+	    if (something == 0) msg(nothing);
+	}
+
+	otherwise:
+	    msg("What a puzzling scroll!");
+	    return;
+    }
+    look(TRUE, FALSE);	/* put the result of the scroll on the screen */
+    status(FALSE);
+    if (is_scroll && item && s_know[which] && s_guess[which])
+    {
+	free(s_guess[which]);
+	s_guess[which] = NULL;
+    }
+    else if (is_scroll				&& 
+	     !s_know[which]			&& 
+	     item				&&
+	     askme				&&
+	     (obj->o_flags & ISKNOW) == 0	&&
+	     (obj->o_flags & ISPOST) == 0	&&
+	     s_guess[which] == NULL) {
+	nameitem(item, FALSE);
+    }
+    if (item != NULL) o_discard(item);
+    updpack(TRUE, &player);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/state.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,2674 @@
+/*
+    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, fileno(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;
+        case STARTLEV: lt = 5; 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;
+        case 5: *l = STARTLEV; 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_lvladj);
+    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_lvladj);
+    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(savef,i[n].mi_name,sizeof(i[n].mi_name));  */
+        rs_write_int(savef,i[n].mi_prob);
+/*      rs_write_int(savef,i[n].mi_worth);		    */
+/*      rs_write_int(savef,i[n].mi_curse);		    */
+/*      rs_write_int(savef,i[n].mi_bless);		    */
+    }
+    
+    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(inf,mi[n].mi_name,sizeof(mi[n].mi_name));	*/
+	    rs_read_int(inf,&mi[n].mi_prob);
+/*          rs_read_int(inf,&mi[n].mi_worth);			*/
+/*          rs_read_int(inf,&mi[n].mi_curse);			*/
+/*          rs_read_int(inf,&mi[n].mi_bless);			*/
+        }
+    }
+    
+    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,cNCOLORS,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,cNCOLORS,&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,cNSTONES,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,cNSTONES,&r_stones[i]);
+	rs_read_boolean(inf,&r_know[i]);
+        rs_read_new_string(inf,&r_guess[i]);
+    }
+
+    return(READSTAT);
+}
+
+int
+rs_write_misc(FILE *savef)
+{
+    int i;
+
+    if (read_error || format_error)
+        return(READSTAT);
+
+    for(i = 0; i < MAXMM; i++)
+    {
+        rs_write_boolean(savef,m_know[i]);
+        rs_write_string(savef,m_guess[i]);
+    }
+
+    return(READSTAT);
+}
+
+int
+rs_read_misc(int inf)
+{
+    int i;
+
+    if (write_error)
+        return(WRITESTAT);
+
+    for(i = 0; i < MAXMM; i++)
+    {
+        rs_read_boolean(inf,&m_know[i]);
+        rs_read_new_string(inf,&m_guess[i]);
+    }
+
+    return(WRITESTAT);
+}
+
+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,cNWOOD,ws_made[i]);
+        }
+        else
+        {
+            rs_write_int(savef,1);
+	    rs_write_string_index(savef,metal,cNMETAL,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,cNWOOD,&ws_made[i]);
+            ws_type[i] = "staff";
+        }
+        else 
+        {
+	    rs_read_string_index(inf,metal,cNMETAL,&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 == trap_look)
+            func = 4;
+        else if (d_list[i].d_func == eat_gold)
+            func = 5;
+        else if (d_list[i].d_func == ring_search)
+            func = 6;
+        else if (d_list[i].d_func == ring_teleport)
+            func = 7;
+        else if (d_list[i].d_func == fumble)
+            func = 8;
+        else if (d_list[i].d_func == strangle)
+            func = 9;
+        else if (d_list[i].d_func == unconfuse)
+            func = 10;
+        else if (d_list[i].d_func == swander)
+            func = 11;
+        else if (d_list[i].d_func == spell_recovery)
+            func = 12;
+        else if (d_list[i].d_func == chant_recovery)
+            func = 13;
+        else if (d_list[i].d_func == prayer_recovery)
+            func = 14;
+        else if (d_list[i].d_func == cure_disease)
+            func = 15;
+        else if (d_list[i].d_func == unstink)
+            func = 16;
+        else if (d_list[i].d_func == (int (*)()) res_strength)
+            func = 17;
+        else if (d_list[i].d_func == undance)
+            func = 18;
+        else if (d_list[i].d_func == suffocate)
+            func = 19;
+        else if (d_list[i].d_func == wghtchk)
+            func = 20;
+        else if (d_list[i].d_func == dust_appear)
+            func = 21;
+        else if (d_list[i].d_func == unchoke)
+            func = 22;
+        else if (d_list[i].d_func == sight)
+            func = 23;
+        else if (d_list[i].d_func == changeclass)
+            func = 24;
+        else if (d_list[i].d_func == cloak_charge)
+            func = 25;
+        else if (d_list[i].d_func == quill_charge)
+            func = 26;
+        else if (d_list[i].d_func == nohaste)
+            func = 27;
+        else if (d_list[i].d_func == noslow)
+            func = 28;
+        else if (d_list[i].d_func == unclrhead)
+            func = 29;
+        else if (d_list[i].d_func == unsee)
+            func = 30;
+        else if (d_list[i].d_func == unphase)
+            func = 31;
+        else if (d_list[i].d_func == land)
+            func = 32;
+        else if (d_list[i].d_func == appear)
+            func = 33;
+        else if (d_list[i].d_func == unskill)
+            func = 34;
+        else if (d_list[i].d_func == nofire)
+            func = 35;
+        else if (d_list[i].d_func == nocold)
+            func = 36;
+        else if (d_list[i].d_func == nobolt)
+            func = 37;
+        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);
+
+        if (d_list[i].d_func == doctor)
+           rs_write_int(savef, 1);
+        else if (d_list[i].d_func == eat_gold)
+        {
+            int index;
+            index = find_list_ptr(player.t_pack, d_list[i].d_.varg);
+            rs_write_int(savef,index);
+        }
+        else if (d_list[i].d_func == changeclass)
+        {
+            rs_write_int(savef, d_list[i].d_.arg);
+        }
+        else if (d_list[i].d_func == cloak_charge)
+        {
+            int index;
+            index = find_list_ptr(player.t_pack, d_list[i].d_.varg);
+            rs_write_int(savef,index);
+        }
+        else
+            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 = trap_look;
+                     break;
+            case  5: d_list[i].d_func = eat_gold;
+                     break;
+            case  6: d_list[i].d_func = ring_search;
+                     break;
+            case  7: d_list[i].d_func = ring_teleport;
+                     break;
+            case  8: d_list[i].d_func = fumble;
+                     break;
+            case  9: d_list[i].d_func = strangle;
+                     break;
+            case 10: d_list[i].d_func = unconfuse;
+                     break;
+            case 11: d_list[i].d_func = swander;
+                     break;
+            case 12: d_list[i].d_func = spell_recovery;
+                     break;
+            case 13: d_list[i].d_func = chant_recovery;
+                     break;
+            case 14: d_list[i].d_func = prayer_recovery;
+                     break;
+            case 15: d_list[i].d_func = cure_disease;
+                     break;
+            case 16: d_list[i].d_func = unstink;
+                     break;
+            case 17: d_list[i].d_func = (int (*)()) res_strength;
+                     break;
+            case 18: d_list[i].d_func = undance;
+                     break;
+            case 19: d_list[i].d_func = suffocate;
+                     break;
+            case 20: d_list[i].d_func = wghtchk;
+                     break;
+            case 21: d_list[i].d_func = dust_appear;
+                     break;
+            case 22: d_list[i].d_func = unchoke;
+                     break;
+            case 23: d_list[i].d_func = sight;
+                     break;
+            case 24: d_list[i].d_func = changeclass;
+                     break;
+            case 25: d_list[i].d_func = cloak_charge;
+                     break;
+            case 26: d_list[i].d_func = quill_charge;
+                     break;
+            case 27: d_list[i].d_func = nohaste;
+                     break;
+            case 28: d_list[i].d_func = noslow;
+                     break;
+            case 29: d_list[i].d_func = unclrhead;
+                     break;
+            case 30: d_list[i].d_func = unsee;
+                     break;
+            case 31: d_list[i].d_func = unphase;
+                     break;
+            case 32: d_list[i].d_func = land;
+                     break;
+            case 33: d_list[i].d_func = appear;
+                     break;
+            case 34: d_list[i].d_func = unskill;
+                     break;
+            case 35: d_list[i].d_func = nofire;
+                     break;
+            case 36: d_list[i].d_func = nocold;
+                     break;
+            case 37: d_list[i].d_func = nobolt;
+                     break;
+	    case  0:
+            case -1:
+            default: d_list[i].d_func = NULL;
+                     break;
+        }
+
+        if (d_list[i].d_func == doctor)
+        {
+	    rs_read_int(inf, &dummy);
+            d_list[i].d_.varg = &player;
+        }
+        else if (d_list[i].d_func == eat_gold)
+        {
+	    rs_read_int(inf, &dummy);
+            d_list[i].d_.varg = get_list_item(player.t_pack, dummy);
+            if (d_list[i].d_.varg == NULL)
+		d_list[i].d_type = 0;
+	}
+        else if (d_list[i].d_func == changeclass)
+        {
+	    rs_read_int(inf, &d_list[i].d_.arg);
+        }
+        else if (d_list[i].d_func == cloak_charge)
+        {
+	    rs_read_int(inf, &dummy);
+            d_list[i].d_.varg = get_list_item(player.t_pack,dummy);
+
+	    if (d_list[i].d_.varg == NULL)
+		d_list[i].d_type = 0;
+        }
+        else
+	    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_.varg = NULL;
+	    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);
+}
+
+int
+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_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_short(savef, t->t_movement);
+    rs_write_short(savef, t->t_action);
+    rs_write_short(savef, t->t_artifact);
+    rs_write_short(savef, t->t_wand);
+    rs_write_short(savef, t->t_summon);
+    rs_write_short(savef, t->t_cast);
+    rs_write_short(savef, t->t_breathe);
+
+    rs_write_string(savef,t->t_name);
+    rs_write_door_reference(savef, t->t_doorgoal);
+
+    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_coord(savef, t->t_pos);
+    rs_write_coord(savef, t->t_oldpos);
+    rs_write_coord(savef, t->t_newpos);
+    rs_write_ulongs(savef, t->t_flags, 16);
+    rs_write_object_list(savef, t->t_pack);
+    i = -1;
+    if (t->t_using != NULL)
+        i = find_list_ptr(t->t_pack, t->t_using->l_data);
+    rs_write_int(savef, i);
+    rs_write_int(savef, t->t_selection);
+    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_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_short(inf, &t->t_movement);
+    rs_read_short(inf, &t->t_action);
+    rs_read_short(inf, &t->t_artifact);
+    rs_read_short(inf, &t->t_wand);
+    rs_read_short(inf, &t->t_summon);
+    rs_read_short(inf, &t->t_cast);
+    rs_read_short(inf, &t->t_breathe);
+    rs_read_new_string(inf,&t->t_name);
+    rs_read_door_reference(inf,&t->t_doorgoal);
+
+    rs_read_int(inf,&listid);
+    rs_read_int(inf,&index);
+    t->t_reserved = -1;
+    if (listid == 0)
+    {
+	if (index == 1)
+	    t->t_dest = &hero;
+        else
+	    t->t_dest = NULL;
+    }
+    else if (listid == 1)
+    {
+	t->t_dest     = NULL;
+        t->t_reserved = index;
+    }
+    else if (listid == 2)
+    {
+	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_coord(inf,&t->t_pos);
+    rs_read_coord(inf,&t->t_oldpos);
+    rs_read_coord(inf,&t->t_newpos);
+    rs_read_ulongs(inf,t->t_flags,16);
+    rs_read_object_list(inf,&t->t_pack);
+    rs_read_int(inf,&index);
+    t->t_using = get_list_item(t->t_pack, index);
+    rs_read_int(inf, &t->t_selection);
+    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_write_thing_reference(FILE *savef, struct linked_list *list, struct thing *item)
+{
+    int i;
+
+    if (write_error)
+        return(WRITESTAT);
+
+    if (item == NULL)
+        rs_write_int(savef,-1);
+    else
+    {
+        i = find_list_ptr(list, item);
+
+        rs_write_int(savef, i);
+    }
+
+    return(WRITESTAT);
+}
+
+int
+rs_read_thing_reference(int inf, struct linked_list *list, struct thing **item)
+{
+    int i;
+    
+    if (read_error || format_error)
+        return(READSTAT);
+
+    rs_read_int(inf, &i);
+
+    if (i == -1)
+        *item = NULL;
+    else
+        *item = get_list_item(list,i);
+
+    return(READSTAT);
+}
+
+int
+rs_write_thing_references(FILE *savef, struct linked_list *list, struct thing *items[], int count)
+{
+    int i;
+
+    if (write_error)
+        return(WRITESTAT);
+
+    for(i = 0; i < count; i++)
+        rs_write_thing_reference(savef,list,items[i]);
+
+    return(WRITESTAT);
+}
+
+int
+rs_read_thing_references(int inf, struct linked_list *list, struct thing *items[], int count)
+{
+    int i;
+
+    if (read_error || format_error)
+        return(READSTAT);
+
+    for(i = 0; i < count; i++)
+        rs_read_thing_reference(inf,list,&items[i]);
+
+    return(WRITESTAT);
+}
+
+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,seed);
+    rs_write_int(savef,dnum);
+    rs_write_int(savef,max_level);
+    rs_write_int(savef,cur_max);
+    rs_write_int(savef,mpos);
+    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,chant_time);
+    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_int(savef,cols);
+    rs_write_int(savef,lines);
+    rs_write_char(savef,nfloors);
+    rs_write(savef,curpurch,LINELEN);
+    rs_write_char(savef,PLAYER);
+    rs_write_char(savef,take);
+    rs_write(savef,prbuf,LINELEN*2);
+    rs_write(savef,outbuf,BUFSIZ);
+    rs_write_char(savef,runch);
+    rs_write_scrolls(savef);
+    rs_write_potions(savef);
+    rs_write_rings(savef);
+    rs_write_sticks(savef);
+    rs_write_misc(savef);
+    rs_write(savef,whoami,LINELEN);
+    rs_write(savef,huh,LINELEN);
+    rs_write(savef,file_name,LINELEN);
+    rs_write(savef,score_file,LINELEN);
+    rs_write(savef,home,LINELEN);
+    rs_write_window(savef, cw);
+    rs_write_window(savef, hw);
+    rs_write_window(savef, mw);
+    rs_write_window(savef, msgw);
+    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_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, menu_overlay);
+    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_levtype(savef, levtype);
+    rs_write_magic_items(savef, things,  MAXTHINGS);
+    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_magic_items(savef, rel_magic, MAXRELIC);
+    rs_write_magic_items(savef, foods, MAXFOODS);
+
+    rs_write_monsters(savef, monsters, NUMMONST+1);
+
+    rs_write_daemons(savef, d_list, MAXDAEMONS);
+    rs_write_daemons(savef, f_list, MAXFUSES);
+    rs_write_int(savef, demoncnt);
+    rs_write_int(savef, fusecnt);
+
+    rs_write_int(savef, between);
+
+    rs_write_int(savef, chance);
+
+    return(WRITESTAT);
+}
+
+int
+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,&seed);
+    rs_read_int(inf,&dnum);
+    rs_read_int(inf,&max_level);
+    rs_read_int(inf,&cur_max);
+    rs_read_int(inf,&mpos);
+    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,&chant_time);
+    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_int(inf,&cols);
+    rs_read_int(inf,&lines);
+    rs_read_char(inf,&nfloors);
+    rs_read(inf,curpurch,LINELEN);
+    rs_read_char(inf,&PLAYER);
+    rs_read_char(inf,&take);
+    rs_read(inf,prbuf,LINELEN*2);
+    rs_read(inf,outbuf,BUFSIZ);
+    rs_read_char(inf,&runch);
+    rs_read_scrolls(inf);
+    rs_read_potions(inf);
+    rs_read_rings(inf);
+    rs_read_sticks(inf);
+    rs_read_misc(inf);
+    rs_read(inf,whoami,LINELEN);
+    rs_read(inf,huh,LINELEN);
+    rs_read(inf,file_name,LINELEN);
+    rs_read(inf,score_file,LINELEN);
+    rs_read(inf,home,LINELEN);
+    rs_read_window(inf, cw);
+    rs_read_window(inf, hw);
+    rs_read_window(inf, mw);
+    rs_read_window(inf, msgw);
+    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_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, &menu_overlay);
+    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_levtype(inf, &levtype);
+    rs_read_magic_items(inf, things, MAXTHINGS);
+    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_magic_items(inf, rel_magic, MAXRELIC);
+    rs_read_magic_items(inf, foods, MAXFOODS);
+    rs_read_monsters(inf, monsters, NUMMONST + 1);
+
+    rs_read_daemons(inf, d_list, MAXDAEMONS);
+    rs_read_daemons(inf, f_list, MAXFUSES);
+    rs_read_int(inf, &demoncnt);
+    rs_read_int(inf, &fusecnt);
+
+    rs_read_int(inf, &between);
+
+    rs_read_int(inf, &chance);
+
+    return(READSTAT);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/sticks.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,1247 @@
+/*
+ * sticks.c - Functions to implement the various sticks one might find
+ *
+ * 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.
+ */
+
+/*
+ * Functions to implement the various sticks one might find
+ * while wandering around the dungeon.
+ */
+
+#include "curses.h"
+#include <ctype.h>
+#include "rogue.h"
+
+
+/*
+ * zap a stick and see what happens
+ */
+do_zap(zapper, obj, direction, which, flags)
+struct thing *zapper;
+struct object *obj;
+coord *direction;
+int which;
+int flags;
+{
+    register struct linked_list *item;
+    register struct thing *tp;
+    register int y, x, bonus;
+    struct linked_list *nitem;
+    struct object *nobj;
+    bool cursed, blessed, is_player;
+    char *mname;
+
+    cursed = flags & ISCURSED;
+    blessed = flags & ISBLESSED;
+
+    if (obj && obj->o_type != RELIC) { /* all relics are chargeless */
+	if (obj->o_charges < 1) {
+	    msg(nothing);
+	    return;
+	}
+        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;
+	}
+    }
+
+    tp = NULL;
+    switch (which) {
+	case WS_POLYMORPH:
+	case WS_SLOW_M:
+	case WS_TELMON:
+	case WS_CANCEL:
+	case WS_CONFMON:
+	case WS_DISINTEGRATE:
+	case WS_PETRIFY:
+	case WS_PARALYZE:
+	case WS_MDEG:
+	case WS_FEAR:
+	    y = zapper->t_pos.y;
+	    x = zapper->t_pos.x;
+
+	    do {
+		y += direction->y;
+		x += direction->x;
+	    }
+	    while (shoot_ok(winat(y, x)) && !(y == hero.y && x == hero.x));
+
+	    if (y == hero.y && x == hero.x)
+		is_player = TRUE;
+	    else if (isalpha(mvwinch(mw, y, x))) {
+		item = find_mons(y, x);
+		tp = THINGPTR(item);
+		runto(tp, &hero);
+		turn_off(*tp, CANSURPRISE);
+		mname = monster_name(tp);
+		is_player = FALSE;
+
+		/* The monster may not like being shot at */
+		if ((zapper == &player)	&&
+		    on(*tp, ISCHARMED)	&&
+		    save(VS_MAGIC, tp, 0)) {
+		    msg("The eyes of %s turn clear.", prname(mname, FALSE));
+		    turn_off(*tp, ISCHARMED);
+		    mname = monster_name(tp);
+		}
+	    }
+	    else {
+		/*
+		 * if monster misses player because the player dodged then lessen
+		 * the chances he will use the wand again since the player appears
+		 * to be rather dextrous
+		 */
+		if (zapper != &player) 
+		    zapper->t_wand = zapper->t_wand * 3 / 4;
+	    }
+    }
+    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.");
+	    }
+	    else if (cursed)
+		pstats.s_hpt /= 2;
+	    else
+		drain(hero.y-1, hero.y+1, hero.x-1, hero.x+1);
+
+	when WS_POLYMORPH:
+	{
+	    register char oldch;
+	    register struct room *rp;
+	    register struct linked_list *pitem;
+	    coord delta;
+
+	    if (tp == NULL)
+		break;
+	    if (save(VS_MAGIC, tp, 0)) {
+		msg(nothing);
+		break;
+	    }
+	    rp = roomin(&tp->t_pos);
+	    check_residue(tp);
+	    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;
+	    if (isalpha(mvwinch(cw, y, x)))
+		mvwaddch(cw, y, x, tp->t_type);
+	    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);
+		}
+	    }
+	    runto(tp, &hero);
+	    msg(terse ? "A new %s!" 
+		      : "You have created a new %s!",
+		      monster_name(tp));
+        }
+
+	when WS_PETRIFY:
+	    if (tp == NULL)
+		break;
+	    if (save(VS_MAGIC, tp, 0)) {
+		msg(nothing);
+		break;
+	    }
+	    check_residue(tp);
+	    turn_on(*tp, ISSTONE);
+	    turn_on(*tp, NOSTONE);
+	    turn_off(*tp, ISRUN);
+	    turn_off(*tp, ISINVIS);
+	    turn_off(*tp, CANSURPRISE);
+	    turn_off(*tp, ISDISGUISE);
+	    tp->t_action = A_NIL;
+	    tp->t_no_move = 0;
+	    msg("%s is turned to stone!",prname(mname, TRUE));
+
+	when WS_TELMON:
+	{
+	    register int rm;
+	    register struct room *rp;
+
+	    if (tp == NULL)
+		break;
+	    if (save(VS_MAGIC, tp, 0)) {
+		msg(nothing);
+		break;
+	    }
+	    rp = NULL;
+	    check_residue(tp);
+	    tp->t_action = A_FREEZE; /* creature is disoriented */
+	    tp->t_no_move = 2;
+	    if (cursed) {	/* Teleport monster to player */
+		if ((y == (hero.y + direction->y)) &&
+		    (x == (hero.x + direction->x)))
+			msg(nothing);
+		else {
+		    tp->t_pos.y = hero.y + direction->y;
+		    tp->t_pos.x = hero.x + direction->x;
+		}
+	    }
+	    else if (blessed) {	/* Get rid of monster */
+		killed(item, FALSE, TRUE, TRUE);
+		return;
+	    }
+	    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);
+	    mvwaddch(mw, y, x, ' ');
+	    mvwaddch(mw, tp->t_pos.y, tp->t_pos.x, tp->t_type);
+	    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)) {
+		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);
+		}
+	    }
+	}
+	when WS_CANCEL:
+	    if (tp == NULL)
+		break;
+	    if (save(VS_MAGIC, tp, 0)) {
+		msg(nothing);
+		break;
+	    }
+	    check_residue(tp);
+	    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[5] &= CANC5MASK;
+	    tp->t_flags[6] &= CANC6MASK;
+	    tp->t_flags[7] &= CANC7MASK;
+	    tp->t_flags[8] &= CANC8MASK;
+	    tp->t_flags[9] &= CANC9MASK;
+	    tp->t_flags[10] &= CANCAMASK;
+	    tp->t_flags[11] &= CANCBMASK;
+	    tp->t_flags[12] &= CANCCMASK;
+	    tp->t_flags[13] &= CANCDMASK;
+	    tp->t_flags[14] &= CANCEMASK;
+	    tp->t_flags[15] &= CANCFMASK;
+
+	when WS_MISSILE:
+	{
+	    int dice;
+	    static struct object bolt =
+	    {
+		MISSILE , {0, 0}, "", 0, "", "1d4 " , NULL, 0, WS_MISSILE, 50, 1
+	    };
+
+	    if (!obj)
+		dice = zapper->t_stats.s_lvl;
+	    if (obj->o_type == RELIC)
+		 dice = 15;
+	    else if (EQUAL(ws_type[which], "staff"))
+		 dice = 10;
+	    else
+		 dice = 6;
+	    sprintf(bolt.o_hurldmg, "%dd4", dice);
+	    do_motion(&bolt, direction->y, direction->x, zapper);
+	    if (!hit_monster(unc(bolt.o_pos), &bolt, zapper))
+	       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 */
+
+	    direction->y += hero.y;
+	    direction->x += hero.x;
+	    ch = CCHAR( winat(direction->y, direction->x) );
+	    if (isalpha(ch))
+	    {
+		strike = *obj;
+		strike.o_hplus  = 6;
+		if (EQUAL(ws_type[which], "staff"))
+		    strncpy(strike.o_damage,"3d8",sizeof(strike.o_damage));
+		else
+		    strncpy(strike.o_damage,"2d8",sizeof(strike.o_damage));
+		fight(direction, &strike, FALSE);
+	    }
+	}
+	when WS_SLOW_M:
+	    if (is_player) {
+		add_slow();
+		break;
+	    }
+	    if (tp == NULL)
+		break;
+	    if (cursed) {
+		if (on(*tp, ISSLOW))
+		    turn_off(*tp, ISSLOW);
+		else
+		    turn_on(*tp, ISHASTE);
+		break;
+	    }
+	    if ((on(*tp,ISUNIQUE) && save(VS_MAGIC,tp,0)) || on(*tp,NOSLOW)) {
+		msg(nothing);
+		break;
+	    }
+	    else if (blessed) {
+		turn_off(*tp, ISRUN);
+		turn_on(*tp, ISHELD);
+	    }
+	    /*
+	     * always slow in case he breaks free of HOLD
+	     */
+	    if (on(*tp, ISHASTE))
+		turn_off(*tp, ISHASTE);
+	    else
+		turn_on(*tp, ISSLOW);
+
+	when WS_CHARGE:
+	    if (ws_know[WS_CHARGE] != TRUE && obj)
+		msg("This is a wand of charging.");
+	    nitem = get_item(pack, "charge", STICK, FALSE, FALSE);
+	    if (nitem != NULL) {
+		nobj = OBJPTR(nitem);
+	        if ((++(nobj->o_charges) == 1) && (nobj->o_which == WS_HIT))
+		    fix_stick(nobj);
+		if (blessed) ++(nobj->o_charges);
+	        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:
+	    shoot_bolt(	zapper, zapper->t_pos, *direction, TRUE, D_BOLT, 
+			"lightning bolt", roll(zapper->t_stats.s_lvl,6));
+
+	when WS_FIRE:
+	    shoot_bolt(	zapper, zapper->t_pos, *direction, TRUE, D_BOLT, 
+			"flame", roll(zapper->t_stats.s_lvl,6));
+
+	when WS_COLD:
+	    shoot_bolt(	zapper, zapper->t_pos, *direction, TRUE, D_BOLT, 
+			"ice", roll(zapper->t_stats.s_lvl,6));
+
+	when WS_CONFMON:
+	    if (cursed || is_player) { 
+		if (!save(VS_WAND, &player, 0)) {
+		    dsrpt_player();
+		    confus_player();
+		}
+		else {
+		    if (zapper != &player) zapper->t_wand /= 2;
+		    msg(nothing);
+		}
+	    }
+	    else {
+		if (tp == NULL)
+		    break;
+		if (save(VS_MAGIC, tp, 0) || on(*tp, ISCLEAR))
+		     msg(nothing);
+		else
+		     turn_on (*tp, ISHUH);
+	    }
+	when WS_PARALYZE:
+	    if (is_player || cursed) {
+		if ((obj && obj->o_type==RELIC) || !save(VS_WAND, &player, 0)){
+		    player.t_no_move += 2 * movement(&player) * FREEZETIME;
+		    player.t_action = A_FREEZE;
+		    msg("You can't move.");
+		}
+		else {
+		    if (zapper != &player) zapper->t_wand /= 2;
+		    msg(nothing);
+		}
+	    }
+	    else {
+		if (tp == NULL)
+		    break;
+		bonus = 0;
+		if (blessed) bonus = -3;
+		if (((obj && obj->o_type==RELIC) || !save(VS_WAND,tp,bonus)) &&
+		    off(*tp, NOPARALYZE)) {
+		    tp->t_no_move += 2 * movement(tp) * FREEZETIME;
+		    tp->t_action = A_FREEZE;
+		}
+		else {
+		    msg(nothing);
+		}
+	    }
+	when WS_FEAR:
+	    if (is_player) {
+		if (!on(player, ISFLEE)		|| 
+		    ISWEARING(R_HEROISM)	|| 
+		    save(VS_WAND, &player, 0)) {
+			msg(nothing);
+			zapper->t_wand /= 2;
+		}
+		else {
+		    turn_on(player, ISFLEE);
+		    player.t_dest = &zapper->t_pos;
+		    msg("The sight of %s terrifies you.", prname(mname, FALSE));
+		}
+		break;
+	    }
+	    if (tp == NULL)
+		break;
+	    bonus = 0;
+	    if (blessed) bonus = -3;
+	    if(save(VS_WAND, tp,bonus) || on(*tp,ISUNDEAD) || on(*tp,NOFEAR)){
+		    msg(nothing);
+		    break;
+	    }
+	    turn_on(*tp, ISFLEE);
+	    turn_on(*tp, WASTURNED);
+
+	    /* Stop it from attacking us */
+	    dsrpt_monster(tp, TRUE, cansee(tp->t_pos.y, tp->t_pos.x));
+
+	    /* 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);
+
+	    /* It is okay to turn tail */
+	    tp->t_oldpos = tp->t_pos;
+
+	when WS_MDEG:
+	    if (is_player) {
+		if (save(VS_WAND, &player, 0)) {
+		    msg (nothing);
+		    zapper->t_wand /= 2;
+		    break;
+		}
+		pstats.s_hpt /= 2;
+		if (pstats.s_hpt <= 0) {
+		    msg("Your life has been sucked from you -- More --");
+		    wait_for(' ');
+		    death(zapper);
+		}
+		else
+		    msg("You feel a great drain on your system");
+	    }
+	    if (tp == NULL)
+		break;
+	    if (cursed) {
+		 tp->t_stats.s_hpt *= 2;
+		 msg("%s appears to be stronger now!", prname(mname, TRUE));
+	    }
+	    else if (on(*tp, ISUNIQUE) && save(VS_WAND, tp, 0))
+		 msg (nothing);
+	    else {
+		 tp->t_stats.s_hpt /= 2;
+		 msg("%s appears to be weaker now", prname(mname, TRUE));
+	    }
+	    if (tp->t_stats.s_hpt < 1)
+		 killed(item, TRUE, TRUE, TRUE);
+	when WS_DISINTEGRATE:
+	    if (tp == NULL)
+		break;
+	    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++) {
+			if (m1 == hero.x && m2 == hero.y)
+			    continue;
+			ch = CCHAR( winat(m2,m1) );
+			if (shoot_ok(ch)) {
+			    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 */
+		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, TRUE);
+			 msg("You have disintegrated %s", prname(mname, FALSE));
+		    }
+		    else {
+			msg("%s appears wounded", prname(mname, TRUE));
+		    }
+		}
+		else {
+		    msg("You have disintegrated %s", prname(mname, FALSE));
+		    killed (item, FALSE, TRUE, TRUE);
+		}
+	    }
+	when WS_CURING:
+	    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) || on(player, HASINFEST)) {
+		    extinguish(cure_disease);
+		    turn_off(player, HASINFEST);
+		    infest_dam = 0;
+		    cure_disease(); /* this prints message */
+		}
+		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!");
+    }
+}
+
+
+/*
+ * 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, TRUE);
+		else {
+		    runto(ick, &hero);
+
+		    /* 
+		     * The monster may not like being shot at.  Since the
+		     * shot is not aimed directly at the monster, we will
+		     * give him a poorer save.
+		     */
+		    if (on(*ick, ISCHARMED) && save(VS_MAGIC, ick, -2)) {
+			msg("The eyes of %s turn clear.",
+			    prname(monster_name(ick), FALSE));
+			turn_off(*ick, ISCHARMED);
+		    }
+		    if (cansee(i,j) && (!on(*ick,ISINVIS)||on(player,CANSEE)))
+			    msg("%s appears wounded", 
+				prname(monster_name(ick), TRUE));
+		}
+	    }
+	}
+    }
+}
+
+/*
+ * 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);
+	strncpy(cur->o_damage, "2d3", sizeof(cur->o_damage));
+	cur->o_hplus = 1;
+	cur->o_dplus = 0;
+	switch (cur->o_which) {
+	    case WS_HIT:
+		cur->o_hplus = 3;
+		cur->o_dplus = 3;
+		strncpy(cur->o_damage, "2d8", sizeof(cur->o_damage));
+	    when WS_LIGHT:
+		cur->o_charges = 20 + rnd(10);
+	    }
+    }
+    else {
+	strncpy(cur->o_damage, "1d3", sizeof(cur->o_damage));
+	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;
+		strncpy(cur->o_damage, "1d8", sizeof(cur->o_damage));
+	    when WS_LIGHT:
+		cur->o_charges = 10 + rnd(10);
+	    }
+    }
+    strncpy(cur->o_hurldmg, "1d1", sizeof(cur->o_hurldmg));
+
+}
+
+/*
+ * Use the wand that our monster is wielding.
+ */
+m_use_wand(monster)
+register struct thing *monster;
+{
+    register struct object *obj;
+
+    /* Make sure we really have it */
+    if (monster->t_using) 
+	obj = OBJPTR(monster->t_using);
+    else {
+	debug("Stick not set!");
+	monster->t_action = A_NIL;
+	return;
+    }
+
+    if (obj->o_type != STICK) {
+	debug("Stick not selected!");
+	monster->t_action = A_NIL;
+	return;
+    }
+    /*
+     * shoot the stick!
+     * assume all blessed sticks are normal for now. 
+     * Note that we don't get here if the wand is cursed.
+     */
+    msg("%s points a %s at you!", prname(monster_name(monster), TRUE),
+	ws_type[obj->o_which]);
+    do_zap(monster, obj, &monster->t_newpos, obj->o_which, NULL);
+    monster->t_wand /= 2; /* chance lowers with each use */
+}
+
+bool
+need_dir(type, which)
+int	type,		/* type of item, NULL means stick */
+	which;		/* which item			  */
+{
+    if (type == STICK || type == 0) {
+	switch (which) {
+	    case WS_LIGHT:
+	    case WS_DRAIN: 
+	    case WS_CHARGE:
+	    case WS_CURING:
+		return(FALSE);
+	    default:
+		return(TRUE);
+	}
+    }
+    else if (type == RELIC) {
+	switch (which) {
+	    case MING_STAFF:
+	    case ASMO_ROD:
+	    case EMORI_CLOAK:
+		return(TRUE);
+	    default:
+		return(FALSE);
+	}
+    }
+return (FALSE); /* hope we don't get here */
+}
+/*
+ * let the player zap a stick and see what happens
+ */
+player_zap(which, flag)
+int which;
+int flag;
+{
+    register struct linked_list *item;
+    register struct object *obj;
+
+    obj = NULL;
+    if (which == 0) {
+	/* This is a stick.  It takes 2 movement periods to zap it */
+	if (player.t_action != C_ZAP) {
+	    if ((item = get_item(pack,"zap with",ZAPPABLE,FALSE,FALSE)) == NULL)
+		return(FALSE);
+
+	    obj = OBJPTR(item);
+
+	    if (need_dir(obj->o_type, obj->o_which)) {
+		if (!get_dir(&player.t_newpos))
+		    return(FALSE);
+	    }
+	    player.t_using = item;	/* Remember what it is */
+	    player.t_action = C_ZAP;	/* We are quaffing */
+	    player.t_no_move = 2 * movement(&player);
+	    return(TRUE);
+	}
+
+	item = player.t_using;
+	/* We've waited our time, let's shoot 'em up! */
+	player.t_using = NULL;
+	player.t_action = A_NIL;
+
+	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 EMORI_CLOAK:
+		    which = WS_PARALYZE;
+		    obj->o_charges = 0; /* one zap/day(whatever that is) */
+		    fuse(cloak_charge, obj, CLOAK_TIME, AFTER);
+		when ASMO_ROD:
+		    switch (rnd(3)) {
+			case 0:		which = WS_ELECT;
+			when 1:		which = WS_COLD;
+			otherwise:	which = WS_FIRE;
+		    }
+	    }
+	}
+	else {
+	    which = obj->o_which;
+	    ws_know[which] = TRUE;
+	    flag = obj->o_flags;
+	}
+    }
+    do_zap(&player, obj, &player.t_newpos, which, flag);
+    return(TRUE);
+}
+
+
+/*
+ * 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, ch;
+    register bool used, change;
+    register short y, x, bounces;
+    coord pos;
+    struct linked_list *target=NULL;
+    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 char *mname;
+		    bool see_monster = cansee(pos.y, pos.x);
+
+		    item = find_mons(unc(pos));
+		    tp = THINGPTR(item);
+		    mname = monster_name(tp);
+
+		    /*
+		     * If our prey shot this, let's record the fact that
+		     * he can shoot, regardless of whether he hits us.
+		     */
+		    if ((tp->t_dest != NULL) && ce(*tp->t_dest, shooter->t_pos)) tp->t_wasshot = TRUE;
+
+		    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);
+			    }
+
+			    turn_off(*tp, CANSURPRISE);
+			    msg("The %s hits %s", name, prname(mname, FALSE));
+			}
+
+			/* Should we start to chase the shooter? */
+			if (shooter != &player			&&
+			    shooter != tp			&&
+			    shooter->t_index != tp->t_index	&&
+			    (tp->t_dest == NULL || rnd(100) < 25)) {
+			    /*
+			     * If we're intelligent enough to realize that this
+			     * is a friendly monster, we will attack the hero
+			     * instead.
+			     */
+			    if (on(*shooter, ISFRIENDLY) &&
+				 roll(3,6) < tp->t_stats.s_intel)
+				 runto(tp, &hero);
+
+			    /* Otherwise, let's chase the monster */
+			    else runto(tp, &shooter->t_pos);
+			}
+			else if (shooter == &player) {
+			    runto(tp, &hero);
+
+			    /*
+			     * If the player shot a charmed monster, it may
+			     * not like being shot at.
+			     */
+			    if (on(*tp, ISCHARMED) && save(VS_MAGIC, tp, 0)) {
+				msg("The eyes of %s turn clear.", 
+				    prname(mname, FALSE));
+				turn_off(*tp, ISCHARMED);
+				mname = monster_name(tp);
+			    }
+			}
+
+			/*
+			 * Let the defender know that the attacker has
+			 * missiles!
+			 */
+			if (ce(*tp->t_dest, shooter->t_pos))
+			    tp->t_wasshot = TRUE;
+
+			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)
+				msg("The %s has no effect on %s.",
+					name, prname(mname, FALSE));
+			}
+
+			else {
+			    bool see_him;
+
+			    see_him = 
+				    off(player, ISBLIND)		      &&
+				    cansee(unc(tp->t_pos))		      &&
+				    (off(*tp, ISINVIS) || on(player, CANSEE)) &&
+				    (off(*tp, ISSHADOW)|| on(player, CANSEE)) &&
+				    (off(*tp, CANSURPRISE)||ISWEARING(R_ALERT));
+
+			    /* Did a spell get disrupted? */
+			    dsrpt_monster(tp, FALSE, see_him);
+
+			    /* 
+			     * Check for gas with special effects 
+			     */
+			    if (EQUAL(name, "nerve gas")) {
+				tp->t_no_move = movement(tp) * FREEZETIME;
+				tp->t_action = A_FREEZE;
+			    }
+			    else if (EQUAL(name, "sleeping gas")) {
+				tp->t_no_move = movement(tp) * SLEEPTIME;
+				tp->t_action = A_FREEZE;
+			    }
+			    else if (EQUAL(name, "slow gas")) {
+				if (on(*tp, ISHASTE))
+				    turn_off(*tp, ISHASTE);
+				else
+				    turn_on(*tp, ISSLOW);
+			    }
+			    else if (EQUAL(name, "fear gas")) {
+				turn_on(*tp, ISFLEE);
+				tp->t_dest = &hero;
+
+				/* It is okay to turn tail */
+				tp->t_oldpos = tp->t_pos;
+			    }
+			    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)
+				       msg("The %s divides %s.",
+					   name,prname(mname, FALSE));
+				      light(&hero);
+				    }
+				    else if (see_monster)
+					msg("The %s has no effect on %s.",
+					    name, prname(mname, FALSE));
+			    }
+			    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)
+					msg("The %s kills %s", 
+					    name, prname(mname, FALSE));
+				    else
+				     msg("You hear a faint groan in the distance");
+				    /*
+				     * Instead of calling killed() here, we
+				     * will record that the monster was killed
+				     * and call it at the end of the routine,
+				     * after we restore what was under the bolt.
+				     * We have to do this because in the case
+				     * of a bolt that first misses the monster
+				     * and then gets it on the bounce.  If we
+				     * call killed here, the 'missed' space in
+				     * spotpos puts the monster back on the
+				     * screen
+				     */
+				    target = item;
+				}
+				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
+				msg("The %s whizzes past %s",
+					    name, prname(mname, FALSE));
+			}
+			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,"lightning bolt")&& 
+							 on(player,NOBOLT))  ||
+			        (EQUAL(name,"fear gas")&&ISWEARING(R_HEROISM))){
+			     msg("The %s has no affect", name);
+			}
+
+			else {
+			    dsrpt_player();
+
+			    /* 
+			     * Check for gas with special effects 
+			     */
+			    if (EQUAL(name, "nerve gas")) {
+				msg("The nerve gas paralyzes you.");
+				player.t_no_move +=
+					movement(&player) * FREEZETIME;
+				player.t_action = A_FREEZE;
+			    }
+			    else if (EQUAL(name, "sleeping gas")) {
+				msg("The sleeping gas puts you to sleep.");
+				player.t_no_move +=
+					movement(&player) * SLEEPTIME;
+				player.t_action = A_FREEZE;
+			    }
+			    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 (EQUAL(name, "acid")			&&
+				    cur_armor != NULL			&&
+				    !(cur_armor->o_flags & ISPROT)	&&
+				    !save(VS_BREATH, &player, -2)	&&
+				    cur_armor->o_ac < pstats.s_arm+1) {
+				       msg("Your armor corrodes from the acid");
+				       cur_armor->o_ac++;
+				}
+				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;
+    }
+
+    /* Restore what was under the bolt */
+    for (x = y - 1; x >= 0; x--)
+	mvwaddch(cw, spotpos[x].place.y, spotpos[x].place.x, spotpos[x].oldch);
+
+    /* If we killed something, do so now.  This will also blank the monster. */
+    if (target) killed(target, FALSE, get_points, TRUE);
+    return;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/things.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,930 @@
+/*
+ * things.c - functions for dealing with things like potions and scrolls
+ *
+ * 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.
+ */
+
+/*
+ * Contains functions for dealing with things like
+ * potions and scrolls
+ *
+ */
+
+#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, "named %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 (p_know[obj->o_which])
+		sprintf(pb, "of %s (%s)", p_magic[obj->o_which].mi_name,
+		    p_kind(obj));
+	    else if (obj->o_flags & ISPOST)
+		sprintf(pb, "of %s", p_magic[obj->o_which].mi_name);
+	    else if (p_guess[obj->o_which])
+		sprintf(pb, "named %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_count == 1)
+		sprintf(pb, "A%s %s", vowelstr(foods[obj->o_which].mi_name), 
+			foods[obj->o_which].mi_name);
+	    else
+		sprintf(pb, "%d %ss", obj->o_count,foods[obj->o_which].mi_name);
+	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)");
+	    if (obj->o_flags & ISPOISON)
+		strcat(pb, " {Poisoned}");
+	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 (ws_know[obj->o_which] || obj->o_flags & ISKNOW)
+		sprintf(pb, "of %s%s (%s)", ws_magic[obj->o_which].mi_name,
+		    charge_str(obj), ws_made[obj->o_which]);
+	    else if (obj->o_flags & ISPOST)
+		sprintf(pb, "of %s", ws_magic[obj->o_which].mi_name);
+	    else if (ws_guess[obj->o_which])
+		sprintf(pb, "named %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 (r_know[obj->o_which] || obj->o_flags & ISKNOW)
+		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 (obj->o_flags & ISPOST)
+		sprintf(pb, "A ring of %s", r_magic[obj->o_which].mi_name);
+	    else if (r_guess[obj->o_which])
+		sprintf(pb, "A ring named %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)
+		switch(obj->o_which) {
+		case QUILL_NAGROM:
+		    sprintf(pb, "%s%s", rel_magic[obj->o_which].mi_name, 
+			    charge_str(obj));
+		otherwise:
+		    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 STONEBONES_AMULET:
+		    strcpy(pb, "A stone amulet");
+		when BRIAN_MANDOLIN:
+		    strcpy(pb, "A gleaming mandolin");
+		when HRUGGEK_MSTAR:
+		    strcpy(pb, "A huge morning star");
+		when AXE_AKLAD:
+		    strcpy(pb, "A jewel encrusted axe");
+		when QUILL_NAGROM:
+		    strcpy(pb, "A bright white feather");
+		when GERYON_HORN:
+		    strcpy(pb, "A jet black horn");
+		when YEENOGHU_FLAIL:
+		    strcpy(pb, "A shimmering flail");
+		when SURTUR_RING:
+		    strcpy(pb, "A fiery red ring");
+		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)");
+		    if (obj->o_charges)
+			strcat(pb, " [charged]");
+		    else
+			strcat(pb, " [discharged]");
+		when HEIL_ANKH:
+		    if (cur_relic[HEIL_ANKH]) strcat(pb, " (in hand)");
+		when EYE_VECNA:
+		    if (cur_relic[EYE_VECNA]) strcat(pb, " (in eye socket)");
+		when STONEBONES_AMULET:
+		    if (cur_relic[STONEBONES_AMULET])
+			strcat(pb, " (in chest)");
+		when YENDOR_AMULET:
+		    if (cur_relic[YENDOR_AMULET])
+			strcat(pb, " (in chest)");
+		when MUSTY_DAGGER:
+		case HRUGGEK_MSTAR:
+		case AXE_AKLAD:
+		case YEENOGHU_FLAIL:
+		case MING_STAFF:
+		case ASMO_ROD:
+		case ORCUS_WAND:
+		    if (cur_weapon == obj) strcat(pb, " (weapon in hand)");
+		when SURTUR_RING:
+		    if (cur_relic[SURTUR_RING])
+			strcat(pb, " (in nose)");
+	    }
+	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, " named: ");
+		    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 MISSILE:
+	    return(ws_magic[obj->o_which].mi_name);
+	when RELIC:
+	    switch (obj->o_which) {
+		case MUSTY_DAGGER:
+		    return("daggers");
+		when YEENOGHU_FLAIL:
+		    return("flail");
+		when AXE_AKLAD:
+		    return("axe");
+		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;
+    register struct linked_list *obj, *nobj;
+    register struct object *op;
+
+    if (item == NULL) {
+	/* We charge 2 movement times to drop something */
+	if (player.t_action == C_DROP && player.t_using != NULL) {
+	    obj = player.t_using;
+	    player.t_using = NULL;
+	    player.t_action = A_NIL;
+	}
+
+	/* t_action == C_DROP always when called from command() */
+	else {
+	    if ((obj = get_item(pack, "drop", ALL, FALSE, FALSE)) == NULL) {
+		player.t_action = A_NIL;
+		player.t_using = NULL;
+		return(FALSE);
+	    }
+	    if (player.t_action == C_DROP) {
+		player.t_using = obj;
+		player.t_no_move = 2 * movement(&player);
+		return(FALSE);	/* We'll come back after we've waited */
+	    }
+	}
+
+	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);
+	}
+    }
+    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, &player);
+    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 (' ');
+	    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->o_type == RING && cur_misc[WEAR_GAUNTLET] != NULL) {
+	msg ("You have to remove your gauntlets first!");
+	return FALSE;
+    }
+    cur_null(op);	/* set current to NULL */
+    if (op->o_type == RING) {
+	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 (!ISWEARING(R_SEEINVIS) &&
+			      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:    if (!ISWEARING(R_WARMTH) && !find_slot(nocold)) 
+				turn_off(player, NOCOLD);
+	when R_FIRE:   	  if (!ISWEARING(R_FIRE)	&& 
+			      !cur_relic[SURTUR_RING]	&&
+			      !find_slot(nofire))
+				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);
+	}
+    }
+    return TRUE;
+}
+
+/*
+ * return a new thing
+ */
+struct linked_list *
+new_thing(thing_type, allow_curse)
+int thing_type;
+bool allow_curse;
+{
+    register struct linked_list *item;
+    register struct object *cur;
+    register int j;
+    register int blesschance, cursechance;
+
+    item = new_item(sizeof *cur);
+    cur = OBJPTR(item);
+    cur->o_hplus = cur->o_dplus = 0;
+    strncpy(cur->o_damage, "0d0", sizeof(cur->o_damage));
+    strncpy(cur->o_hurldmg, "0d0", sizeof(cur->o_hurldmg));
+    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);
+    if (allow_curse) cursechance = rnd(100);
+    else cursechance = 100;	/* No chance of curse */
+
+    /* 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;
+	    do {
+		cur->o_which = pick_one(p_magic, MAXPOTIONS);
+	    } while (!allow_curse && p_magic[cur->o_which].mi_curse == 100);
+	    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;
+
+	    /* If we made a gain ability potion, see what kind it is */
+	    if (cur->o_which == P_ABIL) cur->o_kind = rnd(NUMABILITIES);
+
+	when TYP_SCROLL:
+	    cur->o_type = SCROLL;
+	    do {
+		cur->o_which = pick_one(s_magic, MAXSCROLLS);
+	    } while (!allow_curse && s_magic[cur->o_which].mi_curse == 100);
+	    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;
+	    cur->o_which = pick_one(foods, MAXFOODS);
+	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 (cursechance < 20)
+	    {
+		cur->o_flags |= ISCURSED;
+		cur->o_ac += rnd(3)+1;
+	    }
+	    else if (blesschance < 35)
+		cur->o_ac -= rnd(3)+1;
+	when TYP_RING:
+	    cur->o_type = RING;
+	    do {
+		cur->o_which = pick_one(r_magic, MAXRINGS);
+	    } while (!allow_curse && r_magic[cur->o_which].mi_curse == 100);
+	    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;
+	    do {
+		cur->o_which = pick_one(ws_magic, MAXSTICKS);
+	    } while (!allow_curse && ws_magic[cur->o_which].mi_curse == 100);
+	    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;
+	    do {
+		cur->o_which = pick_one(m_magic, MAXMM);
+	    } while (!allow_curse && m_magic[cur->o_which].mi_curse == 100);
+	    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(11)) {
+			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 8: cur->o_ac = P_FLY;
+			when 9: cur->o_ac = P_SKILL;
+			when 10:cur->o_ac = P_FFIND;
+		    }
+		when MM_OPEN:
+		    cur->o_ac = (4 + rnd(5)) * 5;
+		when 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: /*  set it to a character class */
+		    cur->o_ac = rnd(NUM_CHARTYPES-1);
+		otherwise:
+		    cur->o_ac = 0;
+	    }
+	otherwise:
+	    debug("Picked a bad kind of object");
+	    wait_for(' ');
+    }
+    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;
+    strncpy(obj->o_damage, "0d0", sizeof(obj->o_damage));
+    strncpy(obj->o_hurldmg, "0d0", sizeof(obj->o_hurldmg));
+    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;
+	    if (obj->o_which == EMORI_CLOAK)
+		obj->o_charges = 1;
+
+    }
+    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)
+	{
+	    msg("bad pick_one: %d from %d items", i, nitems);
+	    for (magic = start; magic < end; magic++)
+		msg("%s: %d%%", magic->mi_name, magic->mi_prob);
+	}
+	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("");
+}
+
+/*
+ * p_kind returns the type of potion for some types of identified potions;
+ * otherwise, it returns the color.
+ */
+
+char *
+p_kind(obj)
+struct object *obj;	/* We assume that obj points to a potion */
+{
+    if (obj->o_which == P_ABIL) return(abilities[obj->o_kind]);
+    else return(p_colors[obj->o_which]);
+}
+
+/*
+ * 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/arogue7/trader.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,539 @@
+/*
+ * trader.c - Anything to do with trading posts
+ *
+ * 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.
+ */
+
+/*
+ * Anything to do with trading posts
+ */
+
+#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(startup)
+bool startup;	/* True if equipping the player at the beginning of the game */
+{
+	coord tp;
+	reg int i, j, k;
+	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 */
+
+	/* Are we equipping the player? */
+	if (startup) {
+	    int wpt;
+
+	    /*
+	     * Give the rogue some weaponry.  
+	     */
+	    for (wpt=0; wpt<MAXWEAPONS; wpt++) {
+		ll = spec_item(WEAPON, wpt, rnd(2), rnd(2)+1);
+		attach(lvl_obj, ll);
+		op = OBJPTR(ll);
+		op->o_flags |= (ISPOST | ISKNOW);
+		do {
+		    rnd_pos(rp,&tp);
+		} until (mvinch(tp.y, tp.x) == FLOOR);
+		op->o_pos = tp;
+		mvaddch(tp.y,tp.x,op->o_type);
+	    }
+
+	    /*
+	     * And his suit of armor.......
+	     * Thieves can only wear leather armor,
+	     * so make sure some is available for them.
+	     */
+	    for (i=0; i<MAXARMORS; i++) {
+		ll = spec_item(ARMOR, i, 0, 0);
+		attach(lvl_obj, ll);
+		op = OBJPTR(ll);
+		op->o_flags |= (ISPOST | ISKNOW);
+		op->o_weight = armors[i].a_wght;
+		do {
+		    rnd_pos(rp,&tp);
+		} until (mvinch(tp.y, tp.x) == FLOOR);
+		op->o_pos = tp;
+		mvaddch(tp.y,tp.x,op->o_type);
+	    }
+
+	    /* Now create some wands */
+	    for (i=rnd(4)+2; i>0; i--) {
+		switch (rnd(8)) {
+		    case 0: j = WS_SLOW_M;
+		    when 1: j = WS_TELMON;
+		    when 2: j = WS_CONFMON;
+		    when 3: j = WS_PARALYZE;
+		    when 4: j = WS_MDEG;
+		    when 5: j = WS_WONDER;
+		    when 6: j = WS_FEAR;
+		    when 7: j = WS_LIGHT;
+		}
+		ll = spec_item(STICK, j, 0, 0);
+		attach(lvl_obj, ll);
+		op = OBJPTR(ll);
+
+		/* Let clerics and MU'S know what kind they are */
+		switch (player.t_ctype) {
+		    case C_MAGICIAN:
+		    case C_CLERIC:
+		    case C_DRUID:
+			op->o_flags |= (ISPOST | ISKNOW);
+		    otherwise:
+			op->o_flags |= ISPOST;
+		}
+		fix_stick(op);
+		do {
+		    rnd_pos(rp,&tp);
+		} until (mvinch(tp.y, tp.x) == FLOOR);
+		op->o_pos = tp;
+		mvaddch(tp.y,tp.x,op->o_type);
+	    }
+
+	    /* Now let's make some rings */
+	    for (i=rnd(4)+3; i>0; i--) {
+		k = 0;
+		switch (rnd(15)) {
+		case 0: j = R_PROTECT;	k = roll(1,2);
+		when 1: j = R_ADDSTR;	k = roll(1,3);
+		when 2: j = R_ADDHIT;	k = roll(1,3);
+		when 3: j = R_ADDDAM;	k = roll(1,3);
+		when 4: j = R_DIGEST;	k = 1;
+		when 5: j = R_ADDINTEL;	k = roll(1,3);
+		when 6: j = R_ADDWISDOM;k = roll(1,3);
+		when 7: j = R_SUSABILITY;
+		when 8: j = R_SEEINVIS;
+		when 9: j = R_ALERT;
+		when 10:j = R_HEALTH;
+		when 11:j = R_HEROISM;
+		when 12:j = R_FIRE;
+		when 13:j = R_WARMTH;
+		when 14:j = R_FREEDOM;
+		}
+		ll = spec_item(RING, j, k, 0);
+		attach(lvl_obj, ll);
+		op = OBJPTR(ll);
+
+		/*
+		 * Let fighters, assassins, monks, and thieves know what kind
+		 * of rings these are.
+		 */
+		switch (player.t_ctype) {
+		    case C_FIGHTER:
+		    case C_THIEF:
+		    case C_ASSASIN:
+		    case C_MONK:
+			op->o_flags |= (ISPOST | ISKNOW);
+		    otherwise:
+			op->o_flags |= ISPOST;
+		}
+		do {
+		    rnd_pos(rp,&tp);
+		} until (mvinch(tp.y, tp.x) == FLOOR);
+		op->o_pos = tp;
+		mvaddch(tp.y,tp.x,op->o_type);
+	    }
+
+	    /* Let's offer some potions */
+	    for (i=rnd(3)+1; i>0; i--) {
+		/* Choose the type of potion */
+		if (i == 1 && player.t_ctype == C_ASSASIN) j = P_POISON;
+		else switch (rnd(8)) {
+		    case 0:	j = P_CLEAR;
+		    when 1:	j = P_HEALING;
+		    when 2:	j = P_MFIND;
+		    when 3:	j = P_TFIND;
+		    when 4:	j = P_HASTE;
+		    when 5:	j = P_RESTORE;
+		    when 6:	j = P_FLY;
+		    when 7:	j = P_FFIND;
+		}
+
+		/* Make the potion */
+		ll = spec_item(POTION, j, 0, 0);
+		attach(lvl_obj, ll);
+		op = OBJPTR(ll);
+		op->o_flags |= ISPOST;
+
+		/* Place the potion */
+		do {
+		    rnd_pos(rp,&tp);
+		} until (mvinch(tp.y, tp.x) == FLOOR);
+		op->o_pos = tp;
+		mvaddch(tp.y,tp.x,op->o_type);
+	    }
+
+	    /* Let's offer some scrolls */
+	    for (i=rnd(3)+1; i>0; i--) {
+		/* Choose the type of scrolls */
+		switch (rnd(8)) {
+		    case 0:	j = S_CONFUSE;
+		    when 1:	j = S_MAP;
+		    when 2:	j = S_LIGHT;
+		    when 3:	j = S_SLEEP;
+		    when 4:	j = S_IDENT;
+		    when 5:	j = S_GFIND;
+		    when 6:	j = S_REMOVE;
+		    when 7:	j = S_CURING;
+		}
+
+		/* Make the scroll */
+		ll = spec_item(SCROLL, j, 0, 0);
+		attach(lvl_obj, ll);
+		op = OBJPTR(ll);
+		op->o_flags |= ISPOST;
+
+		/* Place the scroll */
+		do {
+		    rnd_pos(rp,&tp);
+		} until (mvinch(tp.y, tp.x) == FLOOR);
+		op->o_pos = tp;
+		mvaddch(tp.y,tp.x,op->o_type);
+	    }
+
+	    /* And finally, let's get some food */
+	    for (i=rnd(3)+1; i>0; i--) {
+		ll = spec_item(FOOD, 0, 0, 0);
+		attach(lvl_obj, ll);
+		op = OBJPTR(ll);
+		op->o_weight = things[TYP_FOOD].mi_wght;
+		op->o_flags |= ISPOST;
+		do {
+		    rnd_pos(rp,&tp);
+		} until (mvinch(tp.y, tp.x) == FLOOR);
+		op->o_pos = tp;
+		mvaddch(tp.y,tp.x,op->o_type);
+	    }
+	}
+	else {
+	    i = roll(10, 4);			/* 10 to 40 items */
+	    for (; i > 0 ; i--) {		/* place all the items */
+		ll = new_thing(ALL, TRUE);		/* 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);
+	    }
+	}
+	wmove(cw,12,0);
+	trader = 0;
+	if (startup) {
+	    waddstr(cw,"Welcome to Friendly Fiend's Equipage\n\r");
+	    waddstr(cw,"====================================\n\r");
+	}
+	else {
+	    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 && level != 0) {
+	    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) {
+	    debug("Can't find the item");
+	    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;
+
+	/* Our shopkeeper is affected by the person's charisma */
+	worth = (int) ((float) worth * (17. / (float)pstats.s_charisma));
+	str = inv_name(obj, TRUE);
+	msg("%s for only %d pieces of gold", str, worth);
+	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, FALSE, FALSE)) == 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;
+	msg("Your %s is worth %d pieces of gold.",typ_name(obj),wo);
+	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 (level == 0)
+	    sprintf(prbuf, "You are welcome to spend whatever you have.");
+	else 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/arogue7/util.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,1283 @@
+/*
+ * util.c  -  all sorts of miscellaneous routines
+ *
+ * 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.
+ */
+
+#include "curses.h"
+#include "rogue.h"
+#include <ctype.h>
+#ifdef PC7300
+#include <track.h>
+#include <kcodes.h>
+#include <sys/window.h>
+extern struct uwdata wdata;
+#endif
+
+/*
+ * all sorts of miscellaneous routines
+ *
+ */
+
+
+
+
+/*
+ * this routine computes the players current AC without dex bonus's
+ */
+int 
+ac_compute(ignoremetal)
+bool ignoremetal;
+{
+    register int ac;
+
+    ac = pstats.s_arm; /* base armor of "skin" */
+    if (cur_armor) {
+	if (!ignoremetal || 
+	     (cur_armor->o_which != LEATHER		&& 
+	      cur_armor->o_which != STUDDED_LEATHER	&& 
+	      cur_armor->o_which != PADDED_ARMOR))
+		ac -= (10 - cur_armor->o_ac);
+    }
+    if (player.t_ctype == C_MONK)
+	ac -= pstats.s_lvl * 2 / 3;
+    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);
+}
+
+/*
+ * aggravate:
+ *	aggravate all the monsters on this level
+ */
+
+aggravate(do_uniques, do_good)
+bool do_uniques, do_good;
+{
+    register struct linked_list *mi;
+    register struct thing *thingptr;
+
+    for (mi = mlist; mi != NULL; mi = next(mi)) {
+	thingptr = THINGPTR(mi);
+	if (do_good == FALSE && off(*thingptr, ISMEAN)) continue;
+	if (do_uniques || off(*thingptr, ISUNIQUE)) runto(thingptr, &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 certain beginning experience levels for all players.
+ * All further experience levels are computed by muliplying by 2
+ * up through MAXDOUBLE. Then the cap is added in to compute
+ * further levels
+ */
+long
+check_level()
+{
+    register int i, j, add = 0;
+    register unsigned long exp;
+    long retval;	/* Return value */
+    int nsides;
+
+    pstats.s_lvl -= pstats.s_lvladj; /* correct for level adjustment */
+    /* See if we are past the doubling stage */
+    exp = char_class[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 = char_class[player.t_ctype].start_exp;
+	while (exp <= pstats.s_exp) {
+	    i++;
+	    exp <<= 1;
+	}
+	retval = exp;
+    }
+    if (++i > pstats.s_lvl) {
+	nsides = char_class[player.t_ctype].hit_pts;
+	for (j=0; j<(i-pstats.s_lvl); j++) /* Take care of multi-level jumps */
+	    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;
+	msg("Welcome, %s, to level %d",
+	    cnames[player.t_ctype][min(i-1, NUM_CNAMES-1)], i);
+    }
+    pstats.s_lvl = i;
+    pstats.s_lvl += pstats.s_lvladj; /* correct for level adjustment */
+    return(retval);
+}
+
+/*
+ * Used to modify the players 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, &player);
+}
+
+/*
+ * let's confuse the player
+ */
+confus_player()
+{
+    if (off(player, ISCLEAR))
+    {
+	msg("Wait, what's going on here. Huh? What? Who?");
+	if (find_slot(unconfuse))
+	    lengthen(unconfuse, HUHDURATION);
+	else
+	    fuse(unconfuse, 0, HUHDURATION, AFTER);
+	turn_on(player, ISHUH);
+    }
+    else msg("You feel dizzy for a moment, but it quickly passes.");
+}
+
+/*
+ * 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);
+}
+
+/*
+ * 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 );
+}
+
+
+/*
+ * findmindex:
+ *	Find the index into the monster table of a monster given its name.
+ */
+
+findmindex(name)
+char *name;
+{
+    int which;
+
+    for (which=1; which<NUMMONST; which++) {
+	 if (strcmp(name, monsters[which].m_name) == 0)
+	     break;
+    }
+    if (which >= NUMMONST) {
+	 debug("couldn't find monster index");
+	 which = 1;
+    }
+    return(which);
+}
+
+/*
+ * find_mons:
+ *	Find the monster from his coordinates
+ */
+
+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;
+}
+
+/*
+ * get coordinates from the player using the cursor keys (or mouse)
+ */
+coord 
+get_coordinates()
+{
+    register int which;
+    coord c;
+#ifdef PC7300
+    struct umdata startmouse, listenmouse;	/* Mouse parameters */
+    int xmouse,	/* x-position of mouse */
+	ymouse, /* y-position of mouse */
+	bmouse, /* button value of mouse */
+	rmouse; /* reason for mouse change */
+#endif
+
+    c = hero;
+    wmove(cw, hero.y, hero.x);
+    draw(cw);
+#ifdef PC7300
+    keypad(0, 1);	/* Turn on escape sequences */
+    ioctl(0, WIOCGETMOUSE, &startmouse); /* Get current mouse parameters */
+    listenmouse = startmouse;	/* Make a copy */
+    listenmouse.um_flags |= MSDOWN;	/* Enable detection of button down */
+    ioctl(0, WIOCSETMOUSE, &listenmouse);	/* Make the change */
+#endif
+    for (;;) {
+#ifdef PC7300
+	which = wgetc(0);
+#else
+	which = (getchar() & 0177);
+#endif
+	switch(which) {
+#ifdef PC7300
+	    case Home:
+		c.x = 0; c.y = 1;
+	    when Beg:
+		c.x = 0;
+	    when End:
+		c.x = cols - 1;
+	    when Mouse:
+	    case ESCAPE:
+	    case Cancl:
+	    case s_Cancl:
+		if (which == Mouse) {
+		    if (wreadmouse(0,&xmouse,&ymouse,&bmouse,&rmouse) != 0 ||
+			(rmouse & MSDOWN) == 0)
+			break;
+		    c.y = ymouse / wdata.uw_vs;
+		    c.x = xmouse / wdata.uw_hs;
+		    c.y = max(c.y, 1);
+		    c.y = min(c.y, lines - 3);
+		    c.x = max(c.x, 0);
+		    c.x = min(c.x, cols - 1);
+		}
+		else c = hero;
+		wmove(cw, c.y, c.x);
+		draw(cw);
+	    case '\n':
+	    case '\c':
+		keypad(0, 0);	/* Turn off escape interpretation */
+		ioctl(0, WIOCSETMOUSE, &startmouse); /* No mouse tracking */
+		return(c);
+	    when 'h':
+	    case 'H':
+	    case Back:
+	    case s_Back:
+		c.x--;
+	    when 'j':
+	    case 'J':
+	    case Down:
+	    case RollDn:
+		c.y++;
+	    when 'k':
+	    case 'K':
+	    case Up:
+	    case RollUp:
+		c.y--;
+	    when 'l':
+	    case 'L':
+	    case Forward:
+	    case s_Forward:
+		c.x++;
+	    when 'y':
+	    case 'Y':
+	    case Prev:
+		c.x--; c.y--;
+	    when 'u':
+	    case 'U':
+	    case Next:
+		c.x++; c.y--;
+	    when 'b':
+	    case 'B':
+	    case s_Prev:
+		c.x--; c.y++;
+	    when 'n':
+	    case 'N':
+	    case s_Next:
+		c.x++; c.y++;
+	    when '*':
+		msg("Select location via mouse, or");
+		msg("Use cursor keys,h,j,k,l,y,u,b,or n, then hit return.");
+#else
+	    case ESCAPE:
+		c = hero;
+		wmove(cw, c.y, c.x);
+		draw(cw);
+	    case '\n':
+	    case '\r':
+		return(c);
+	    when 'h':
+	    case 'H':
+		c.x--;
+	    when 'j':
+	    case 'J':
+		c.y++;
+	    when 'k':
+	    case 'K':
+		c.y--;
+	    when 'l':
+	    case 'L':
+		c.x++;
+	    when 'y':
+	    case 'Y':
+		c.x--; c.y--;
+	    when 'u':
+	    case 'U':
+		c.x++; c.y--;
+	    when 'b':
+	    case 'B':
+		c.x--; c.y++;
+	    when 'n':
+	    case 'N':
+		c.x++; c.y++;
+	    when '*':
+		msg("Use h,j,k,l,y,u,b,n to position cursor, then hit return.");
+#endif
+	}
+	c.y = max(c.y, 1);
+	c.y = min(c.y, lines - 3);
+	c.x = max(c.x, 0);
+	c.x = min(c.x, cols - 1);
+	wmove(cw, c.y, c.x);
+	draw(cw);
+    } 
+}
+
+/*
+ * set up the direction co_ordinate for use in various "prefix" commands
+ */
+bool
+get_dir(direction)
+coord *direction;
+{
+    register char *prompt;
+    register bool gotit;
+    int x,y;
+
+    prompt = terse ? "Direction?" :  "Which direction? ";
+    msg(prompt);
+    do
+    {
+	gotit = TRUE;
+	switch (md_readchar(msgw))
+	{
+	    case 'h': case'H': direction->y =  0; direction->x = -1;
+	    when 'j': case'J': direction->y =  1; direction->x =  0;
+	    when 'k': case'K': direction->y = -1; direction->x =  0;
+	    when 'l': case'L': direction->y =  0; direction->x =  1;
+	    when 'y': case'Y': direction->y = -1; direction->x = -1;
+	    when 'u': case'U': direction->y = -1; direction->x =  1;
+	    when 'b': case'B': direction->y =  1; direction->x = -1;
+	    when 'n': case'N': direction->y =  1; direction->x =  1;
+	    case 0:
+	    when 3: quit(0);
+		    return(FALSE);
+	    when ESCAPE: return (FALSE);
+	    otherwise:
+		mpos = 0;
+		msg(prompt);
+		gotit = FALSE;
+	}
+    } until (gotit);
+    if ((on(player, ISHUH) || on(player, ISDANCE)) && rnd(100) > 20) {
+	do
+	{
+	    *direction = grid[rnd(9)];
+	} while (direction->y == 0 && direction->x == 0);
+    }
+    else if (on(player, ISFLEE)) {
+	    y = hero.y;
+	    x = hero.x;
+	    while (shoot_ok(winat(y, x))) {
+		y += direction->y;
+		x += direction->x;
+	    }
+	    if (isalpha(mvwinch(mw, y, x))) {
+		if (y == player.t_dest->y && x == player.t_dest->x) {
+		    mpos = 0;
+		    msg("You are too frightened to!");
+		    return(FALSE);
+	    }
+	}
+    }
+    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 STONEBONES_AMULET:
+	    case HRUGGEK_MSTAR:
+	    case AXE_AKLAD:
+	    case YEENOGHU_FLAIL:
+	    case SURTUR_RING:
+		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++) {
+	    struct linked_list *it;
+	    coord here;		/* Current <x,y> coordinate */
+	    char savech;	/* Saves character in monster window */
+	    bool in_room;	/* Are we in a room? */
+
+	    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 we have a monster that we can't see anymore, make sure
+	     * that we can note that fact.
+	     */
+	    if (isalpha(savech) &&
+		(y < hero.y - radius || y > hero.y + radius ||
+		 x < hero.x - radius || x > hero.x + radius)) {
+		/* Find the monster */
+		it = find_mons(y, x);
+	    }
+	    else it = NULL;
+
+	    /* Are we in a room? */
+	    here.y = y;
+	    here.x = x;
+	    in_room = (roomin(&here) != NULL);
+
+	    if ((do_blank || !in_room) && (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);
+
+			    /* 
+			     * If we found it (we should!), set it to
+			     * the right character!
+			     */
+			    if (it) (THINGPTR(it))->t_oldch = ch;
+			}
+			break;
+		    when FLOOR:
+		    case FOREST:
+		    default:
+			mvwaddch(cw, y, x, in_room ? ' ' : PASSAGE);
+
+			/* If we found a monster, set it to darkness! */
+			if (it) (THINGPTR(it))->t_oldch = CCHAR( mvwinch(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);
+
+		if (it) {
+		    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;
+    }
+}
+
+/* 
+ * Lower a level of experience 
+ */
+
+lower_level(who)
+short who;
+{
+    int fewer, nsides;
+    unsigned int exp;
+
+    msg("You suddenly feel less skillful.");
+    if (--pstats.s_lvl == 0)
+	death(who);		/* All levels gone */
+    if (pstats.s_lvladj > 0) { /* lose artificial levels first */
+	pstats.s_lvladj--;
+	return;
+    }
+    exp = char_class[player.t_ctype].cap;
+    if (pstats.s_exp >= exp*2)
+	pstats.s_exp -= exp;
+    else
+	pstats.s_exp /= 2;
+
+    nsides = char_class[player.t_ctype].hit_pts;
+    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);
+}
+
+/*
+ * print out the name of a monster
+ */
+char *
+monster_name(tp)
+register struct thing *tp;
+{
+    prbuf[0] = '\0';
+    if (on(*tp, ISFLEE) || on(*tp, WASTURNED))
+	strcat(prbuf, "terrified ");
+    if (on(*tp, ISHUH))
+	strcat(prbuf, "confused ");
+    if (on(*tp, ISCHARMED))
+	strcat(prbuf, "charmed ");
+    else if (on(*tp, ISFLY))
+	strcat(prbuf, "flying ");
+
+    /* If it is sleeping or stoned, write over any of the above attributes */
+    if (off(*tp, ISRUN))
+	strcpy(prbuf, "sleeping ");
+    if (on(*tp, ISSTONE))
+	strcpy(prbuf, "petrified ");
+
+    if (tp->t_name) strcat(prbuf, tp->t_name);
+    else strcat(prbuf, monsters[tp->t_index].m_name);
+
+    return(prbuf);
+}
+
+/*
+ * move_hero:
+ *	Try to move the hero somplace besides next to where he is.  We ask him
+ *	where.  There can be restrictions based on why he is moving.
+ */
+
+bool
+move_hero(why)
+int why;
+{
+    char *action;
+    char which;
+    coord c;
+
+    switch (why) {
+	case H_TELEPORT:
+	    action = "teleport";
+    }
+
+    msg("Where do you wish to %s to? (* for help) ", action);
+    c = get_coordinates();
+    mpos = 0;
+    which = CCHAR( winat(c.y, c.x) );
+    switch (which) {
+	default:
+	    if (!isrock(which) || off(player, CANINWALL)) break;
+
+	case FLOOR:
+	case PASSAGE:
+	case DOOR:
+	case STAIRS:
+	case POST:
+	case GOLD:
+	case POTION:
+	case SCROLL:
+	case FOOD:
+	case WEAPON:
+	case ARMOR:
+	case RING:
+	case MM:
+	case RELIC:
+	case STICK:
+	    hero = c;
+	    return(TRUE);
+    }
+    return(FALSE);
+}
+
+/*
+ * raise_level:
+ *	The guy just magically went up a level.
+ */
+
+raise_level()
+{
+    unsigned long test;	/* Next level -- be sure it is not an overflow */
+
+    test = check_level();	/* 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();
+}
+
+/*
+ * saving throw matrix for character saving throws
+ * this table is indexed by char type and saving throw type
+ */
+static int st_matrix[NUM_CHARTYPES][5] = {
+/* Poison,	Petrify,	wand,		Breath,		Magic */
+{ 14,		15,		16,		16,		17 },
+{ 14,		15,		16,		16,		17 },
+{ 14,		15,		16,		16,		17 },
+{ 14,		13,		11,		15,		12 },
+{ 10,		13,		14,		16,		15 },
+{ 13,		12,		14,		16,		15 },
+{ 13,		12,		14,		16,		15 },
+{ 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, protect;
+
+    protect = 0;
+    level = who->t_stats.s_lvl;
+    need = st_matrix[who->t_ctype][which];
+    switch (who->t_ctype) {
+    case C_FIGHTER:
+    case C_RANGER:
+    case C_PALADIN:
+    case C_MONSTER:
+	need -= (level-1) / 2;
+    when C_MAGICIAN:
+	need -= 2 * (level-1) / 5;
+    when C_CLERIC:
+    case C_DRUID:
+	need -= (level-1) / 3;
+    when C_THIEF:
+    case C_ASSASIN:
+    case C_MONK:
+	need -= 2 * (level-1) / 4;
+    }
+    /* 
+     * 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;
+    if (who == &player) {
+	/*
+	 * does the player have a ring of protection on?
+	 */
+	protect +=  ring_value(R_PROTECT);
+	/*
+	 * does the player have a cloak of protection on?
+	 */
+        if (cur_misc[WEAR_CLOAK])
+	    protect += cur_misc[WEAR_CLOAK]->o_ac;
+
+        protect = min(protect, 4);/* no more than a +4 bonus */
+        need -= protect;
+    }
+    need -= adj;
+    /*
+     * always miss or save on a 1 (except for UNIQUEs
+     */
+    if (who == &player || off(*who, ISUNIQUE))
+	need = max(need, 2);
+    need = min(20, need); /* always make our save on a 20 */
+    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');
+}
+
+/*
+ * 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);
+}
+
+/*
+ * 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);
+    }
+    *s1 = '\0';
+}
+
+/*
+ * tr_name:
+ *	print the name of a trap
+ */
+
+char *
+tr_name(ch)
+char ch;
+{
+    register char *s;
+
+    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 "";
+    }
+}
+
+/*
+ * wake up a room full (hopefully) of creatures
+ */
+wake_room(rp)
+register struct room *rp;
+{
+	register struct linked_list *item;
+	register struct thing *tp;
+
+	for (item=mlist; item!=NULL; item=next(item)) {
+	    tp = THINGPTR(item);
+	    if (off(*tp,ISRUN) && on(*tp,ISMEAN) && roomin(&tp->t_pos) == rp)
+		runto(tp, &hero);
+	}
+}
+		
+
+/*
+ * 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/arogue7/vers.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,24 @@
+/*
+ * vers.c - version number
+ *
+ * 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.
+ */
+
+/*
+ * 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.
+ */
+
+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	7.7 (Bell Labs) 07/07/86";
+char *release = "7.7.1";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/weapons.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,402 @@
+/*
+ * weapons.c - Functions for dealing with problems brought about by weapons
+ *
+ * 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.
+ */
+
+/*
+ * Functions for dealing with problems brought about by weapons
+ *
+ */
+
+#include "curses.h"
+#include <ctype.h>
+#include "rogue.h"
+
+boomerang(ydelta, xdelta, item, tp)
+int ydelta, xdelta;
+register struct linked_list *item;
+register struct thing *tp;
+{
+	register struct object *obj;
+	struct thing midpoint;
+	coord oldpos;
+
+	obj = OBJPTR(item);
+	oldpos = obj->o_pos;
+
+	/*
+	 * make it appear to fly at the target
+	 */
+	do_motion(obj, ydelta, xdelta, tp);
+	hit_monster(unc(obj->o_pos), obj, tp);
+
+	/*
+	 * Now let's make it fly back to the wielder.  We need to
+	 * use midpoint to fool do_motion into thinking the action
+	 * starts there.  Do_motion only looks at the t_pos field.
+	 */
+	midpoint.t_pos = obj->o_pos;	/* Simulate a new start position */
+	do_motion(obj, -ydelta, -xdelta, &midpoint);
+
+	obj->o_pos = oldpos;
+}
+
+/*
+ * do the actual motion on the screen done by an object traveling
+ * across the room.  Note that we should not look at any field in
+ * tp other than t_pos unless we change boomerang().
+ */
+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;
+		}
+
+		/*
+		 * Did we stop because of a monster or the hero?  If we did 
+		 * not, we want to move our position back one because we could
+		 * not actually make it this far.
+		 */
+		if (!isalpha(ch) && 
+		    !(obj->o_pos.y == hero.y && obj->o_pos.x == hero.x)) {
+		        obj->o_pos.y -= ydelta;
+		        obj->o_pos.x -= xdelta;
+		}
+
+		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;
+	struct object *tobj;
+	struct linked_list *titem;
+	coord *fpos;
+
+	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) {
+		if (obj->o_group) { /* try to add groups together */
+		    for(titem=lvl_obj; titem!=NULL; titem=next(titem)) {
+			tobj = OBJPTR(titem);
+			if (tobj->o_group == obj->o_group	&&
+			    tobj->o_pos.y == fpos->y		&&
+			    tobj->o_pos.x == fpos->x) {
+				tobj->o_count += obj->o_count;
+				o_discard(item);
+				return;
+			}
+		    }
+		}
+		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) {
+	    msg("The %s vanishes as it hits the ground.",
+		weaps[obj->o_which].w_name);		
+	}
+	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);
+		}
+
+		/* Player hits monster */
+		return(fight(&mp, obj, TRUE));
+	} else {
+		if (!ce(mp, hero)) {
+		    /* Monster hits monster */
+		    return(skirmish(tp, &mp, obj, TRUE));
+		}
+
+		/* Monster hits player */
+		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];
+	strncpy(weap->o_damage, iwp->w_dam, sizeof(weap->o_damage));
+	strncpy(weap->o_hurldmg, iwp->w_hrl, sizeof(weap->o_hurldmg));
+	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 (obj->o_type == RELIC && obj->o_which == AXE_AKLAD) {
+	    boomerang(ydelta, xdelta, item, tp);
+	    return;
+	}
+
+	if (!dropcheck(obj)) return;	/* Can we get rid of it? */
+
+	if(!(obj->o_flags & ISMISL)) {
+	    while (TRUE) {
+		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, tp);
+	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;
+
+	/*
+	 * It takes 2 movement periods to unwield a weapon and 2 movement
+	 * periods to wield a weapon.
+	 */
+	if (player.t_action != C_WIELD) {
+	    player.t_action = C_WIELD;
+	    player.t_using = NULL;	/* Make sure this is NULL! */
+	    if (cur_weapon != NULL) {
+		player.t_no_move = 2 * movement(&player);
+		return;
+	    }
+	}
+
+	if ((oweapon = cur_weapon) != NULL) {
+	    /* At this point we have waited at least 2 units */
+	    if (!dropcheck(cur_weapon)) {
+		    cur_weapon = oweapon;
+		    player.t_action = A_NIL;
+		    return;
+	    }
+	    if (terse)
+		addmsg("Was ");
+	    else
+		addmsg("You were ");
+	    msg("wielding %s", inv_name(oweapon, TRUE));
+	}
+
+	/* We we have something picked out? */
+	if (player.t_using == NULL) {
+	    /* Now, what does he want to wield? */
+	    if ((item = get_item(pack, "wield", WIELDABLE, FALSE, FALSE)) == NULL) {
+		    player.t_action = A_NIL;
+		    after = FALSE;
+		    return;
+	    }
+	    player.t_using = item;
+	    player.t_no_move = 2 * movement(&player);
+	    return;
+	}
+
+	/* We have waited our time, let's wield the weapon */
+	item = player.t_using;
+	player.t_using = NULL;
+	player.t_action = A_NIL;
+
+	obj = OBJPTR(item);
+
+	if (is_current(obj)) {
+		msg("Item in use.");
+		after = FALSE;
+		return;
+	}
+	if (player.t_ctype != C_FIGHTER && 
+	    player.t_ctype != C_RANGER  &&
+	    player.t_ctype != C_PALADIN &&
+	    obj->o_type == WEAPON	&&
+	   (obj->o_which == TWOSWORD  ||
+	    (obj->o_which == BASWORD &&
+	     player.t_ctype != C_ASSASIN))) {
+		msg("Only fighter types 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/arogue7/wear.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,431 @@
+/*
+ * wear.c  -  functions for dealing with armor
+ *
+ * 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.
+ */
+
+/*
+ * This file contains misc functions for dealing with armor
+ */
+
+#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;
+
+    /* It takes time to take things off */
+    if (player.t_action != C_TAKEOFF) {
+	/* What does player want to take off? */
+	if ((item = get_item(pack, "take off", REMOVABLE, FALSE, FALSE))==NULL)
+	    return;
+
+	obj = OBJPTR(item);
+	if (!is_current(obj)) {
+	    msg("Not wearing %c) %s", pack_char(pack, obj),inv_name(obj, TRUE));
+	    return;
+	}
+
+	player.t_using = item;	/* Remember what it is */
+	player.t_action = C_TAKEOFF;	/* We are taking something off */
+
+	/* Cursed items take almost no time */
+	if (obj->o_flags & ISCURSED) player.t_no_move = movement(&player);
+	else player.t_no_move = dress_units(item) * movement(&player);
+	return;
+    }
+
+    /* We have waited our time, let's take off our item */
+    item = player.t_using;
+    player.t_using = NULL;
+    player.t_action = A_NIL;
+
+    obj = OBJPTR(item);
+    if (!is_current(obj)) {	/* Just to be on the safe side */
+	msg("Not wearing %c) %s", pack_char(pack, obj),inv_name(obj, TRUE));
+	return;
+    }
+
+    /* Can the player remove the item? */
+    if (!dropcheck(obj)) return;
+    updpack(TRUE, &player);
+
+    msg("Was wearing %c) %s", pack_char(pack, obj),inv_name(obj,TRUE));
+}
+
+/*
+ * 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;
+
+    /* It takes time to put things on */
+    if (player.t_action != C_WEAR) {
+	/* What does player want to wear? */
+	if ((item = get_item(pack, "wear", WEARABLE, FALSE, FALSE)) == 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 (player.t_ctype == C_MONK) {
+		    msg("Monks can't wear armor!");
+		    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;
+		}
+		if (player.t_ctype == C_ASSASIN	&&
+		    (obj->o_which != LEATHER    &&
+		     obj->o_which != STUDDED_LEATHER)) {
+		    if (terse) msg("Assassins can't wear that type of armor");
+		    else
+		 msg("Assassins can only wear leather or studded leather armor");
+		    return;
+		}
+
+	    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");
+			return;
+		    }
+		/*
+		 * 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");
+			return;
+		    }
+		/*
+		 * 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");
+			return;
+		    }
+		    else {
+			if (cur_armor != NULL) {
+			   msg("You can't wear bracers of defense with armor.");
+			   return;
+			}
+		    }
+
+		/*
+		 * 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");
+			return;
+		    }
+		    else {
+			if (cur_armor != NULL) {
+			    msg("You can't wear a cloak with armor.");
+			    return;
+			}
+		    }
+		/*
+		 * 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.");
+			return;
+		    }
+		/*
+		 * the jewel of attacks does an aggavate monster
+		 */
+		when MM_JEWEL:
+		    if (cur_misc[WEAR_JEWEL] != NULL	||
+			cur_relic[YENDOR_AMULET]	||
+			cur_relic[STONEBONES_AMULET]) {
+			msg("Already wearing an amulet.");
+			return;
+		    }
+		/*
+		 * 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");
+			return;
+		    }
+		/*
+		 * 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");
+			return;
+		    }
+		otherwise:
+		    msg("what a strange item you have!");
+		    return;
+		}
+
+	    when RING:
+		if (cur_misc[WEAR_GAUNTLET] != NULL) {
+		    msg ("You have to remove your gauntlets first!");
+		    return;
+		}
+
+		/* Is there room to put the ring on */
+		for (i=0; i<NUM_FINGERS; i++)
+		    if (cur_ring[i] == NULL) {
+			break;
+		    }
+		if (i == NUM_FINGERS) {	/* No room */
+		    if (terse) msg("Wearing enough rings");
+		    else msg("You already have on eight rings");
+		    return;
+		}
+	}
+
+	player.t_using = item;	/* Remember what it is */
+	player.t_action = C_WEAR;	/* We are taking something off */
+	player.t_no_move = dress_units(item) * movement(&player);
+	return;
+    }
+
+    /* We have waited our time, let's put on our item */
+    item = player.t_using;
+    player.t_using = NULL;
+    player.t_action = A_NIL;
+
+    obj = OBJPTR(item);
+
+    switch (obj->o_type) {
+	case ARMOR:
+	    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:
+		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:
+		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:
+		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:
+		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:
+		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:
+		msg("Wearing %s",inv_name(obj,TRUE));
+		cur_misc[WEAR_JEWEL] = obj;
+		aggravate(TRUE, TRUE);
+	    /*
+	     * the necklace of adaption makes the hero immune to
+	     * chlorine gas
+	     */
+	    when MM_ADAPTION:
+		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:
+		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) {
+		nameitem(item, FALSE);
+	    }
+
+	when RING:
+	    /* 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(item);
+    }
+    updpack(TRUE, &player);
+}
+
+/*
+ * dress_units:
+ *	How many movements periods does it take to put on or remove the
+ *	given item of "clothing"?
+ */
+dress_units(item)
+struct linked_list *item;
+{
+    register struct object *obj;
+
+    obj = OBJPTR(item);
+
+    switch (obj->o_type) {
+	case ARMOR:
+	    return(10-armors[obj->o_which].a_class);
+	when RING:
+	    return(2);
+	when MM:
+	    switch (obj->o_which) {
+		case MM_ELF_BOOTS:
+		case MM_DANCE:
+		    /* Boots */
+		    return(4);
+		when MM_R_POWERLESS:
+		case MM_DISP:
+		case MM_PROTECT:
+		    /* Robes */
+		    return(4);
+		when MM_BRACERS:
+		case MM_G_DEXTERITY:
+		case MM_G_OGRE:
+		case MM_FUMBLE:
+		    /* Hand garments */
+		    return(3);
+		when MM_JEWEL:
+		case MM_ADAPTION:
+		case MM_STRANGLE:
+		    /* Jewelry */
+		    return(2);
+		otherwise:
+		    return(1);	/* What is it? */
+	}
+	otherwise:
+	    return(1);	/* What is it? */
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/wizard.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,696 @@
+/* 
+ * wizard.c - Special wizard commands
+ *
+ * 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.
+ */
+
+/*
+ * Special wizard commands (some of which are also non-wizard commands
+ * under strange circumstances)
+ */
+
+#include "curses.h"
+#include <ctype.h>
+#include "rogue.h"
+#ifdef PC7300
+#include "menu.h"
+#endif
+
+
+/*
+ * 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, 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') {
+	/* make monster and be done with it */
+	wh = makemonster(TRUE, "Creation", "create");
+	if (wh > 0) {
+	    creat_mons (&player, wh, TRUE);
+	    light(&hero);
+	}
+	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;
+	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 FOOD:	wmi = &foods[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(11)) {
+			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 9: obj->o_ac = P_SKILL;
+			when 10:obj->o_ac = P_FFIND;
+		    }
+		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(NUM_CHARTYPES-1);
+		    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;
+	    if (wh == P_ABIL) obj->o_kind = rnd(NUMABILITIES);
+	    p_know[wh] = TRUE;
+	when RELIC:
+	    obj->o_weight = things[TYP_RELIC].mi_wght;
+	    switch (obj->o_which) {
+	        case QUILL_NAGROM: obj->o_charges = QUILLCHARGES;
+	        when EMORI_CLOAK:  obj->o_charges = 1;
+	        otherwise: break;
+	    }
+	when FOOD:
+	    obj->o_weight = things[TYP_FOOD].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 = wgetch(msgw);
+	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);
+}
+
+#ifdef PC7300
+static menu_t Display;				/* The menu structure */
+static mitem_t Dispitems[NUMMONST+1];		/* Info for each line */
+static char Displines[NUMMONST+1][LINELEN+1];	/* The lines themselves */
+#endif
+
+/*
+ * make a monster for the wizard
+ */
+makemonster(showall, label, action) 
+bool showall;	/* showall -> show uniques and genocided creatures */
+char *label, *action;
+{
+#ifdef PC7300
+    register int nextmonst;
+#endif
+    register int i;
+    register short which_monst;
+    register int num_monst = NUMMONST, pres_monst=1, num_lines=2*(lines-3);
+    int max_monster;
+    char monst_name[40];
+
+    /* If we're not showing all, subtract out the UNIQUES and quartermaster */
+    if (!showall) num_monst -= NUMUNIQUE + 1;
+    max_monster = num_monst;
+
+#ifdef PC7300
+    nextmonst = 0;
+    for (i=1; i<=num_monst; i++) {
+	/* Only display existing monsters if we're not showing them all */
+	if (showall || monsters[i].m_normal) {
+	    strcpy(Displines[nextmonst], monsters[i]);
+	    Dispitems[nextmonst].mi_name = Displines[nextmonst];
+	    Dispitems[nextmonst].mi_flags = 0;
+	    Dispitems[nextmonst++].mi_val = i;
+	}
+    }
+
+    /* Place an end marker for the items */
+    Dispitems[nextmonst].mi_name = 0;
+
+    /* Set up the main menu structure */
+    Display.m_label = label;
+    Display.m_title = "Monster Listing";
+    Display.m_prompt = "Select a monster or press Cancl.";
+    Display.m_curptr = '\0';
+    Display.m_markptr = '\0';
+    Display.m_flags = 0;
+    Display.m_selcnt = 1;
+    Display.m_items = Dispitems;
+    Display.m_curi = 0;
+
+    /*
+     * Try to display the menu.  If we don't have a local terminal,
+     * the call will fail and we will just continue with the
+     * normal mode.
+     */
+    if (menu(&Display) >= 0) {
+	restscr(cw);
+	touchwin(cw);
+	return(Display.m_selcnt == 1 ? Display.m_curi->mi_val : -1);
+    }
+#endif
+
+    /* 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,
+				(showall || 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<=max_monster; i++) {
+	    sprintf(monst_name, "[%d] %c%s",
+				pres_monst,
+				(showall || 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(' ');
+	}
+
+	else {
+	    mvwaddstr(hw, 0, 0, "Which monster");
+	    if (!terse) {
+		waddstr(hw, " do you wish to ");
+		waddstr(hw, action);
+	    }
+	    waddstr(hw, "? ");
+	    draw(hw);
+	}
+    }
+
+get_monst:
+    get_str(monst_name, hw);
+    which_monst = atoi(monst_name);
+    if ((which_monst < 1 || which_monst > max_monster)) {
+	mvwaddstr(hw, 0, 0, "Please enter a number in the displayed range -- ");
+	draw(hw);
+	goto get_monst;
+    }
+    restscr(cw);
+    touchwin(cw);
+    return(which_monst);
+}
+
+/*
+ * passwd:
+ *	see if user knows password
+ */
+
+passwd()
+{
+    register char *sp, c;
+    char buf[LINELEN], *crypt();
+
+    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, "mT")) == 0);
+}
+
+
+/*
+ * teleport:
+ *	Bamf the hero someplace else
+ */
+
+teleport()
+{
+    register struct room *new_rp, *old_rp = roomin(&hero);
+    register int rm, which;
+    coord old;
+    bool got_position = FALSE;
+
+    /* Disrupt whatever the hero was doing */
+    dsrpt_player();
+
+    /*
+     * If the hero wasn't doing something disruptable, NULL out his
+     * action anyway and let him know about it.  We don't want him
+     * swinging or moving into his old place.
+     */
+    if (player.t_action != A_NIL) {
+	player.t_action = A_NIL;
+	msg("You feel momentarily disoriented.");
+    }
+
+    old = hero;
+    mvwaddch(cw, hero.y, hero.x, mvwinch(stdscr, hero.y, hero.x));
+    if (ISWEARING(R_TELCONTROL) || wizard) {
+	got_position = move_hero(H_TELEPORT);
+	if (!got_position)
+	    msg("Your attempt fails.");
+	else {
+	    new_rp = roomin(&hero);
+	    msg("You teleport successfully.");
+	}
+    }
+    if (!got_position) {
+	do {
+	    rm = rnd_room();
+	    rnd_pos(&rooms[rm], &hero);
+	} until(winat(hero.y, hero.x) == FLOOR);
+	new_rp = &rooms[rm];
+    }
+    player.t_oldpos = old;	/* Save last position */
+
+    /* If hero gets moved, darken old room */
+    if (old_rp && old_rp != new_rp) {
+	old_rp->r_flags |= FORCEDARK;	/* Fake darkness */
+	light(&old);
+	old_rp->r_flags &= ~FORCEDARK; /* Restore light state */
+    }
+
+    /* Darken where we just came from */
+    else if (levtype == MAZELEV) light(&old);
+
+    light(&hero);
+    mvwaddch(cw, hero.y, hero.x, PLAYER);
+    /* if entering a treasure room, wake everyone up......Surprise! */
+    if (new_rp->r_flags & ISTREAS)
+	wake_room(new_rp);
+
+    /* Reset current room and position */
+    oldrp = new_rp;	/* Used in look() */
+    player.t_oldpos = hero;
+    /*
+     * make sure we set/unset the ISINWALL on a teleport
+     */
+    which = winat(hero.y, hero.x);
+    if (isrock(which)) turn_on(player, ISINWALL);
+    else turn_off(player, ISINWALL);
+
+    /*
+     * 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, FALSE, FALSE))==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/arogue7/xcrypt.c	Fri May 08 15:24:40 2015 -0400
@@ -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 MASTER
+# 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);
+}