Import Advanced Rogue 5.8 from the Roguelike Restoration Project (r1490)
This commit is contained in:
parent
9ed6e5e369
commit
14fad3b319
47 changed files with 29836 additions and 0 deletions
178
arogue5/LICENSE.TXT
Normal file
178
arogue5/LICENSE.TXT
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
Portions Copyright (C) 1984 Robert D. Kindelberger
|
||||
Portions Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
Portions Copyright (C) 2005 Nicholas J. Kisseberth
|
||||
Portions Copyright (C) 1994 David Burren
|
||||
All rights reserved.
|
||||
|
||||
===========================================================================
|
||||
|
||||
Advanced Rogue
|
||||
Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name(s) of the author(s) nor the names of other contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
4. The name "Advanced Rogue" and "ARogue" must not be used to endorse or
|
||||
promote products derived from this software without prior written
|
||||
permission.
|
||||
5. Products derived from this software may not be called "Advanced Rogue" or
|
||||
"ARogue", nor may "Advanced Rogue" or "ARogue appear in their name,
|
||||
without prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
===========================================================================
|
||||
|
||||
Portions of this software are based on the work of Robert D. Kindelberger.
|
||||
Used under license:
|
||||
|
||||
Super-Rogue
|
||||
Copyright (C) 1984 Robert D. Kindelberger
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name(s) of the author(s) nor the names of other contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
4. The name "Super-Rogue" must not be used to endorse or promote products
|
||||
derived from this software without prior written permission.
|
||||
5. Products derived from this software may not be called "Super-Rogue",
|
||||
nor may "Super-Rogue" appear in their name, without prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
===========================================================================
|
||||
|
||||
Portions of this software are based on the work of Michael Toy, Ken Arnold
|
||||
and Glenn Wichman. Used under license:
|
||||
|
||||
Rogue: Exploring the Dungeons of Doom
|
||||
Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name(s) of the author(s) nor the names of other contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
===========================================================================
|
||||
|
||||
Portions of this software (save/restore game state) are based on the work
|
||||
of Nicholas J. Kisseberth. Used under license:
|
||||
|
||||
Copyright (C) 2005 Nicholas J. Kisseberth
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name(s) of the author(s) nor the names of other contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
===========================================================================
|
||||
|
||||
Portions of this software (encryption) are based on the work
|
||||
of David Burren. Used under license:
|
||||
|
||||
FreeSec: libcrypt
|
||||
|
||||
Copyright (C) 1994 David Burren
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name(s) of the author(s) nor the names of other contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
203
arogue5/Makefile
Normal file
203
arogue5/Makefile
Normal file
|
|
@ -0,0 +1,203 @@
|
|||
#
|
||||
# Makefile for rogue
|
||||
#
|
||||
# Advanced Rogue
|
||||
# Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
# All rights reserved.
|
||||
#
|
||||
# Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
# Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
# All rights reserved.
|
||||
#
|
||||
# See the file LICENSE.TXT for full copyright and licensing information.
|
||||
#
|
||||
|
||||
DISTNAME=arogue5.8.2
|
||||
PROGRAM=arogue58
|
||||
|
||||
O=o
|
||||
|
||||
HDRS = rogue.h mach_dep.h network.h
|
||||
OBJS1 = chase.$(O) command.$(O) daemon.$(O) daemons.$(O) encumb.$(O) \
|
||||
fight.$(O) init.$(O) io.$(O) list.$(O) main.$(O) maze.$(O) mdport.$(O)\
|
||||
misc.$(O) monsters.$(O) move.$(O) new_level.$(O) options.$(O) \
|
||||
outside.$(O)
|
||||
OBJS2 = pack.$(O) passages.$(O) player.$(O) potions.$(O) rings.$(O) rip.$(O) \
|
||||
rogue.$(O) rooms.$(O) save.$(O) scrolls.$(O) state.$(O) sticks.$(O) \
|
||||
things.$(O) trader.$(O) util.$(O) vers.$(O) weapons.$(O) wear.$(O) \
|
||||
wizard.$(O) xcrypt.$(O)
|
||||
OBJS = $(OBJS1) $(OBJS2)
|
||||
CFILES= \
|
||||
vers.c chase.c command.c daemon.c daemons.c encumb.c \
|
||||
fight.c init.c io.c list.c main.c maze.c mdport.c misc.c monsters.c \
|
||||
move.c new_level.c options.c outside.c pack.c passages.c player.c \
|
||||
potions.c rings.c rip.c rogue.c \
|
||||
rooms.c save.c scrolls.c state.c sticks.c things.c trader.c util.c \
|
||||
weapons.c wear.c wizard.c xcrypt.c
|
||||
|
||||
MISC= Makefile LICENSE.TXT arogue58.sln arogue58.vcproj
|
||||
DOCS= arogue58.doc arogue58.html
|
||||
|
||||
CC = gcc
|
||||
CFLAGS= -g
|
||||
CRLIB = -lcurses
|
||||
RM = rm -f
|
||||
TAR = tar
|
||||
.SUFFIXES: .obj
|
||||
|
||||
.c.obj:
|
||||
$(CC) $(CFLAGS) /c $*.c
|
||||
|
||||
$(PROGRAM): $(OBJS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(CRLIB) -o $@
|
||||
|
||||
tags: $(HDRS) $(CFILES)
|
||||
ctags -u $?
|
||||
ed - tags < :ctfix
|
||||
sort tags -o tags
|
||||
|
||||
lint:
|
||||
lint -hxbc $(CFILES) $(CRLIB) > linterrs
|
||||
|
||||
clean:
|
||||
$(RM) $(OBJS1)
|
||||
$(RM) $(OBJS2)
|
||||
$(RM) core a.exe a.out a.exe.stackdump $(PROGRAM) $(PROGRAM).exe $(PROGRAM).tar $(PROGRAM).tar.gz $(PROGRAM).zip
|
||||
|
||||
count:
|
||||
wc -l $(HDRS) $(CFILES)
|
||||
|
||||
realcount:
|
||||
cc -E $(CFILES) | ssp - | wc -l
|
||||
|
||||
update:
|
||||
ar uv .SAVE $(CFILES) $(HDRS) $(MISC)
|
||||
|
||||
dist:
|
||||
@mkdir dist
|
||||
cp $(CFILES) $(HDRS) $(MISC) dist
|
||||
|
||||
dist.src:
|
||||
make clean
|
||||
tar cf $(DISTNAME)-src.tar $(CFILES) $(HDRS) $(MISC) $(DOCS)
|
||||
gzip -f $(DISTNAME)-src.tar
|
||||
|
||||
dist.irix:
|
||||
make clean
|
||||
make CC=cc CFLAGS="-woff 1116 -O3" $(PROGRAM)
|
||||
tar cf $(DISTNAME)-irix.tar $(PROGRAM) LICENSE.TXT $(DOCS)
|
||||
gzip -f $(DISTNAME)-irix.tar
|
||||
|
||||
dist.aix:
|
||||
make clean
|
||||
make CC=xlc CFLAGS="-qmaxmem=16768 -O3 -qstrict" $(PROGRAM)
|
||||
tar cf $(DISTNAME)-aix.tar $(PROGRAM) LICENSE.TXT $(DOCS)
|
||||
gzip -f $(DISTNAME)-aix.tar
|
||||
|
||||
debug.linux:
|
||||
make clean
|
||||
make CFLAGS="-g -DWIZARD" $(PROGRAM)
|
||||
|
||||
dist.linux:
|
||||
make clean
|
||||
make $(PROGRAM)
|
||||
tar cf $(DISTNAME)-linux.tar $(PROGRAM) LICENSE.TXT $(DOCS)
|
||||
gzip -f $(DISTNAME)-linux.tar
|
||||
|
||||
debug.interix:
|
||||
make clean
|
||||
make CFLAGS="-g3 -DWIZARD" $(PROGRAM)
|
||||
|
||||
dist.interix:
|
||||
make clean
|
||||
make $(PROGRAM)
|
||||
tar cf $(DISTNAME)-interix.tar $(PROGRAM) LICENSE.TXT $(DOCS)
|
||||
gzip -f $(DISTNAME)-interix.tar
|
||||
|
||||
debug.cygwin:
|
||||
make clean
|
||||
make CFLAGS="-g3 -DWIZARD" $(PROGRAM)
|
||||
|
||||
dist.cygwin:
|
||||
make clean
|
||||
make CRLIB="-static -lcurses" $(PROGRAM)
|
||||
tar cf $(DISTNAME)-cygwin.tar $(PROGRAM).exe LICENSE.TXT $(DOCS)
|
||||
gzip -f $(DISTNAME)-cygwin.tar
|
||||
|
||||
#
|
||||
# Use MINGW32-MAKE to build this target
|
||||
#
|
||||
dist.mingw32:
|
||||
@$(MAKE) --no-print-directory RM="cmd /c del" clean
|
||||
@$(MAKE) --no-print-directory CRLIB="-lpdcurses" $(PROGRAM)
|
||||
cmd /c del $(DISTNAME)-mingw32.zip
|
||||
zip $(DISTNAME)-mingw32.zip $(PROGRAM).exe LICENSE.TXT $(DOCS)
|
||||
|
||||
dist.msys:
|
||||
@$(MAKE) --no-print-directory clean
|
||||
@$(MAKE) --no-print-directory CRLIB="-lcurses" $(PROGRAM)
|
||||
tar cf $(DISTNAME)-msys.tar $(PROGRAM).exe LICENSE.TXT $(DOCS)
|
||||
gzip -f $(DISTNAME)-msys.tar
|
||||
|
||||
debug.djgpp:
|
||||
make clean
|
||||
make CFGLAGS="-g3 -DWIZARD" LDFLAGS="-L$(DJDIR)/LIB" CRLIB="-lpdcurses" $(PROGRAM)
|
||||
|
||||
dist.djgpp:
|
||||
make clean
|
||||
make LDFLAGS="-L$(DJDIR)/LIB" CRLIB="-lpdcurses" $(PROGRAM)
|
||||
rm -f $(DISTNAME)-djgpp.zip
|
||||
zip $(DISTNAME)-djgpp.zip $(PROGRAM).exe LICENSE.TXT $(DOCS)
|
||||
|
||||
#
|
||||
# Use NMAKE to build this target
|
||||
#
|
||||
|
||||
debug.win32:
|
||||
nmake O="obj" RM="-del" clean
|
||||
nmake O="obj" CC="CL" CRLIB="..\pdcurses\pdcurses.lib shfolder.lib user32.lib Advapi32.lib" CFLAGS="-DWIZARD -nologo -I..\pdcurses -Ox -wd4033 -wd4716" $(PROGRAM)
|
||||
|
||||
dist.win32:
|
||||
nmake O="obj" RM="-del" clean
|
||||
nmake O="obj" CC="CL" CRLIB="..\pdcurses\pdcurses.lib shfolder.lib user32.lib Advapi32.lib" CFLAGS="-nologo -I..\pdcurses -Ox -wd4033 -wd4716" $(PROGRAM)
|
||||
-del $(DISTNAME)-win32.zip
|
||||
zip $(DISTNAME)-win32.zip $(PROGRAM).exe LICENSE.TXT $(DOCS)
|
||||
|
||||
vers.$(O): vers.c rogue.h
|
||||
chase.$(O): chase.c rogue.h
|
||||
command.$(O): command.c rogue.h
|
||||
daemon.$(O): daemon.c rogue.h
|
||||
daemons.$(O): daemons.c rogue.h
|
||||
encumb.$(O): encumb.c rogue.h
|
||||
fight.$(O): fight.c rogue.h
|
||||
init.$(O): init.c rogue.h
|
||||
io.$(O): io.c rogue.h
|
||||
list.$(O): list.c rogue.h
|
||||
main.$(O): main.c rogue.h
|
||||
maze.$(O): maze.c rogue.h
|
||||
misc.$(O): misc.c rogue.h
|
||||
monsters.$(O): monsters.c rogue.h
|
||||
move.$(O): move.c rogue.h
|
||||
new_level.$(O): new_level.c rogue.h
|
||||
options.$(O): options.c rogue.h
|
||||
outside.$(O): outside.c rogue.h
|
||||
pack.$(O): pack.c rogue.h
|
||||
passages.$(O): passages.c rogue.h
|
||||
player.$(O): player.c rogue.h
|
||||
potions.$(O): potions.c rogue.h
|
||||
rings.$(O): rings.c rogue.h
|
||||
rip.$(O): rip.c rogue.h
|
||||
rogue.$(O): rogue.c rogue.h
|
||||
rooms.$(O): rooms.c rogue.h
|
||||
save.$(O): save.c rogue.h
|
||||
scrolls.$(O): scrolls.c rogue.h
|
||||
state.$(O): state.c rogue.h
|
||||
sticks.$(O): sticks.c rogue.h
|
||||
things.$(O): things.c rogue.h
|
||||
trader.$(O): trader.c rogue.h
|
||||
util.$(O): util.c rogue.h
|
||||
weapons.$(O): weapons.c rogue.h
|
||||
wear.$(O): wear.c rogue.h
|
||||
wizard.$(O): wizard.c rogue.h
|
||||
xcrypt.$(O): xcrypt.c
|
||||
|
||||
1025
arogue5/arogue58.doc
Normal file
1025
arogue5/arogue58.doc
Normal file
File diff suppressed because it is too large
Load diff
953
arogue5/arogue58.html
Normal file
953
arogue5/arogue58.html
Normal file
|
|
@ -0,0 +1,953 @@
|
|||
<!-- Advanced Rogue -->
|
||||
<!-- Copyright (C) 1984, 1985, 1986 Michael Morgan, Ken Dalka and AT&T -->
|
||||
<!-- All rights reserved. -->
|
||||
<!-- -->
|
||||
<!-- Based on "Rogue: Exploring the Dungeons of Doom" -->
|
||||
<!-- Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman -->
|
||||
<!-- All rights reserved. -->
|
||||
<!-- -->
|
||||
<!-- See the file LICENSE.TXT for full copyright and licensing information. -->
|
||||
<!-- Creator : groff version 1.18.1 -->
|
||||
<!-- CreationDate: Sat Jan 21 09:55:23 2006 -->
|
||||
<h1 align="center"><a href="http://roguelike.sourceforge.net/arogue77">The Dungeons of
|
||||
Doom</a></h1>
|
||||
<br>
|
||||
<h2 align="center">AT&T Bell Laboratories</h2>
|
||||
<h3 align="center"><A href="http://roguelike.sourceforge.net/arogue58">http://roguelike.sourceforge.net/arogue58</A></h3>
|
||||
<br>
|
||||
<table border="0" cellpadding="3" cellspacing="3" style="BORDER-COLLAPSE: collapse" id="table1" align="center">
|
||||
<tr>
|
||||
<td nowrap>
|
||||
Advanced Rogue<br>
|
||||
Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T<br>
|
||||
All rights reserved.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td nowrap>
|
||||
Based on "Rogue: Exploring the Dungeons of Doom"<br>
|
||||
Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman<br>
|
||||
All rights reserved.
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p align="center">See the file LICENSE.TXT for full copyright and licensing
|
||||
information.</p>
|
||||
<p align="center"> </p>
|
||||
<p align="center"><b>ABSTRACT</b></p>
|
||||
<blockquote>
|
||||
<blockquote>
|
||||
<p align="justify">Rogue was first introduced by Michael Toy at the
|
||||
University of California at Berkeley as a screen-oriented fantasy game.
|
||||
The game had 26 types of monsters that the player could meet while
|
||||
exploring a dungeon generated by the computer. Scrolls, potions, rings,
|
||||
wands, staves, armor, and weapons helped the player to battle these
|
||||
monsters and to gain gold, the basis for scoring.</p>
|
||||
<p align="justify">The version of Rogue described in this guide has been
|
||||
expanded to include over 110 monsters with many new capabilities. Many
|
||||
of the monsters are intelligent, and they, like the player, must avoid
|
||||
traps and decide when it is better to fight or to run. The player
|
||||
chooses a character class at the beginning of the game which defines the
|
||||
player's abilities. Experience, rather than gold, decides the player's
|
||||
score.</p>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
<h2 align="justify"> </h2>
|
||||
<h3 align="justify">1. INTRODUCTION</h3>
|
||||
<p align="justify">
|
||||
Rogue is a screen-oriented fantasy game set in the ever-changing Dungeons of
|
||||
Doom. The game comes complete with monsters, spells, weapons, armor,
|
||||
potions, and other magical items. The dungeon's geography changes with every
|
||||
game, and although many magical items have certain identifiable properties,
|
||||
such as turning the player invisible, the physical manifestation of the
|
||||
magic changes each game. A red potion, for example, will cause the same
|
||||
reaction throughout a given game, but it may be a completely different
|
||||
potion in a new game.</p>
|
||||
<p align="justify">
|
||||
Entering the dungeon with only a little food, armor, and a weapon, the
|
||||
player must develop a good strategy of when to fight, when to run, and how
|
||||
to best use any magical items found in the dungeon. To make things
|
||||
interesting, the player has a quest to return one of several unique
|
||||
artifacts, rumored to lie deep in the dungeon's bowels. Returning with this
|
||||
artifact brings great glory and the title of Complete Winner. But even after
|
||||
finding the artifact, the player may wish to continue further to match wits
|
||||
with an arch-devil, demon prince, or even a deity found far down in the
|
||||
dungeon. Defeating such a creature will gain the player many experience
|
||||
points, the basis for scoring in Rogue.</p>
|
||||
<p align="justify">
|
||||
It is very difficult to return from the Dungeons of Doom. Few people ever
|
||||
make it out alive. Should this unlikely event occur, the player would be
|
||||
proclaimed a complete winner and handsomely rewarded for any booty removed
|
||||
from the dungeon.</p>
|
||||
<h3 align="justify">2. CHARACTER CLASSES AND ATTRIBUTES</h3>
|
||||
<p align="justify">
|
||||
Before placing the player in the dungeon, the game requests the player to
|
||||
select a character class: a fighter, a magic user, a cleric, or a thief.</p>
|
||||
<p align="justify"><span style="FONT-VARIANT: small-caps"><strong>2.1 The Fighter</strong></span></p>
|
||||
<p align="justify">
|
||||
A fighter is very strong and will have a high strength rating. This great
|
||||
strength gives a fighter the best odds of winning a battle with a monster.
|
||||
At high experience levels the fighter also gets to attack multiple times in
|
||||
a single turn. This obviously further increases his chances at winning
|
||||
battles. Intrinsic to the fighter class is a robustness which results in 1
|
||||
to 10 extra hit points for every new experience level.</p>
|
||||
<p align="justify"><span style="FONT-VARIANT: small-caps"><strong>2.2 The Magician</strong></span></p>
|
||||
<p align="justify">
|
||||
A magician's major attribute is intelligence, which enables the magician to
|
||||
cast spells. The number and variety of spells increases as the magician
|
||||
gains experience and intelligence. Other types of characters can cast
|
||||
spells, but only if they manage to gain extraordinarily high intelligence.
|
||||
Magic users are not as hearty as fighters; they receive 1 to 8 extra hit
|
||||
points for every new experience level.</p>
|
||||
<p align="justify"><strong><span style="FONT-VARIANT: small-caps">2.3 The Cleric</span></strong></p>
|
||||
<p align="justify">
|
||||
A cleric has a high wisdom rating and can thus pray. The number and variety
|
||||
of prayers which the gods are willing to grant to a cleric increase as the
|
||||
cleric gains experience and wisdom. Other character types can pray only if
|
||||
they manage to gain extraordinary wisdom.</p>
|
||||
<p align="justify">
|
||||
Because of their religious nature, clerics can also affect the "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 Thief</span></strong></p>
|
||||
<p align="justify">
|
||||
A thief is exceptionally dextrous and has a good chance to set a trap or rob
|
||||
a monster. Any type of character can try to set a trap or steal from a
|
||||
monster standing next to the character, but the chances of success are low
|
||||
compared to a thief's chances.
|
||||
</p>
|
||||
<p align="justify">
|
||||
By their nature, thieves can automatically detect all the gold on the
|
||||
current level of the dungeon. They are also good at detecting hidden traps.
|
||||
Because thieves slink along, they are not as likely as other characters to
|
||||
wake sleeping monsters. If a thief manages to sneak up on a creature without
|
||||
waking it, he will get a chance to backstab the monster. When this is done,
|
||||
the damage done by the thief greatly increases based on his experience
|
||||
level.</p>
|
||||
<p align="justify">
|
||||
Thieves gain from 1 to 6 extra hit points from a new experience level.
|
||||
</p>
|
||||
<p align="justify"><strong><span style="FONT-VARIANT: small-caps">2.5
|
||||
CONSTITUTION</span></strong></p>
|
||||
<p align="justify">Every character has a constitution rating. A character with
|
||||
an exceptionally good constitution will gain more than the normal amount of hit
|
||||
points associated with the character's class when the character reaches a new
|
||||
experience level. Exceptional constitution also provides better protection
|
||||
versus poison-based attacks and diseases.</p>
|
||||
<p align="justify"><strong><span style="FONT-VARIANT: small-caps">2.6 Experience Levels</span></strong></p>
|
||||
<p align="justify">
|
||||
Characters gain experience for killing monsters, stealing from monsters, and
|
||||
turning monsters. Each character class has a set of thresholds associated
|
||||
with it. When a character reaches a threshold, the character attains the
|
||||
next experience level. This new level brings extra hit points and a greater
|
||||
chance of success in performing the abilities associated with the
|
||||
character's class. Magicians receive new spells, and clerics receive new
|
||||
prayers.</p>
|
||||
<p align="justify">
|
||||
Thieves have the lowest threshold for gaining experience levels, followed by
|
||||
clerics. Fighters are next, and magicians have the highest threshold.</p>
|
||||
<h3 align="justify">
|
||||
3. THE SCREEN</h3>
|
||||
<p align="justify">
|
||||
During the normal course of play, the screen consists of three separate
|
||||
sections: the top line of the terminal, the bottom two lines of the
|
||||
terminal, and the remaining middle lines. The top line reports actions which
|
||||
occur during the game, the middle section depicts the dungeon, and the
|
||||
bottom lines describe the player's current condition.</p>
|
||||
<p align="justify"><strong><span style="FONT-VARIANT: small-caps">3.1 The Top Line</span></strong>
|
||||
<p align="justify">
|
||||
Whenever anything happens to the player, such as finding a scroll or hitting
|
||||
or being hit by a monster, a short report of the occurrence appears on the
|
||||
top line of the screen. When such reports occur quickly, one right after
|
||||
another, the game displays the notice followed by the prompt '--More--.'
|
||||
After reading this notice, the player can press a space to display the next
|
||||
message. At such a point, the game ignores all commands until the player
|
||||
presses a space.</p>
|
||||
<p align="justify">
|
||||
<strong>
|
||||
<span style="FONT-VARIANT: small-caps">3.2 The Dungeon Section</span></strong>
|
||||
<p align="justify">
|
||||
The large middle section of the screen displays the player's surroundings using
|
||||
the following symbols:
|
||||
</p>
|
||||
<p>
|
||||
<table border="0" cellpadding="3" style="BORDER-COLLAPSE: collapse" id="table3" cellspacing="3">
|
||||
<tr>
|
||||
<td align="middle">|</td>
|
||||
<td>
|
||||
</td>
|
||||
<td>A wall of a room.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle">-</td>
|
||||
<td> </td>
|
||||
<td>A wall of a room.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle">*</td>
|
||||
<td> </td>
|
||||
<td>A pile of gold.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle">%</td>
|
||||
<td> </td>
|
||||
<td>A way to the next level.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle">+</td>
|
||||
<td> </td>
|
||||
<td>A doorway.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle">.</td>
|
||||
<td> </td>
|
||||
<td>The floor in a room.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle">@</td>
|
||||
<td> </td>
|
||||
<td>The player.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle">_</td>
|
||||
<td> </td>
|
||||
<td>The player, when invisible.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle">#</td>
|
||||
<td> </td>
|
||||
<td>The floor in a passageway.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle">!</td>
|
||||
<td> </td>
|
||||
<td>A flask containing a potion.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle">?</td>
|
||||
<td> </td>
|
||||
<td>A sealed scroll.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle">:</td>
|
||||
<td> </td>
|
||||
<td>Some food.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle">)</td>
|
||||
<td> </td>
|
||||
<td>A weapon.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle"> </td>
|
||||
<td nowrap> </td>
|
||||
<td nowrap>Solid rock (denoted by a space).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle">]</td>
|
||||
<td> </td>
|
||||
<td>Some armor.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle">;</td>
|
||||
<td> </td>
|
||||
<td>A miscellaneous magic item.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle">,</td>
|
||||
<td> </td>
|
||||
<td>An artifact.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle">=</td>
|
||||
<td> </td>
|
||||
<td>A ring.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle">/</td>
|
||||
<td> </td>
|
||||
<td>A wand or a staff.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle">^</td>
|
||||
<td> </td>
|
||||
<td>The entrance to a trading post.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle">></td>
|
||||
<td> </td>
|
||||
<td>A trapdoor leading to the next level</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle">{</td>
|
||||
<td> </td>
|
||||
<td>An arrow trap</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle">$</td>
|
||||
<td> </td>
|
||||
<td>A sleeping gas trap</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle">}</td>
|
||||
<td> </td>
|
||||
<td>A beartrap</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle">~</td>
|
||||
<td> </td>
|
||||
<td>A trap that teleports you somewhere else</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle">`</td>
|
||||
<td> </td>
|
||||
<td>A poison dart trap</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle">"</td>
|
||||
<td> </td>
|
||||
<td>a shimmering magic pool</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle">'</td>
|
||||
<td> </td>
|
||||
<td>An entrance to a maze</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle">$</td>
|
||||
<td> </td>
|
||||
<td>Any magical item. (During magic detection)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle">></td>
|
||||
<td nowrap> </td>
|
||||
<td nowrap>A blessed magical item. (During magic detection)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle"><</td>
|
||||
<td> </td>
|
||||
<td>A cursed magical item. (During magic detection)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle">A letter</td>
|
||||
<td> </td>
|
||||
<td>A monster. Note that a given letter may signify<br>
|
||||
multiple monsters, depending on the level of the<br>
|
||||
dungeon. The player can always identify a current<br>
|
||||
monster by using the identify command ('/').</td>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
<p align="justify"><strong><span style="FONT-VARIANT: small-caps">3.3 The Status Section</span></strong></p>
|
||||
<p align="justify">
|
||||
The bottom two lines of the screen describe the player's current status. The
|
||||
first line gives the player's characteristics:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<p align="justify">Intelligence (Int)</p>
|
||||
<li>
|
||||
<p align="justify">Strength (Str)</p>
|
||||
<li>
|
||||
<p align="justify">Wisdom (Wis)</p>
|
||||
<li>
|
||||
<p align="justify">Dexterity (Dxt)</p>
|
||||
<li>
|
||||
<p align="justify">Constitution (Const)</p>
|
||||
<li>
|
||||
<p align="justify">Charisma (Char)</p>
|
||||
<li>
|
||||
<p align="justify">Encumbrance (Carry)</p>
|
||||
</li>
|
||||
</ul>
|
||||
<p align="justify">
|
||||
Intelligence, strength, wisdom, dexterity, and constitution have a normal
|
||||
maximum of 25, but can be higher when augmented by a ring. Encumbrance is a
|
||||
measurement of how much the player can carry versus how much he is currently
|
||||
carrying. The more you carry relative to your maximum causes you to use more
|
||||
food.</p>
|
||||
<p align="justify">
|
||||
The second status line provides the following information:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<p align="justify">The current level (Lvl) in the dungeon. This number
|
||||
increases as the player goes further down.</p>
|
||||
<li>
|
||||
<p align="justify">How much gold (Au) the player is carrying.</p>
|
||||
<li>
|
||||
<p align="justify">The player's current number of hit points (Hp), followed
|
||||
in parentheses by the player's current maximum number of hit points. Hit
|
||||
points express the player's health. As a player heals by resting, the
|
||||
player's current hit points gradually increase until reaching the current
|
||||
maximum. This maximum increases each time a player attains a new experience
|
||||
level. If the player's current hit points reach 0, the player dies.</p>
|
||||
<li>
|
||||
<p align="justify">The player's armor class (Ac). This number describes the
|
||||
amount of protection provided by the armor and rings currently worn by the
|
||||
player. Wearing no armor is equivalent to an armor class of 10. The
|
||||
protection level increases as the armor class decreases.</p>
|
||||
<li>
|
||||
<p align="justify">The player's current experience level (Exp) followed by
|
||||
the player's experience points. The player can gain experience points by
|
||||
killing monsters, successfully stealing from monsters, and turning monsters.
|
||||
When a player gains enough experience points to surpass a threshold that
|
||||
depends on the player's character type, the player reaches a new experience
|
||||
level. A new experience level brings extra hit points and possibly added
|
||||
abilities, such as a new spell for a magician or a new prayer for a cleric.</p>
|
||||
<li>
|
||||
<p align="justify">A description of the player's character. This description
|
||||
depends on the player's character type and experience level.</p>
|
||||
</li>
|
||||
</ul>
|
||||
<h3 align="justify">4. COMMANDS</h3>
|
||||
<p align="justify">
|
||||
A player can invoke most Rogue commands by typing a single character. Some
|
||||
commands, however, require a direction, in which case the player types the
|
||||
command character followed by a directional command. Many commands can be
|
||||
prefaced by a number, indicating how many times the command should be
|
||||
executed.</p>
|
||||
<p align="justify">
|
||||
When the player invokes a command referring to an item in the player's pack
|
||||
(such as reading a scroll), the game prompts for the item. The player should
|
||||
then type the letter associated with the item, as displayed by the inventory
|
||||
command. Typing a '*' at this point produces a list of the eligible items.</p>
|
||||
<p align="center"><b><i>Rogue understands the following commands:</i></b></p>
|
||||
<p>
|
||||
<table border="0" cellpadding="3" style="BORDER-COLLAPSE: collapse" id="table4" cellspacing="3">
|
||||
<tr>
|
||||
<td align="middle" valign="top">?</td>
|
||||
<td> </td>
|
||||
<td>Preceding a command by a '?' produces a brief explanation of the command. The
|
||||
command '?*' gives an explanation of all the commands.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">/</td>
|
||||
<td> </td>
|
||||
<td>Preceding a symbol by a '/' identifies the symbol.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">h</td>
|
||||
<td> </td>
|
||||
<td>Move one position to the left.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">j</td>
|
||||
<td> </td>
|
||||
<td>Move one position down.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">k</td>
|
||||
<td> </td>
|
||||
<td>Move one position up.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">l</td>
|
||||
<td> </td>
|
||||
<td>Move one position to the right.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">y</td>
|
||||
<td height="21"> </td>
|
||||
<td height="21">Move one position to the top left.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">u</td>
|
||||
<td> </td>
|
||||
<td>Move one position to the top right.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">b</td>
|
||||
<td> </td>
|
||||
<td>Move one position to the bottom left.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">n</td>
|
||||
<td> </td>
|
||||
<td>Move one position to the bottom right</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">H</td>
|
||||
<td> </td>
|
||||
<td>Run to the left until reaching something interesting.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">J</td>
|
||||
<td> </td>
|
||||
<td>Run down until reaching something interesting.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">K</td>
|
||||
<td> </td>
|
||||
<td>Run up until reaching something interesting.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">L</td>
|
||||
<td> </td>
|
||||
<td>Run to the right until reaching something interesting.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">Y</td>
|
||||
<td> </td>
|
||||
<td>Run to the top left until reaching something interesting.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">U</td>
|
||||
<td> </td>
|
||||
<td>Run to the top right until reaching something interesting.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">B</td>
|
||||
<td> </td>
|
||||
<td>Run to the bottom left until reaching something interesting.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">N</td>
|
||||
<td> </td>
|
||||
<td>Run to the bottom right until reaching something interesting</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">t</td>
|
||||
<td> </td>
|
||||
<td>This command, followed by a directional command, prompts for an
|
||||
object from the players pack. The player then throws the object in the
|
||||
specified direction.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">f</td>
|
||||
<td> </td>
|
||||
<td>When this command precedes a directional command, the player moves
|
||||
in the specified direction until passing something interesting.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">z</td>
|
||||
<td> </td>
|
||||
<td>This command must be followed by a directional command. Rogue then
|
||||
prompts for a wand or staff from the player's pack and zaps it in the
|
||||
specified direction.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">></td>
|
||||
<td> </td>
|
||||
<td>Go down to the next level.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top"><</td>
|
||||
<td> </td>
|
||||
<td>Go up to the next level.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">s</td>
|
||||
<td> </td>
|
||||
<td>Search for a secret door or a trap in the circle surrounding the player.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">.</td>
|
||||
<td> </td>
|
||||
<td>This command (a dot) causes the player to rest a turn.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">i</td>
|
||||
<td> </td>
|
||||
<td>Display an inventory of the player's pack.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">I</td>
|
||||
<td> </td>
|
||||
<td>This command prompts for an item from the player's pack and displays
|
||||
the inventory information for that item.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">q</td>
|
||||
<td> </td>
|
||||
<td>Quaff a potion from the player's pack.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">r</td>
|
||||
<td> </td>
|
||||
<td>Read a scroll from the player's pack.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">e</td>
|
||||
<td> </td>
|
||||
<td>Eat some food from the player's pack.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">w</td>
|
||||
<td> </td>
|
||||
<td>Wield a weapon from the player's pack.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">W</td>
|
||||
<td> </td>
|
||||
<td>Wear some armor or miscellaneous magic item from the player's pack.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">T</td>
|
||||
<td> </td>
|
||||
<td>Take off whatever the player is wearing.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">P</td>
|
||||
<td> </td>
|
||||
<td>Put on a ring from the player's pack. The player can wear a maximum
|
||||
of eight rings.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">R</td>
|
||||
<td> </td>
|
||||
<td>Remove a ring from the player's hand.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">^U</td>
|
||||
<td> </td>
|
||||
<td>Use a miscellaneous magic item in the player's pack.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">d</td>
|
||||
<td> </td>
|
||||
<td>Drop an item from the player's pack.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">c</td>
|
||||
<td> </td>
|
||||
<td>When the player types this command, Rogue prompts for an item from
|
||||
the player's pack and a one-line name. Rogue then calls all similar
|
||||
items (such as all the blue potions) by the specified name.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">m</td>
|
||||
<td> </td>
|
||||
<td>When the player types this command, Rogue prompts for an item from
|
||||
the player's pack and a one-line name. Rogue then marks the specified
|
||||
item with the given name.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">o</td>
|
||||
<td> </td>
|
||||
<td>Typing this command causes Rogue to display all the settable
|
||||
options. The player can then merely examine the options or change any or
|
||||
all of them.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">C</td>
|
||||
<td> </td>
|
||||
<td>This command, restricted to magicians and characters with
|
||||
exceptionally high intelligence, produces a listing of the magician's
|
||||
current supply of spells. The player can select one of the displayed
|
||||
spells and, if the player's energy level is sufficiently high, cast it.
|
||||
The more complicated the spell, the more energy it takes.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">p</td>
|
||||
<td> </td>
|
||||
<td>This command, restricted to clerics and characters with
|
||||
exceptionally high wisdom, produces a listing of the cleric's known
|
||||
prayers. The player can then offer one of these prayers to the
|
||||
character's deity. Deities are not known for favoring characters which
|
||||
continually pray to them, and they are most likely to answer the least
|
||||
"ambitious" prayers.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">a</td>
|
||||
<td> </td>
|
||||
<td>This command is restricted to clerics and characters with
|
||||
exceptionally high wisdom and must be followed by a directional command.
|
||||
If there is an "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.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">^</td>
|
||||
<td> </td>
|
||||
<td>This command sets a trap and is most likely to succeed for a
|
||||
character with a high dexterity, such as a thief. If the character is
|
||||
successful, Rogue prompts the player for a type of trap and sets it
|
||||
where the player is standing.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">G</td>
|
||||
<td> </td>
|
||||
<td>This command is restricted to thieves. It causes Rogue to display
|
||||
all the gold on the current level.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">D</td>
|
||||
<td> </td>
|
||||
<td>Dip something into a magic pool.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">^T</td>
|
||||
<td height="22"> </td>
|
||||
<td height="22">This command is most likely to succeed for a character
|
||||
with a high dexterity, such as a thief, and it must be followed by a
|
||||
directional command. If there is a monster standing next to the player
|
||||
in the specified direction, the player tries to steal an item from the
|
||||
monster's pack. If the player is successful, the monster does not notice
|
||||
anything, but if the player is unsuccessful, there is a chance the
|
||||
monster will wake up.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">^L</td>
|
||||
<td> </td>
|
||||
<td>Redraw the screen.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">^R</td>
|
||||
<td> </td>
|
||||
<td>Repeat the last message that was displayed on the top line of the screen.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">Escape (^[)</td>
|
||||
<td> </td>
|
||||
<td>Typing an escape will usually cause Rogue to cancel the current command.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">v</td>
|
||||
<td> </td>
|
||||
<td>Print the current Rogue version number.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">!</td>
|
||||
<td> </td>
|
||||
<td>Escape to the shell level.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">S</td>
|
||||
<td> </td>
|
||||
<td>Quit and save the game for resumption at a later time.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="middle" valign="top">Q</td>
|
||||
<td> </td>
|
||||
<td>Quit without saving the game.</td>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
<h3 align="justify">5. 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">6. LIGHT</h3>
|
||||
<p align="justify">
|
||||
Some rooms in the dungeon possess a natural light source. In other rooms and
|
||||
in corridors the player can see only those things within a one space radius
|
||||
from the player. These dark rooms can be lit with magical light or by a fire
|
||||
beetle.</p>
|
||||
<h3 align="justify">7. WEAPONS AND ARMOR</h3>
|
||||
<p align="justify">
|
||||
The player can wield exactly one weapon at a time. When the player attacks a
|
||||
monster, the amount of damage depends on the particular weapon the player is
|
||||
wielding. To fire a projectile weapon, such as a crossbow or a short bow,
|
||||
the player should wield the bow and "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.</p>
|
||||
<h3 align="justify">8. POTIONS AND SCROLLS</h3>
|
||||
<p align="justify">
|
||||
The player can frequently find potions and scrolls in the dungeon. In any
|
||||
given dungeon, the player can distinguish among the different types of
|
||||
potions by a potion's color and among the different types of scrolls by a
|
||||
scroll's name. Quaffing a potion or reading a scroll usually causes some
|
||||
magical occurrence. Most potions and scrolls may be cursed or blessed.</p>
|
||||
<h3 align="justify">9. RINGS</h3>
|
||||
<p align="justify">
|
||||
The player can wear a maximum of eight rings, and they have a magical effect
|
||||
on the player as long as they are worn. Some rings also speed up the
|
||||
player's metabolism, making the player require food more often. Many rings
|
||||
can be cursed or blessed, and the player cannot remove a cursed ring. The
|
||||
player can distinguish among different types of rings by a ring's jewel.</p>
|
||||
<h3 align="justify">10. WANDS AND STAVES</h3>
|
||||
<p align="justify">
|
||||
Wands and staves affect the player's environment. The player can zap a wand
|
||||
or staff at something and perhaps shoot a bolt of lightning at it or
|
||||
teleport it away. All wands or staves of the same type are constructed with
|
||||
the same type of wood. Some wands and staves may be cursed or blessed.</p>
|
||||
<h3 align="justify">11. FOOD</h3>
|
||||
<p>The player must be careful not to run out of food since moving through the
|
||||
dungeon fighting monsters consumes a lot of energy. Starving results in the
|
||||
player's fainting for increasingly longer periods of time, during which any
|
||||
nearby monster can attack the player freely. </p>
|
||||
<h3 align="justify">12. GOLD</h3>
|
||||
<p>Gold has one use in a dungeon: buying things. One can buy things in two ways,
|
||||
either in a trading post or from a quartermaster. A trading post is a place
|
||||
"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>
|
||||
<h3 align="justify">13. MISCELLANEOUS MAGIC ITEMS</h3>
|
||||
<p align="justify">
|
||||
Miscellaneous items such as a pair of boots or a book may be found within
|
||||
the dungeon. These items can usually be used to the player's advantage
|
||||
(assuming they are not cursed). Some of these items can be worn, such as a
|
||||
cloak, while others are to be used, such as a book.</p>
|
||||
<h3 align="justify">14. ARTIFACTS</h3>
|
||||
<p align="justify">
|
||||
Some monsters down in the depths of the dungeon carry unique artifacts. The
|
||||
game begins as a quest to retrieve one of these items. Each artifact appears
|
||||
only on its owner's person.</p>
|
||||
<h3 align="justify">15. TRAPS</h3>
|
||||
<p align="justify">
|
||||
A variety of traps, including trap doors, bear traps, and sleeping
|
||||
traps, are hidden in the dungeon. They remain hidden until sprung by a
|
||||
monster or the player. A sprung trap continues to function, but since it is
|
||||
visible, an intelligent monster is not likely to tread on it.</p>
|
||||
<h3 align="justify">16. THE MONSTERS</h3>
|
||||
<p align="justify">
|
||||
Each monster except for the merchant quartermaster appears in a limited
|
||||
range of dungeon levels. All monsters of the same type share the same
|
||||
abilities; all giant rats, for example, can give the player a disease, and
|
||||
all jackalweres can put the player to sleep. Monsters of the same type can
|
||||
vary, however, such that one kobold may be much more difficult to kill than
|
||||
another one. In general, the more difficult it is to kill a monster, the
|
||||
more experience points the monster is worth.</p>
|
||||
<p align="justify">
|
||||
Most monsters attack by biting and clawing, but some monsters carry weapons,
|
||||
including such projectile weapons as short bows and crossbows, and some
|
||||
monsters have breath weapons. These latter monsters can attack the player
|
||||
from across a room or down a corridor.</p>
|
||||
<p align="justify">
|
||||
Some monsters are more intelligent than others, and the more intelligent a
|
||||
monster, the more likely that the monster will run away if it is about to
|
||||
die. A fleeing monster will not attack the player unless cornered.</p>
|
||||
<p align="justify">As the player moves down in the dungeon, the monsters get
|
||||
more powerful. Deep down in the dungeon there exist some one-of-a-kind monsters.
|
||||
These monsters are greatly feared. However, once a "unique monster" is killed,
|
||||
the player will not find another in the current dungeon.</p>
|
||||
<h3 align="justify">17. OPTIONS</h3>
|
||||
<p align="justify">
|
||||
Rogue has several options which may be set by the player:
|
||||
</p>
|
||||
<p>
|
||||
<table border="0" cellpadding="3" style="BORDER-COLLAPSE: collapse" id="table5" cellspacing="3">
|
||||
<tr>
|
||||
<td valign="top">terse</td>
|
||||
<td> </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> </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> </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> </td>
|
||||
<td>Setting this Boolean option results in flushing all type ahead
|
||||
(pending) commands when the player encounters a monster.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">askme</td>
|
||||
<td nowrap> </td>
|
||||
<td>Setting this Boolean option results in the game prompting the player
|
||||
for a name upon encountering a new type of scroll, potion, ring, staff,
|
||||
or wand.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">name</td>
|
||||
<td> </td>
|
||||
<td>This string is the player's name and defaults to the player's
|
||||
account name.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">fruit</td>
|
||||
<td> </td>
|
||||
<td>This string identifies the player's favorite fruit, sometimes
|
||||
encountered in the dungeon. It defaults to slime-mold.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">file</td>
|
||||
<td> </td>
|
||||
<td>This string, which defaults to rogue.save, specifies the file to use
|
||||
for saving the game.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">score</td>
|
||||
<td> </td>
|
||||
<td>This string identifies the top-ten score file to use for the game.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">class</td>
|
||||
<td> </td>
|
||||
<td>This option specifies the character class of the rogue. It can be
|
||||
set only in the ROGUEOPTS environment variable.</td>
|
||||
</tr>
|
||||
</table>
|
||||
</p>
|
||||
<p align="justify">
|
||||
The player can set options at the beginning of a game via the ROGUEOPTS
|
||||
environment variable. Naming a Boolean option sets it, and preceding the
|
||||
Boolean option name by "no" clears it. The syntax "stringoption=name" sets a
|
||||
string option to "name." So setting ROGUEOPTS to "terse, jump, nostep,
|
||||
flush, askme, name=Ivan the Terrible, fruit=pomegranate" would set the
|
||||
terse, jump, flush, and askme Boolean options, clear the step Boolean
|
||||
option, set the player's name to "Ivan the Terrible," set the player's
|
||||
favorite fruit to a pomegranate, and use the defaults for the save file and
|
||||
the score file.</p>
|
||||
<p align="justify">
|
||||
The player may change an option at any time during the game via the option
|
||||
command, which results in a listing of the current options. Typing a new
|
||||
value changes the option, a RETURN moves to the next option, a '-' moves to
|
||||
the previous option, and an ESCAPE returns the player to the dungeon.</p>
|
||||
<h3 align="justify">18. SCORING</h3>
|
||||
<p>The player receives experience points for stealing items from monsters,
|
||||
turning monsters (a clerical ability), and killing monsters. When the player
|
||||
gets killed, the player's score equals the player's experience points. A player
|
||||
who quits gets a score equal to the player's experience points and gold. If the
|
||||
player makes it back up out of the dungeon, the player's score equals the
|
||||
player's experience points plus the gold the player carried and the gold
|
||||
received from selling the player's possessions. Rogue maintains a list of the
|
||||
top ten scores to date, together with the name of the player obtaining the
|
||||
score, the level where the player finished, and the manner in which the player
|
||||
ended the game.</p>
|
||||
<h3 align="justify">19. ACKNOWLEDGEMENTS</h3>
|
||||
<p align="justify">
|
||||
This version of Rogue is based on a version developed at the University of
|
||||
California at Berkeley by Michael Toy and Ken Arnold.</p>
|
||||
24
arogue5/arogue58.sln
Normal file
24
arogue5/arogue58.sln
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
Microsoft Visual Studio Solution File, Format Version 7.00
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "arogue58", "arogue58.vcproj", "{2EEE53AB-A85A-4D4D-8DB2-B5F23513F415}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
ConfigName.0 = Debug
|
||||
ConfigName.1 = Release
|
||||
ConfigName.2 = test
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectDependencies) = postSolution
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfiguration) = postSolution
|
||||
{2EEE53AB-A85A-4D4D-8DB2-B5F23513F415}.Debug.ActiveCfg = Debug|Win32
|
||||
{2EEE53AB-A85A-4D4D-8DB2-B5F23513F415}.Debug.Build.0 = Debug|Win32
|
||||
{2EEE53AB-A85A-4D4D-8DB2-B5F23513F415}.Release.ActiveCfg = Release|Win32
|
||||
{2EEE53AB-A85A-4D4D-8DB2-B5F23513F415}.Release.Build.0 = Release|Win32
|
||||
{2EEE53AB-A85A-4D4D-8DB2-B5F23513F415}.test.ActiveCfg = Debug|Win32
|
||||
{2EEE53AB-A85A-4D4D-8DB2-B5F23513F415}.test.Build.0 = Debug|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityAddIns) = postSolution
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
305
arogue5/arogue58.vcproj
Normal file
305
arogue5/arogue58.vcproj
Normal file
|
|
@ -0,0 +1,305 @@
|
|||
<?xml version="1.0" encoding = "Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.00"
|
||||
Name="arogue58"
|
||||
ProjectGUID="{2EEE53AB-A85A-4D4D-8DB2-B5F23513F415}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="Debug"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/I.. /wd4033 /wd4716"
|
||||
Optimization="0"
|
||||
OptimizeForWindowsApplication="TRUE"
|
||||
AdditionalIncludeDirectories="../pdcurses"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
|
||||
MinimalRebuild="FALSE"
|
||||
ExceptionHandling="FALSE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="5"
|
||||
BufferSecurityCheck="TRUE"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="1"
|
||||
DisableSpecificWarnings="4013;4033;4716"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="pdcurses.lib Ws2_32.lib"
|
||||
AdditionalDependencies="shfolder.lib pdcurses.lib"
|
||||
OutputFile="$(OutDir)/arogue58.exe"
|
||||
LinkIncremental="0"
|
||||
AdditionalLibraryDirectories="..\pdcurses"
|
||||
IgnoreDefaultLibraryNames="LIBC.LIB"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/arogue58.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="Release"
|
||||
IntermediateDirectory="Release"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
OmitFramePointers="TRUE"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="4"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
UsePrecompiledHeader="3"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)/arogue58.exe"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="test|Win32"
|
||||
OutputDirectory="test"
|
||||
IntermediateDirectory="test"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="5"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)/arogue58.exe"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/arogue58.pdb"
|
||||
SubSystem="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm">
|
||||
<File
|
||||
RelativePath="chase.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="command.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="daemon.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="daemons.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="encumb.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="fight.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="init.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="io.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="list.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="main.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="maze.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="mdport.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="misc.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="monsters.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="move.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="new_level.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="options.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="outside.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="pack.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="passages.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="player.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="potions.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="rings.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="rip.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="rogue.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="rooms.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="save.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="scrolls.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="state.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="sticks.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="things.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="trader.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="util.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="vers.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="weapons.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="wear.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="wizard.c">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="xcrypt.c">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc">
|
||||
<File
|
||||
RelativePath="mach_dep.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="network.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="rogue.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath="LICENSE.TXT">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="Makefile">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="arogue58.doc">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="arogue58.html">
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
1008
arogue5/chase.c
Normal file
1008
arogue5/chase.c
Normal file
File diff suppressed because it is too large
Load diff
938
arogue5/command.c
Normal file
938
arogue5/command.c
Normal file
|
|
@ -0,0 +1,938 @@
|
|||
/*
|
||||
* Read and execute the user commands
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "curses.h"
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include <signal.h>
|
||||
#include "mach_dep.h"
|
||||
#include "rogue.h"
|
||||
|
||||
/*
|
||||
* command:
|
||||
* Process the user commands
|
||||
*/
|
||||
|
||||
command()
|
||||
{
|
||||
register char ch;
|
||||
register int ntimes = 1; /* Number of player moves */
|
||||
static char countch, direction, newcount = FALSE;
|
||||
struct linked_list *item;
|
||||
bool an_after = FALSE;
|
||||
|
||||
if (on(player, ISHASTE)) {
|
||||
ntimes++;
|
||||
turns--; /* correct for later */
|
||||
}
|
||||
if (on(player, ISSLOW) || on(player, ISDANCE)) {
|
||||
if (player.t_turn != TRUE) {
|
||||
ntimes--;
|
||||
turns++;
|
||||
an_after = TRUE;
|
||||
}
|
||||
player.t_turn ^= TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Let the daemons start up
|
||||
*/
|
||||
do_daemons(BEFORE);
|
||||
do_fuses(BEFORE);
|
||||
while (ntimes-- > 0)
|
||||
{
|
||||
/* One more tick of the clock. */
|
||||
if ((++turns % DAYLENGTH) == 0) {
|
||||
daytime ^= TRUE;
|
||||
if (levtype == OUTSIDE) {
|
||||
if (daytime) msg("The sun rises above the horizon");
|
||||
else msg("The sun sinks below the horizon");
|
||||
}
|
||||
light(&hero);
|
||||
}
|
||||
|
||||
look(after, FALSE);
|
||||
if (!running) door_stop = FALSE;
|
||||
lastscore = purse;
|
||||
wmove(cw, hero.y, hero.x);
|
||||
if (!((running || count) && jump)) {
|
||||
status(FALSE);
|
||||
wmove(cw, hero.y, hero.x);
|
||||
draw(cw); /* Draw screen */
|
||||
}
|
||||
take = 0;
|
||||
after = TRUE;
|
||||
/*
|
||||
* Read command or continue run
|
||||
*/
|
||||
if (!no_command)
|
||||
{
|
||||
if (running) {
|
||||
/* If in a corridor or maze, if we are at a turn with only one
|
||||
* way to go, turn that way.
|
||||
*/
|
||||
if ((winat(hero.y, hero.x) == PASSAGE || levtype == MAZELEV) &&
|
||||
off(player, ISHUH) && (off(player, ISBLIND))) {
|
||||
int y, x;
|
||||
if (getdelta(runch, &y, &x) == TRUE) {
|
||||
corr_move(y, x);
|
||||
}
|
||||
}
|
||||
ch = runch;
|
||||
}
|
||||
else if (count) ch = countch;
|
||||
else
|
||||
{
|
||||
ch = readchar();
|
||||
if (mpos != 0 && !running) /* Erase message if its there */
|
||||
msg("");
|
||||
}
|
||||
}
|
||||
else ch = '.';
|
||||
if (no_command)
|
||||
{
|
||||
if (--no_command == 0)
|
||||
msg("You can move again.");
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* check for prefixes
|
||||
*/
|
||||
if (isdigit(ch))
|
||||
{
|
||||
count = 0;
|
||||
newcount = TRUE;
|
||||
while (isdigit(ch))
|
||||
{
|
||||
count = count * 10 + (ch - '0');
|
||||
if (count > 255)
|
||||
count = 255;
|
||||
ch = readchar();
|
||||
}
|
||||
countch = ch;
|
||||
/*
|
||||
* turn off count for commands which don't make sense
|
||||
* to repeat
|
||||
*/
|
||||
switch (ch) {
|
||||
case 'h': case 'j': case 'k': case 'l':
|
||||
case 'y': case 'u': case 'b': case 'n':
|
||||
case 'H': case 'J': case 'K': case 'L':
|
||||
case 'Y': case 'U': case 'B': case 'N':
|
||||
case 'q': case 'r': case 's': case 'f':
|
||||
case 't': case 'C': case 'I': case '.':
|
||||
case 'z': case 'p':
|
||||
break;
|
||||
default:
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Save current direction */
|
||||
if (!running) /* If running, it is already saved */
|
||||
switch (ch) {
|
||||
case 'h': case 'j': case 'k': case 'l':
|
||||
case 'y': case 'u': case 'b': case 'n':
|
||||
case 'H': case 'J': case 'K': case 'L':
|
||||
case 'Y': case 'U': case 'B': case 'N':
|
||||
runch = tolower(ch);
|
||||
}
|
||||
|
||||
/* Perform the action */
|
||||
switch (ch) {
|
||||
case 'f':
|
||||
if (!on(player, ISBLIND))
|
||||
{
|
||||
door_stop = TRUE;
|
||||
firstmove = TRUE;
|
||||
}
|
||||
if (count && !newcount)
|
||||
ch = direction;
|
||||
else
|
||||
ch = readchar();
|
||||
switch (ch)
|
||||
{
|
||||
case 'h': case 'j': case 'k': case 'l':
|
||||
case 'y': case 'u': case 'b': case 'n':
|
||||
ch = toupper(ch);
|
||||
}
|
||||
direction = ch;
|
||||
}
|
||||
newcount = FALSE;
|
||||
/*
|
||||
* execute a command
|
||||
*/
|
||||
if (count && !running)
|
||||
count--;
|
||||
switch (ch)
|
||||
{
|
||||
case '!' : shell();
|
||||
when 'h' : do_move(0, -1);
|
||||
when 'j' : do_move(1, 0);
|
||||
when 'k' : do_move(-1, 0);
|
||||
when 'l' : do_move(0, 1);
|
||||
when 'y' : do_move(-1, -1);
|
||||
when 'u' : do_move(-1, 1);
|
||||
when 'b' : do_move(1, -1);
|
||||
when 'n' : do_move(1, 1);
|
||||
when 'H' : do_run('h');
|
||||
when 'J' : do_run('j');
|
||||
when 'K' : do_run('k');
|
||||
when 'L' : do_run('l');
|
||||
when 'Y' : do_run('y');
|
||||
when 'U' : do_run('u');
|
||||
when 'B' : do_run('b');
|
||||
when 'N' : do_run('n');
|
||||
when 't':
|
||||
if((item=get_item(pack,"throw", ALL)) != NULL && get_dir())
|
||||
missile(delta.y, delta.x, item, &player);
|
||||
else
|
||||
after = FALSE;
|
||||
when 'Q' : after = FALSE; quit(-1);
|
||||
when 'i' : after = FALSE; inventory(pack, ALL);
|
||||
when 'I' : after = FALSE; picky_inven();
|
||||
when 'd' : drop(NULL);
|
||||
when 'P' : grab(hero.y, hero.x);
|
||||
when 'q' : quaff(-1, NULL, TRUE);
|
||||
when 'r' : read_scroll(-1, NULL, TRUE);
|
||||
when 'e' : eat();
|
||||
when 'w' : wield();
|
||||
when 'W' : wear();
|
||||
when 'T' : take_off();
|
||||
when 'o' : option();
|
||||
when 'c' : call(FALSE);
|
||||
when 'm' : call(TRUE);
|
||||
when '>' : after = FALSE; d_level();
|
||||
when '<' : after = FALSE; u_level();
|
||||
when '?' : after = FALSE; help();
|
||||
when '/' : after = FALSE; identify();
|
||||
when CTRL('U') : use_mm(-1);
|
||||
when CTRL('T') :
|
||||
if (get_dir()) steal();
|
||||
else after = FALSE;
|
||||
when 'D' : dip_it();
|
||||
when 'G' : gsense();
|
||||
when '^' : set_trap(&player, hero.y, hero.x);
|
||||
when 's' : search(FALSE, FALSE);
|
||||
when 'z' : if (!do_zap(TRUE, NULL, FALSE))
|
||||
after=FALSE;
|
||||
when 'p' : pray();
|
||||
when 'C' : cast();
|
||||
when 'a' :
|
||||
if (get_dir())
|
||||
affect();
|
||||
else after = FALSE;
|
||||
when 'v' : after = FALSE;
|
||||
msg("Advanced Rogue Version %s.",
|
||||
release);
|
||||
when CTRL('L') : after = FALSE; clearok(curscr, TRUE);
|
||||
touchwin(cw); /* MMMMMMMMMM */
|
||||
when CTRL('R') : after = FALSE; msg(huh);
|
||||
when 'S' :
|
||||
after = FALSE;
|
||||
if (save_game())
|
||||
{
|
||||
wclear(cw);
|
||||
draw(cw);
|
||||
endwin();
|
||||
printf("\n");
|
||||
exit(0);
|
||||
}
|
||||
when '.' : ; /* Rest command */
|
||||
when ' ' : after = FALSE; /* Do Nothing */
|
||||
#ifdef WIZARD
|
||||
when CTRL('P') :
|
||||
after = FALSE;
|
||||
if (wizard)
|
||||
{
|
||||
wizard = FALSE;
|
||||
trader = 0;
|
||||
msg("Not wizard any more");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (waswizard || passwd())
|
||||
{
|
||||
msg("Welcome, oh mighty wizard.");
|
||||
wizard = waswizard = TRUE;
|
||||
}
|
||||
else
|
||||
msg("Sorry");
|
||||
}
|
||||
#endif
|
||||
when ESCAPE : /* Escape */
|
||||
door_stop = FALSE;
|
||||
count = 0;
|
||||
after = FALSE;
|
||||
when '#':
|
||||
if (levtype == POSTLEV) /* buy something */
|
||||
buy_it();
|
||||
after = FALSE;
|
||||
when '$':
|
||||
if (levtype == POSTLEV) /* price something */
|
||||
price_it();
|
||||
after = FALSE;
|
||||
when '%':
|
||||
if (levtype == POSTLEV) /* sell something */
|
||||
sell_it();
|
||||
after = FALSE;
|
||||
otherwise :
|
||||
after = FALSE;
|
||||
#ifdef WIZARD
|
||||
if (wizard) switch (ch)
|
||||
{
|
||||
case 'M' : create_obj(TRUE, 0, 0);
|
||||
when CTRL('W') : wanderer();
|
||||
when CTRL('I') : inventory(lvl_obj, ALL);
|
||||
when CTRL('Z') : whatis(NULL);
|
||||
when CTRL('D') : level++; new_level(NORMLEV);
|
||||
when CTRL('F') : overlay(stdscr,cw);
|
||||
when CTRL('X') : overlay(mw,cw);
|
||||
when CTRL('J') : teleport();
|
||||
when CTRL('E') : sprintf(outstring,"food left: %d\tfood level: %d",
|
||||
food_left, foodlev);
|
||||
msg(outstring);
|
||||
when CTRL('A') : activity();
|
||||
when CTRL('C') :
|
||||
{
|
||||
int tlev;
|
||||
prbuf[0] = '\0';
|
||||
msg("Which level? ");
|
||||
if(get_str(prbuf,cw) == NORM) {
|
||||
tlev = atoi(prbuf);
|
||||
if(tlev < 1) {
|
||||
mpos = 0;
|
||||
msg("Illegal level.");
|
||||
}
|
||||
else if (tlev > 199) {
|
||||
levtype = MAZELEV;
|
||||
level = tlev - 200 + 1;
|
||||
}
|
||||
else if (tlev > 99) {
|
||||
levtype = POSTLEV;
|
||||
level = tlev - 100 + 1;
|
||||
}
|
||||
else {
|
||||
levtype = NORMLEV;
|
||||
level = tlev;
|
||||
}
|
||||
new_level(levtype);
|
||||
}
|
||||
}
|
||||
when CTRL('N') :
|
||||
{
|
||||
if ((item=get_item(pack, "charge", STICK)) != NULL){
|
||||
(OBJPTR(item))->o_charges=10000;
|
||||
}
|
||||
}
|
||||
when CTRL('H') :
|
||||
{
|
||||
register int i;
|
||||
register struct object *obj;
|
||||
|
||||
for (i = 0; i < 9; i++)
|
||||
raise_level(TRUE);
|
||||
/*
|
||||
* Give the rogue a sword
|
||||
*/
|
||||
if(cur_weapon==NULL || cur_weapon->o_type!=RELIC) {
|
||||
item = spec_item(WEAPON, TWOSWORD, 5, 5);
|
||||
add_pack(item, TRUE, NULL);
|
||||
cur_weapon = OBJPTR(item);
|
||||
cur_weapon->o_flags |= (ISKNOW | ISPROT);
|
||||
}
|
||||
/*
|
||||
* And his suit of armor
|
||||
*/
|
||||
if (player.t_ctype == C_THIEF)
|
||||
item = spec_item(ARMOR, STUDDED_LEATHER, 10, 0);
|
||||
else
|
||||
item = spec_item(ARMOR, PLATE_ARMOR, 7, 0);
|
||||
obj = OBJPTR(item);
|
||||
obj->o_flags |= (ISKNOW | ISPROT);
|
||||
obj->o_weight = armors[PLATE_ARMOR].a_wght;
|
||||
cur_armor = obj;
|
||||
add_pack(item, TRUE, NULL);
|
||||
purse += 20000;
|
||||
}
|
||||
otherwise :
|
||||
msg("Illegal command '%s'.", unctrl(ch));
|
||||
count = 0;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
msg("Illegal command '%s'.", unctrl(ch));
|
||||
count = 0;
|
||||
after = FALSE;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* turn off flags if no longer needed
|
||||
*/
|
||||
if (!running)
|
||||
door_stop = FALSE;
|
||||
}
|
||||
/*
|
||||
* If he ran into something to take, let him pick it up.
|
||||
* unless its a trading post
|
||||
*/
|
||||
if (auto_pickup && take != 0 && levtype != POSTLEV)
|
||||
pick_up(take);
|
||||
if (!running)
|
||||
door_stop = FALSE;
|
||||
|
||||
/* If after is true, mark an_after as true so that if
|
||||
* we are hasted, the first "after" will be noted.
|
||||
* if after is FALSE then stay in this loop
|
||||
*/
|
||||
if (after) an_after = TRUE;
|
||||
else ntimes++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Kick off the rest if the daemons and fuses
|
||||
*/
|
||||
if (an_after)
|
||||
{
|
||||
/*
|
||||
* If player is infested, take off a hit point
|
||||
*/
|
||||
if (on(player, HASINFEST)) {
|
||||
if ((pstats.s_hpt -= infest_dam) <= 0) death(D_INFESTATION);
|
||||
}
|
||||
/*
|
||||
* if player has body rot then take off five hits
|
||||
*/
|
||||
if (on(player, DOROT)) {
|
||||
if ((pstats.s_hpt -= 5) <= 0) death(D_ROT);
|
||||
}
|
||||
do_daemons(AFTER);
|
||||
do_fuses(AFTER);
|
||||
if (!((running || count) && jump)) look(FALSE, FALSE);
|
||||
|
||||
|
||||
}
|
||||
t_free_list(monst_dead);
|
||||
}
|
||||
|
||||
/*
|
||||
* quit:
|
||||
* Have player make certain, then exit.
|
||||
*/
|
||||
|
||||
void
|
||||
quit(int sig)
|
||||
{
|
||||
NOOP(sig);
|
||||
|
||||
/*
|
||||
* Reset the signal in case we got here via an interrupt
|
||||
*/
|
||||
if (signal(SIGINT, &quit) != &quit)
|
||||
mpos = 0;
|
||||
msg("Really quit? ");
|
||||
draw(cw);
|
||||
if (readchar() == 'y')
|
||||
{
|
||||
clear();
|
||||
move(LINES-1, 0);
|
||||
draw(stdscr);
|
||||
score(pstats.s_exp + (long) purse, CHICKEN, 0);
|
||||
exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
signal(SIGINT, quit);
|
||||
wmove(cw, 0, 0);
|
||||
wclrtoeol(cw);
|
||||
status(FALSE);
|
||||
draw(cw);
|
||||
mpos = 0;
|
||||
count = 0;
|
||||
running = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* bugkill:
|
||||
* killed by a program bug instead of voluntarily.
|
||||
*/
|
||||
|
||||
void
|
||||
bugkill(sig)
|
||||
int sig;
|
||||
{
|
||||
signal(sig, quit); /* If we get it again, give up */
|
||||
death(D_SIGNAL); /* Killed by a bug */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* search:
|
||||
* Player gropes about him to find hidden things.
|
||||
*/
|
||||
|
||||
search(is_thief, door_chime)
|
||||
register bool is_thief, door_chime;
|
||||
{
|
||||
register int x, y;
|
||||
register char ch, /* The trap or door character */
|
||||
sch, /* Trap or door character (as seen on screen) */
|
||||
mch; /* Monster, if a monster is on the trap or door */
|
||||
register struct linked_list *item;
|
||||
register struct thing *mp; /* Status on surrounding monster */
|
||||
|
||||
/*
|
||||
* Look all around the hero, if there is something hidden there,
|
||||
* give him a chance to find it. If its found, display it.
|
||||
*/
|
||||
if (on(player, ISBLIND))
|
||||
return;
|
||||
for (x = hero.x - 1; x <= hero.x + 1; x++)
|
||||
for (y = hero.y - 1; y <= hero.y + 1; y++)
|
||||
{
|
||||
if (y==hero.y && x==hero.x)
|
||||
continue;
|
||||
|
||||
/* Mch and ch will be the same unless there is a monster here */
|
||||
mch = CCHAR( winat(y, x) );
|
||||
ch = CCHAR( mvwinch(stdscr, y, x) );
|
||||
sch = CCHAR( mvwinch(cw, y, x) ); /* What's on the screen */
|
||||
|
||||
if (door_chime == FALSE && isatrap(ch)) {
|
||||
register struct trap *tp;
|
||||
|
||||
/* Is there a monster on the trap? */
|
||||
if (mch != ch && (item = find_mons(y, x)) != NULL) {
|
||||
mp = THINGPTR(item);
|
||||
if (sch == mch) sch = mp->t_oldch;
|
||||
}
|
||||
else mp = NULL;
|
||||
|
||||
/*
|
||||
* is this one found already?
|
||||
*/
|
||||
if (isatrap(sch))
|
||||
continue; /* give him chance for other traps */
|
||||
tp = trap_at(y, x);
|
||||
/*
|
||||
* if the thief set it then don't display it.
|
||||
* if its not a thief he has 50/50 shot
|
||||
*/
|
||||
if((tp->tr_flags&ISTHIEFSET) || (!is_thief && rnd(100)>50))
|
||||
continue; /* give him chance for other traps */
|
||||
tp->tr_flags |= ISFOUND;
|
||||
|
||||
/* Let's update the screen */
|
||||
if (mp != NULL && CCHAR(mvwinch(cw, y, x)) == mch)
|
||||
mp->t_oldch = ch; /* Will change when monst moves */
|
||||
else mvwaddch(cw, y, x, ch);
|
||||
|
||||
count = 0;
|
||||
running = FALSE;
|
||||
msg(tr_name(tp->tr_type));
|
||||
}
|
||||
else if (ch == SECRETDOOR) {
|
||||
if (door_chime == TRUE || (!is_thief && rnd(100) < 20)) {
|
||||
/* Is there a monster on the door? */
|
||||
if (mch != ch && (item = find_mons(y, x)) != NULL) {
|
||||
mp = THINGPTR(item);
|
||||
|
||||
/* Screen will change when monster moves */
|
||||
if (sch == mch) mp->t_oldch = ch;
|
||||
}
|
||||
mvaddch(y, x, DOOR);
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* help:
|
||||
* Give single character help, or the whole mess if he wants it
|
||||
*/
|
||||
|
||||
help()
|
||||
{
|
||||
register struct h_list *strp = helpstr;
|
||||
#ifdef WIZARD
|
||||
struct h_list *wizp = wiz_help;
|
||||
#endif
|
||||
register char helpch;
|
||||
register int cnt;
|
||||
|
||||
msg("Character you want help for (* for all): ");
|
||||
helpch = readchar();
|
||||
mpos = 0;
|
||||
/*
|
||||
* If its not a *, print the right help string
|
||||
* or an error if he typed a funny character.
|
||||
*/
|
||||
if (helpch != '*') {
|
||||
wmove(cw, 0, 0);
|
||||
while (strp->h_ch) {
|
||||
if (strp->h_ch == helpch) {
|
||||
sprintf(outstring,"%s%s", unctrl(strp->h_ch), strp->h_desc);
|
||||
msg(outstring);
|
||||
return;
|
||||
}
|
||||
strp++;
|
||||
}
|
||||
#ifdef WIZARD
|
||||
if (wizard) {
|
||||
while (wizp->h_ch) {
|
||||
if (wizp->h_ch == helpch) {
|
||||
sprintf(outstring,"%s%s", unctrl(wizp->h_ch), wizp->h_desc);
|
||||
msg(outstring);
|
||||
return;
|
||||
}
|
||||
wizp++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
msg("Unknown character '%s'", unctrl(helpch));
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Here we print help for everything.
|
||||
* Then wait before we return to command mode
|
||||
*/
|
||||
wclear(hw);
|
||||
cnt = 0;
|
||||
while (strp->h_ch) {
|
||||
mvwaddstr(hw, cnt % 23, cnt > 22 ? 40 : 0, unctrl(strp->h_ch));
|
||||
waddstr(hw, strp->h_desc);
|
||||
strp++;
|
||||
if (++cnt >= 46 && strp->h_ch) {
|
||||
wmove(hw, LINES-1, 0);
|
||||
wprintw(hw, morestr);
|
||||
draw(hw);
|
||||
wait_for(hw,' ');
|
||||
wclear(hw);
|
||||
cnt = 0;
|
||||
}
|
||||
}
|
||||
#ifdef WIZARD
|
||||
if (wizard) {
|
||||
while (wizp->h_ch) {
|
||||
mvwaddstr(hw, cnt % 23, cnt > 22 ? 40 : 0, unctrl(wizp->h_ch));
|
||||
waddstr(hw, wizp->h_desc);
|
||||
wizp++;
|
||||
if (++cnt >= 46 && wizp->h_ch) {
|
||||
wmove(hw, LINES-1, 0);
|
||||
wprintw(hw, morestr);
|
||||
draw(hw);
|
||||
wait_for(hw,' ');
|
||||
wclear(hw);
|
||||
cnt = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
wmove(hw, LINES-1, 0);
|
||||
wprintw(hw, spacemsg);
|
||||
draw(hw);
|
||||
wait_for(hw,' ');
|
||||
wclear(hw);
|
||||
draw(hw);
|
||||
wmove(cw, 0, 0);
|
||||
wclrtoeol(cw);
|
||||
status(FALSE);
|
||||
touchwin(cw);
|
||||
}
|
||||
/*
|
||||
* identify:
|
||||
* Tell the player what a certain thing is.
|
||||
*/
|
||||
|
||||
identify()
|
||||
{
|
||||
register char ch;
|
||||
const char *str;
|
||||
|
||||
msg("What do you want identified? ");
|
||||
ch = readchar();
|
||||
mpos = 0;
|
||||
if (ch == ESCAPE)
|
||||
{
|
||||
msg("");
|
||||
return;
|
||||
}
|
||||
if (isalpha(ch))
|
||||
str = monsters[id_monst(ch)].m_name;
|
||||
else switch(ch)
|
||||
{
|
||||
case '|':
|
||||
case '-':
|
||||
str = (levtype == OUTSIDE) ? "boundary of sector"
|
||||
: "wall of a room";
|
||||
when GOLD: str = "gold";
|
||||
when STAIRS : str = (levtype == OUTSIDE) ? "entrance to a dungeon"
|
||||
: "passage leading down";
|
||||
when DOOR: str = "door";
|
||||
when FLOOR: str = (levtype == OUTSIDE) ? "meadow" : "room floor";
|
||||
when VPLAYER: str = "the hero of the game ---> you";
|
||||
when IPLAYER: str = "you (but invisible)";
|
||||
when PASSAGE: str = "passage";
|
||||
when POST: str = "trading post";
|
||||
when POOL: str = (levtype == OUTSIDE) ? "lake"
|
||||
: "a shimmering pool";
|
||||
when TRAPDOOR: str = "trapdoor";
|
||||
when ARROWTRAP: str = "arrow trap";
|
||||
when SLEEPTRAP: str = "sleeping gas trap";
|
||||
when BEARTRAP: str = "bear trap";
|
||||
when TELTRAP: str = "teleport trap";
|
||||
when DARTTRAP: str = "dart trap";
|
||||
when MAZETRAP: str = "entrance to a maze";
|
||||
when FOREST: str = "forest";
|
||||
when POTION: str = "potion";
|
||||
when SCROLL: str = "scroll";
|
||||
when FOOD: str = "food";
|
||||
when WEAPON: str = "weapon";
|
||||
when ' ' : str = "solid rock";
|
||||
when ARMOR: str = "armor";
|
||||
when MM: str = "miscellaneous magic";
|
||||
when RING: str = "ring";
|
||||
when STICK: str = "wand or staff";
|
||||
when SECRETDOOR:str = "secret door";
|
||||
when RELIC: str = "artifact";
|
||||
otherwise: str = "unknown character";
|
||||
}
|
||||
sprintf(outstring,"'%s' : %s", unctrl(ch), str);
|
||||
msg(outstring);
|
||||
}
|
||||
|
||||
/*
|
||||
* d_level:
|
||||
* He wants to go down a level
|
||||
*/
|
||||
|
||||
d_level()
|
||||
{
|
||||
bool no_phase=FALSE;
|
||||
|
||||
|
||||
/* If we are at a top-level trading post, we probably can't go down */
|
||||
if (levtype == POSTLEV && level == 0 && rnd(100) < 80) {
|
||||
msg("I see no way down.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (winat(hero.y, hero.x) != STAIRS) {
|
||||
if (off(player, CANINWALL) || /* Must use stairs if can't phase */
|
||||
(levtype == OUTSIDE && rnd(100) < 90)) {
|
||||
msg("I see no way down.");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Is there any dungeon left below? */
|
||||
if (level >= nfloors) {
|
||||
msg("There is only solid rock below.");
|
||||
return;
|
||||
}
|
||||
|
||||
extinguish(unphase); /* Using phase to go down gets rid of it */
|
||||
no_phase = TRUE;
|
||||
}
|
||||
|
||||
/* Is this the bottom? */
|
||||
if (level >= nfloors) {
|
||||
msg("The stairway only goes up.");
|
||||
return;
|
||||
}
|
||||
|
||||
level++;
|
||||
new_level(NORMLEV);
|
||||
if (no_phase) unphase();
|
||||
}
|
||||
|
||||
/*
|
||||
* u_level:
|
||||
* He wants to go up a level
|
||||
*/
|
||||
|
||||
u_level()
|
||||
{
|
||||
bool no_phase = FALSE;
|
||||
register struct linked_list *item;
|
||||
struct thing *tp;
|
||||
struct object *obj;
|
||||
|
||||
if (winat(hero.y, hero.x) != STAIRS) {
|
||||
if (off(player, CANINWALL)) { /* Must use stairs if can't phase */
|
||||
msg("I see no way up.");
|
||||
return;
|
||||
}
|
||||
|
||||
extinguish(unphase);
|
||||
no_phase = TRUE;
|
||||
}
|
||||
|
||||
if (level == 0) {
|
||||
msg("The stairway only goes down.");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* does he have the item he was quested to get?
|
||||
*/
|
||||
if (level == 1) {
|
||||
for (item = pack; item != NULL; item = next(item)) {
|
||||
obj = OBJPTR(item);
|
||||
if (obj->o_type == RELIC && obj->o_which == quest_item)
|
||||
total_winner();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* check to see if he trapped a UNIQUE, If he did then put it back
|
||||
* in the monster table for next time
|
||||
*/
|
||||
for (item = tlist; item != NULL; item = next(item)) {
|
||||
tp = THINGPTR(item);
|
||||
if (on(*tp, ISUNIQUE))
|
||||
monsters[tp->t_index].m_normal = TRUE;
|
||||
}
|
||||
t_free_list(tlist); /* Monsters that fell below are long gone! */
|
||||
|
||||
if (levtype != POSTLEV) level--;
|
||||
if (level > 0) new_level(NORMLEV);
|
||||
else {
|
||||
level = -1; /* Indicate that we are new to the outside */
|
||||
msg("You emerge into the %s", daytime ? "light" : "night");
|
||||
new_level(OUTSIDE); /* Leaving the dungeon */
|
||||
}
|
||||
|
||||
if (no_phase) unphase();
|
||||
}
|
||||
|
||||
/*
|
||||
* Let him escape for a while
|
||||
*/
|
||||
|
||||
shell()
|
||||
{
|
||||
/*
|
||||
* Set the terminal back to original mode
|
||||
*/
|
||||
wclear(hw);
|
||||
wmove(hw, LINES-1, 0);
|
||||
draw(hw);
|
||||
endwin();
|
||||
in_shell = TRUE;
|
||||
fflush(stdout);
|
||||
|
||||
md_shellescape();
|
||||
|
||||
printf(retstr);
|
||||
fflush(stdout);
|
||||
noecho();
|
||||
raw();
|
||||
keypad(cw,1);
|
||||
in_shell = FALSE;
|
||||
wait_for(hw,'\n');
|
||||
clearok(cw, TRUE);
|
||||
touchwin(cw);
|
||||
wmove(cw,0,0);
|
||||
draw(cw);
|
||||
}
|
||||
|
||||
/*
|
||||
* allow a user to call a potion, scroll, or ring something
|
||||
*/
|
||||
call(mark)
|
||||
bool mark;
|
||||
{
|
||||
register struct object *obj;
|
||||
register struct linked_list *item;
|
||||
register char **guess = NULL, *elsewise = NULL;
|
||||
register bool *know;
|
||||
|
||||
if (mark) item = get_item(pack, "mark", ALL);
|
||||
else item = get_item(pack, "call", CALLABLE);
|
||||
/*
|
||||
* Make certain that it is somethings that we want to wear
|
||||
*/
|
||||
if (item == NULL)
|
||||
return;
|
||||
obj = OBJPTR(item);
|
||||
switch (obj->o_type)
|
||||
{
|
||||
case RING:
|
||||
guess = r_guess;
|
||||
know = r_know;
|
||||
elsewise = (r_guess[obj->o_which] != NULL ?
|
||||
r_guess[obj->o_which] : r_stones[obj->o_which]);
|
||||
when POTION:
|
||||
guess = p_guess;
|
||||
know = p_know;
|
||||
elsewise = (p_guess[obj->o_which] != NULL ?
|
||||
p_guess[obj->o_which] : p_colors[obj->o_which]);
|
||||
when SCROLL:
|
||||
guess = s_guess;
|
||||
know = s_know;
|
||||
elsewise = (s_guess[obj->o_which] != NULL ?
|
||||
s_guess[obj->o_which] : s_names[obj->o_which]);
|
||||
when STICK:
|
||||
guess = ws_guess;
|
||||
know = ws_know;
|
||||
elsewise = (ws_guess[obj->o_which] != NULL ?
|
||||
ws_guess[obj->o_which] : ws_made[obj->o_which]);
|
||||
when MM:
|
||||
guess = m_guess;
|
||||
know = m_know;
|
||||
elsewise = (m_guess[obj->o_which] != NULL ?
|
||||
m_guess[obj->o_which] : "nothing");
|
||||
otherwise:
|
||||
if (!mark) {
|
||||
msg("You can't call that anything.");
|
||||
return;
|
||||
}
|
||||
else know = (bool *) 0;
|
||||
}
|
||||
if ((obj->o_flags & ISPOST) || (know && know[obj->o_which]) && !mark) {
|
||||
msg("That has already been identified.");
|
||||
return;
|
||||
}
|
||||
if (mark) {
|
||||
if (obj->o_mark[0]) {
|
||||
addmsg(terse ? "M" : "Was m");
|
||||
msg("arked \"%s\"", obj->o_mark);
|
||||
}
|
||||
msg(terse ? "Mark it: " : "What do you want to mark it? ");
|
||||
prbuf[0] = '\0';
|
||||
}
|
||||
else {
|
||||
addmsg(terse ? "C" : "Was c");
|
||||
msg("alled \"%s\"", elsewise);
|
||||
msg(terse ? "Call it: " : "What do you want to call it? ");
|
||||
if (guess[obj->o_which] != NULL)
|
||||
free(guess[obj->o_which]);
|
||||
strcpy(prbuf, elsewise);
|
||||
}
|
||||
if (get_str(prbuf, cw) == NORM) {
|
||||
if (mark) {
|
||||
strncpy(obj->o_mark, prbuf, MARKLEN-1);
|
||||
obj->o_mark[MARKLEN-1] = '\0';
|
||||
}
|
||||
else {
|
||||
guess[obj->o_which] = new((unsigned int) strlen(prbuf) + 1);
|
||||
strcpy(guess[obj->o_which], prbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
244
arogue5/daemon.c
Normal file
244
arogue5/daemon.c
Normal file
|
|
@ -0,0 +1,244 @@
|
|||
/*
|
||||
* Contains functions for dealing with things that happen in the future.
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "curses.h"
|
||||
#include "rogue.h"
|
||||
|
||||
#define EMPTY 0
|
||||
#define DAEMON -1
|
||||
|
||||
#define _X_ { EMPTY }
|
||||
|
||||
struct delayed_action d_list[MAXDAEMONS] = {
|
||||
_X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_
|
||||
};
|
||||
struct delayed_action f_list[MAXFUSES] = {
|
||||
_X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_,
|
||||
_X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_
|
||||
};
|
||||
int demoncnt = 0; /* number of active daemons */
|
||||
int fusecnt = 0;
|
||||
|
||||
|
||||
/*
|
||||
* d_slot:
|
||||
* Find an empty slot in the daemon list
|
||||
*/
|
||||
struct delayed_action *
|
||||
d_slot()
|
||||
{
|
||||
reg int i;
|
||||
reg struct delayed_action *dev;
|
||||
|
||||
for (i = 0, dev = d_list; i < MAXDAEMONS; i++, dev++)
|
||||
if (dev->d_type == EMPTY)
|
||||
return dev;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* f_slot:
|
||||
* Find an empty slot in the fuses list
|
||||
*/
|
||||
struct delayed_action *
|
||||
f_slot()
|
||||
{
|
||||
reg int i;
|
||||
reg struct delayed_action *dev;
|
||||
|
||||
for (i = 0, dev = f_list; i < MAXFUSES; i++, dev++)
|
||||
if (dev->d_type == EMPTY)
|
||||
return dev;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* find_slot:
|
||||
* Find a particular slot in the table
|
||||
*/
|
||||
struct delayed_action *
|
||||
find_slot(func)
|
||||
reg int (*func)();
|
||||
{
|
||||
reg int i;
|
||||
reg struct delayed_action *dev;
|
||||
|
||||
for (i = 0, dev = f_list; i < MAXFUSES; i++, dev++)
|
||||
if (dev->d_type != EMPTY && func == dev->d_func)
|
||||
return dev;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* daemon:
|
||||
* Start a daemon, takes a function.
|
||||
*/
|
||||
daemon(func, arg, type)
|
||||
reg int arg, type, (*func)();
|
||||
{
|
||||
reg struct delayed_action *dev;
|
||||
|
||||
dev = d_slot();
|
||||
if (dev != NULL) {
|
||||
dev->d_type = type;
|
||||
dev->d_func = func;
|
||||
dev->d_arg = arg;
|
||||
dev->d_time = DAEMON;
|
||||
demoncnt += 1; /* update count */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* kill_daemon:
|
||||
* Remove a daemon from the list
|
||||
*/
|
||||
kill_daemon(func)
|
||||
reg int (*func)();
|
||||
{
|
||||
reg struct delayed_action *dev;
|
||||
reg int i;
|
||||
|
||||
for (i = 0, dev = d_list; i < MAXDAEMONS; i++, dev++) {
|
||||
if (dev->d_type != EMPTY && func == dev->d_func)
|
||||
break;
|
||||
}
|
||||
if (i >= MAXDAEMONS) return; /* if not found, forget it */
|
||||
/*
|
||||
* Take it out of the list
|
||||
*/
|
||||
dev->d_type = EMPTY;
|
||||
dev->d_arg = 0;
|
||||
dev->d_func = NULL;
|
||||
dev->d_time = 0;
|
||||
demoncnt -= 1; /* update count */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* do_daemons:
|
||||
* Run all the daemons that are active with the current flag,
|
||||
* passing the argument to the function.
|
||||
*/
|
||||
do_daemons(flag)
|
||||
reg int flag;
|
||||
{
|
||||
reg struct delayed_action *dev;
|
||||
|
||||
/*
|
||||
* Loop through the devil list
|
||||
*/
|
||||
for (dev = d_list; dev <= &d_list[MAXDAEMONS-1]; dev++)
|
||||
/*
|
||||
* Executing each one, giving it the proper arguments
|
||||
*/
|
||||
if (dev->d_func != NULL && dev->d_type == flag && dev->d_time == DAEMON)
|
||||
(*dev->d_func)(dev->d_arg);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fuse:
|
||||
* Start a fuse to go off in a certain number of turns
|
||||
*/
|
||||
fuse(func, arg, time, type)
|
||||
reg int (*func)(), arg, time, type;
|
||||
{
|
||||
reg struct delayed_action *wire;
|
||||
|
||||
wire = f_slot();
|
||||
if (wire != NULL) {
|
||||
wire->d_type = type;
|
||||
wire->d_func = func;
|
||||
wire->d_arg = arg;
|
||||
wire->d_time = time;
|
||||
fusecnt += 1; /* update count */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* lengthen:
|
||||
* Increase the time until a fuse goes off
|
||||
*/
|
||||
lengthen(func, xtime)
|
||||
reg int (*func)(), xtime;
|
||||
{
|
||||
reg struct delayed_action *wire;
|
||||
|
||||
if ((wire = find_slot(func)) == NULL)
|
||||
return;
|
||||
wire->d_time += xtime;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* extinguish:
|
||||
* Put out a fuse
|
||||
*/
|
||||
extinguish(func)
|
||||
reg int (*func)();
|
||||
{
|
||||
reg struct delayed_action *wire;
|
||||
|
||||
if ((wire = find_slot(func)) == NULL)
|
||||
return;
|
||||
wire->d_type = EMPTY;
|
||||
wire->d_func = NULL;
|
||||
wire->d_arg = 0;
|
||||
wire->d_time = 0;
|
||||
fusecnt -= 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* do_fuses:
|
||||
* Decrement counters and start needed fuses
|
||||
*/
|
||||
do_fuses(flag)
|
||||
reg int flag;
|
||||
{
|
||||
reg struct delayed_action *wire;
|
||||
|
||||
/*
|
||||
* Step though the list
|
||||
*/
|
||||
for (wire = f_list; wire <= &f_list[MAXFUSES-1]; wire++) {
|
||||
/*
|
||||
* Decrementing counters and starting things we want. We also need
|
||||
* to remove the fuse from the list once it has gone off.
|
||||
*/
|
||||
if(flag == wire->d_type && wire->d_time > 0 &&
|
||||
--wire->d_time == 0) {
|
||||
wire->d_type = EMPTY;
|
||||
if (wire->d_func != NULL)
|
||||
(*wire->d_func)(wire->d_arg);
|
||||
fusecnt -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* activity:
|
||||
* Show wizard number of demaons and memory blocks used
|
||||
*/
|
||||
activity()
|
||||
{
|
||||
sprintf(outstring,"Daemons = %d : Fuses = %d : Memory Items = %d : Memory Used = %d",
|
||||
demoncnt,fusecnt,total,md_memused());
|
||||
msg(outstring);
|
||||
}
|
||||
487
arogue5/daemons.c
Normal file
487
arogue5/daemons.c
Normal file
|
|
@ -0,0 +1,487 @@
|
|||
/*
|
||||
* All the daemon and fuse functions are in here
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "curses.h"
|
||||
#include "rogue.h"
|
||||
|
||||
int between = 0;
|
||||
|
||||
/*
|
||||
* doctor:
|
||||
* A healing daemon that restors hit points after rest
|
||||
*/
|
||||
|
||||
doctor(tp)
|
||||
register struct thing *tp;
|
||||
{
|
||||
register int ohp;
|
||||
register int limit, new_points;
|
||||
register struct stats *curp; /* current stats pointer */
|
||||
register struct stats *maxp; /* max stats pointer */
|
||||
|
||||
curp = &(tp->t_stats);
|
||||
maxp = &(tp->maxstats);
|
||||
if (curp->s_hpt == maxp->s_hpt) {
|
||||
tp->t_quiet = 0;
|
||||
return;
|
||||
}
|
||||
tp->t_quiet++;
|
||||
switch (tp->t_ctype) {
|
||||
case C_MAGICIAN:
|
||||
limit = 8 - curp->s_lvl;
|
||||
new_points = curp->s_lvl - 3;
|
||||
when C_THIEF:
|
||||
limit = 8 - curp->s_lvl;
|
||||
new_points = curp->s_lvl - 2;
|
||||
when C_CLERIC:
|
||||
limit = 8 - curp->s_lvl;
|
||||
new_points = curp->s_lvl - 3;
|
||||
when C_FIGHTER:
|
||||
limit = 16 - curp->s_lvl*2;
|
||||
new_points = curp->s_lvl - 5;
|
||||
when C_MONSTER:
|
||||
limit = 16 - curp->s_lvl;
|
||||
new_points = curp->s_lvl - 6;
|
||||
otherwise:
|
||||
debug("what a strange character you are!");
|
||||
return;
|
||||
}
|
||||
ohp = curp->s_hpt;
|
||||
if (off(*tp, HASDISEASE) && off(*tp, DOROT)) {
|
||||
if (curp->s_lvl < 8) {
|
||||
if (tp->t_quiet > limit) {
|
||||
curp->s_hpt++;
|
||||
tp->t_quiet = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (tp->t_quiet >= 3) {
|
||||
curp->s_hpt += rnd(new_points)+1;
|
||||
tp->t_quiet = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tp == &player) {
|
||||
if (ISRING(LEFT_1, R_REGEN)) curp->s_hpt++;
|
||||
if (ISRING(LEFT_2, R_REGEN)) curp->s_hpt++;
|
||||
if (ISRING(LEFT_3, R_REGEN)) curp->s_hpt++;
|
||||
if (ISRING(LEFT_4, R_REGEN)) curp->s_hpt++;
|
||||
if (ISRING(RIGHT_1, R_REGEN)) curp->s_hpt++;
|
||||
if (ISRING(RIGHT_2, R_REGEN)) curp->s_hpt++;
|
||||
if (ISRING(RIGHT_3, R_REGEN)) curp->s_hpt++;
|
||||
if (ISRING(RIGHT_4, R_REGEN)) curp->s_hpt++;
|
||||
}
|
||||
if (on(*tp, ISREGEN))
|
||||
curp->s_hpt += curp->s_lvl/10 + 1;
|
||||
if (ohp != curp->s_hpt) {
|
||||
if (curp->s_hpt >= maxp->s_hpt) {
|
||||
curp->s_hpt = maxp->s_hpt;
|
||||
if (off(*tp, WASTURNED) && on(*tp, ISFLEE) && tp != &player) {
|
||||
turn_off(*tp, ISFLEE);
|
||||
tp->t_oldpos = tp->t_pos; /* Start our trek over */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Swander:
|
||||
* Called when it is time to start rolling for wandering monsters
|
||||
*/
|
||||
|
||||
swander()
|
||||
{
|
||||
daemon(rollwand, 0, BEFORE);
|
||||
}
|
||||
|
||||
/*
|
||||
* rollwand:
|
||||
* Called to roll to see if a wandering monster starts up
|
||||
*/
|
||||
|
||||
rollwand()
|
||||
{
|
||||
if (++between >= 4)
|
||||
{
|
||||
/* Theives may not awaken a monster */
|
||||
if ((roll(1, 6) == 4) &&
|
||||
((player.t_ctype != C_THIEF) || (rnd(30) >= dex_compute()))) {
|
||||
if (levtype != POSTLEV)
|
||||
wanderer();
|
||||
kill_daemon(rollwand);
|
||||
fuse(swander, 0, WANDERTIME, BEFORE);
|
||||
}
|
||||
between = 0;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* this function is a daemon called each turn when the character is a thief
|
||||
*/
|
||||
trap_look()
|
||||
{
|
||||
if (rnd(100) < (2*dex_compute() + 5*pstats.s_lvl))
|
||||
search(TRUE, FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* unconfuse:
|
||||
* Release the poor player from his confusion
|
||||
*/
|
||||
|
||||
unconfuse()
|
||||
{
|
||||
turn_off(player, ISHUH);
|
||||
msg("You feel less confused now");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* unsee:
|
||||
* He lost his see invisible power
|
||||
*/
|
||||
|
||||
unsee()
|
||||
{
|
||||
if (!ISWEARING(R_SEEINVIS)) {
|
||||
turn_off(player, CANSEE);
|
||||
msg("The tingling feeling leaves your eyes");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* unstink:
|
||||
* Remove to-hit handicap from player
|
||||
*/
|
||||
|
||||
unstink()
|
||||
{
|
||||
turn_off(player, HASSTINK);
|
||||
}
|
||||
|
||||
/*
|
||||
* unclrhead:
|
||||
* Player is no longer immune to confusion
|
||||
*/
|
||||
|
||||
unclrhead()
|
||||
{
|
||||
turn_off(player, ISCLEAR);
|
||||
msg("The blue aura about your head fades away.");
|
||||
}
|
||||
|
||||
/*
|
||||
* unphase:
|
||||
* Player can no longer walk through walls
|
||||
*/
|
||||
|
||||
unphase()
|
||||
{
|
||||
turn_off(player, CANINWALL);
|
||||
msg("Your dizzy feeling leaves you.");
|
||||
if (!step_ok(hero.y, hero.x, NOMONST, &player)) death(D_PETRIFY);
|
||||
}
|
||||
|
||||
/*
|
||||
* land:
|
||||
* Player can no longer fly
|
||||
*/
|
||||
|
||||
land()
|
||||
{
|
||||
turn_off(player, ISFLY);
|
||||
msg("You regain your normal weight");
|
||||
running = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* sight:
|
||||
* He gets his sight back
|
||||
*/
|
||||
|
||||
sight()
|
||||
{
|
||||
if (on(player, ISBLIND))
|
||||
{
|
||||
extinguish(sight);
|
||||
turn_off(player, ISBLIND);
|
||||
light(&hero);
|
||||
msg("The veil of darkness lifts");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* res_strength:
|
||||
* Restore player's strength
|
||||
*/
|
||||
|
||||
res_strength()
|
||||
{
|
||||
|
||||
/* If lost_str is non-zero, restore that amount of strength,
|
||||
* else all of it
|
||||
*/
|
||||
if (lost_str) {
|
||||
chg_str(lost_str);
|
||||
lost_str = 0;
|
||||
}
|
||||
|
||||
/* Otherwise, put player at the maximum strength */
|
||||
else {
|
||||
pstats.s_str = max_stats.s_str + ring_value(R_ADDSTR);
|
||||
}
|
||||
|
||||
updpack(TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* nohaste:
|
||||
* End the hasting
|
||||
*/
|
||||
|
||||
nohaste()
|
||||
{
|
||||
turn_off(player, ISHASTE);
|
||||
msg("You feel yourself slowing down.");
|
||||
}
|
||||
|
||||
/*
|
||||
* noslow:
|
||||
* End the slowing
|
||||
*/
|
||||
|
||||
noslow()
|
||||
{
|
||||
turn_off(player, ISSLOW);
|
||||
msg("You feel yourself speeding up.");
|
||||
}
|
||||
|
||||
/*
|
||||
* suffocate:
|
||||
* If this gets called, the player has suffocated
|
||||
*/
|
||||
|
||||
suffocate()
|
||||
{
|
||||
death(D_SUFFOCATION);
|
||||
}
|
||||
|
||||
/*
|
||||
* digest the hero's food
|
||||
*/
|
||||
stomach()
|
||||
{
|
||||
register int oldfood, old_hunger, food_use, i;
|
||||
|
||||
old_hunger = hungry_state;
|
||||
if (food_left <= 0)
|
||||
{
|
||||
/*
|
||||
* the hero is fainting
|
||||
*/
|
||||
if (no_command || rnd(100) > 20)
|
||||
return;
|
||||
no_command = rnd(8)+4;
|
||||
if (!terse)
|
||||
addmsg("You feel too weak from lack of food. ");
|
||||
msg("You faint");
|
||||
running = FALSE;
|
||||
count = 0;
|
||||
hungry_state = F_FAINT;
|
||||
}
|
||||
else
|
||||
{
|
||||
oldfood = food_left;
|
||||
food_use = 0;
|
||||
for (i=0; i<MAXRELIC; i++) { /* each relic eats an additional food */
|
||||
if (cur_relic[i])
|
||||
food_use++;
|
||||
}
|
||||
food_use += (ring_eat(LEFT_1) + ring_eat(LEFT_2) +
|
||||
ring_eat(LEFT_3) + ring_eat(LEFT_4) +
|
||||
ring_eat(RIGHT_1) + ring_eat(RIGHT_2) +
|
||||
ring_eat(RIGHT_3) + ring_eat(RIGHT_4) +
|
||||
foodlev);
|
||||
if (food_use < 1)
|
||||
food_use = 1;
|
||||
food_left -= food_use;
|
||||
if (food_left < MORETIME && oldfood >= MORETIME) {
|
||||
msg("You are starting to feel weak");
|
||||
running = FALSE;
|
||||
hungry_state = F_WEAK;
|
||||
}
|
||||
else if (food_left < 2 * MORETIME && oldfood >= 2 * MORETIME)
|
||||
{
|
||||
msg(terse ? "Getting hungry" : "You are starting to get hungry");
|
||||
running = FALSE;
|
||||
hungry_state = F_HUNGRY;
|
||||
}
|
||||
|
||||
}
|
||||
if (old_hunger != hungry_state)
|
||||
updpack(TRUE);
|
||||
wghtchk();
|
||||
}
|
||||
/*
|
||||
* daemon for curing the diseased
|
||||
*/
|
||||
cure_disease()
|
||||
{
|
||||
turn_off(player, HASDISEASE);
|
||||
if (off (player, HASINFEST))
|
||||
msg(terse ? "You feel yourself improving"
|
||||
: "You begin to feel yourself improving again");
|
||||
}
|
||||
|
||||
/*
|
||||
* daemon for adding back dexterity
|
||||
*/
|
||||
un_itch()
|
||||
{
|
||||
if (--lost_dext < 1) {
|
||||
lost_dext = 0;
|
||||
turn_off(player, HASITCH);
|
||||
}
|
||||
res_dexterity(1);
|
||||
}
|
||||
/*
|
||||
* appear:
|
||||
* Become visible again
|
||||
*/
|
||||
appear()
|
||||
{
|
||||
turn_off(player, ISINVIS);
|
||||
PLAYER = VPLAYER;
|
||||
msg("The tingling feeling leaves your body");
|
||||
light(&hero);
|
||||
}
|
||||
/*
|
||||
* dust_appear:
|
||||
* dust of disappearance wears off
|
||||
*/
|
||||
dust_appear()
|
||||
{
|
||||
turn_off(player, ISINVIS);
|
||||
PLAYER = VPLAYER;
|
||||
msg("You become visible again");
|
||||
light(&hero);
|
||||
}
|
||||
/*
|
||||
* unchoke:
|
||||
* the effects of "dust of choking and sneezing" wear off
|
||||
*/
|
||||
unchoke()
|
||||
{
|
||||
if (!find_slot(unconfuse))
|
||||
turn_off(player, ISHUH);
|
||||
if (!find_slot(sight))
|
||||
turn_off(player, ISBLIND);
|
||||
light(&hero);
|
||||
msg("Your throat and eyes return to normal");
|
||||
}
|
||||
/*
|
||||
* make some potion for the guy in the Alchemy jug
|
||||
*/
|
||||
alchemy(obj)
|
||||
register struct object *obj;
|
||||
{
|
||||
register struct object *tobj = NULL;
|
||||
register struct linked_list *item;
|
||||
|
||||
/*
|
||||
* verify that the object pointer we have still points to an alchemy
|
||||
* jug (hopefully the right one!) because the hero could have thrown
|
||||
* it away
|
||||
*/
|
||||
for (item = pack; item != NULL; item = next(item)) {
|
||||
tobj = OBJPTR(item);
|
||||
if (tobj == obj &&
|
||||
tobj->o_type == MM &&
|
||||
tobj->o_which== MM_JUG &&
|
||||
tobj->o_ac == JUG_EMPTY )
|
||||
break;
|
||||
}
|
||||
if (item == NULL) { /* not in the pack, check the level */
|
||||
for (item = lvl_obj; item != NULL; item = next(item)) {
|
||||
tobj = OBJPTR(item);
|
||||
if (tobj == obj &&
|
||||
tobj->o_type == MM &&
|
||||
tobj->o_which== MM_JUG &&
|
||||
tobj->o_ac == JUG_EMPTY )
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (item == NULL) /* can't find it.....too bad */
|
||||
return;
|
||||
|
||||
switch(rnd(9)) {
|
||||
case 0: tobj->o_ac = P_PHASE;
|
||||
when 1: tobj->o_ac = P_CLEAR;
|
||||
when 2: tobj->o_ac = P_SEEINVIS;
|
||||
when 3: tobj->o_ac = P_HEALING;
|
||||
when 4: tobj->o_ac = P_MFIND;
|
||||
when 5: tobj->o_ac = P_TFIND;
|
||||
when 6: tobj->o_ac = P_HASTE;
|
||||
when 7: tobj->o_ac = P_RESTORE;
|
||||
when 8: tobj->o_ac = P_FLY;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* otto's irresistable dance wears off
|
||||
*/
|
||||
|
||||
undance()
|
||||
{
|
||||
turn_off(player, ISDANCE);
|
||||
msg ("Your feet take a break.....whew!");
|
||||
}
|
||||
|
||||
/*
|
||||
* if he has our favorite necklace of strangulation then take damage every turn
|
||||
*/
|
||||
strangle()
|
||||
{
|
||||
if ((pstats.s_hpt -= 6) <= 0) death(D_STRANGLE);
|
||||
}
|
||||
/*
|
||||
* if he has on the gauntlets of fumbling he might drop his weapon each turn
|
||||
*/
|
||||
fumble()
|
||||
{
|
||||
register struct linked_list *item;
|
||||
|
||||
if(cur_weapon!=NULL && cur_weapon->o_type!=RELIC && rnd(100)<3) {
|
||||
for (item = pack; item != NULL; item = next(item)) {
|
||||
if (OBJPTR(item) == cur_weapon)
|
||||
break;
|
||||
}
|
||||
if (item != NULL) {
|
||||
drop(item);
|
||||
running = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* this is called each turn the hero has the ring of searching on
|
||||
*/
|
||||
ring_search()
|
||||
{
|
||||
search(FALSE, FALSE);
|
||||
}
|
||||
/*
|
||||
* this is called each turn the hero has the ring of teleportation on
|
||||
*/
|
||||
ring_teleport()
|
||||
{
|
||||
if (rnd(100) < 2) teleport();
|
||||
}
|
||||
175
arogue5/encumb.c
Normal file
175
arogue5/encumb.c
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* Stuff to do with encumberence
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Super-Rogue"
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "curses.h"
|
||||
#include "rogue.h"
|
||||
|
||||
/*
|
||||
* updpack:
|
||||
* Update his pack weight and adjust fooduse accordingly
|
||||
*/
|
||||
updpack(getmax)
|
||||
int getmax;
|
||||
{
|
||||
|
||||
reg int topcarry, curcarry;
|
||||
|
||||
if (getmax)
|
||||
pstats.s_carry = totalenc(); /* get total encumb */
|
||||
curcarry = packweight(); /* get pack weight */
|
||||
topcarry = pstats.s_carry / 5; /* 20% of total carry */
|
||||
if(curcarry > 4 * topcarry) {
|
||||
if(rnd(100) < 80)
|
||||
foodlev = 3; /* > 80% of pack */
|
||||
} else if(curcarry > 3 * topcarry) {
|
||||
if(rnd(100) < 60)
|
||||
foodlev = 2; /* > 60% of pack */
|
||||
} else
|
||||
foodlev = 1; /* <= 60% of pack */
|
||||
pstats.s_pack = curcarry; /* update pack weight */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* packweight:
|
||||
* Get the total weight of the hero's pack
|
||||
*/
|
||||
packweight()
|
||||
{
|
||||
reg struct object *obj;
|
||||
reg struct linked_list *pc;
|
||||
reg int weight;
|
||||
|
||||
weight = 0;
|
||||
for(pc = pack ; pc != NULL ; pc = next(pc)) {
|
||||
obj = OBJPTR(pc);
|
||||
weight += itemweight(obj);
|
||||
}
|
||||
if(weight < 0) /* in case of amulet */
|
||||
weight = 0;
|
||||
if(ISWEARING(R_HEAVY))
|
||||
weight += weight / 4;
|
||||
return(weight);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* itemweight:
|
||||
* Get the weight of an object
|
||||
*/
|
||||
itemweight(wh)
|
||||
reg struct object *wh;
|
||||
{
|
||||
reg int weight;
|
||||
reg int ac;
|
||||
|
||||
weight = wh->o_weight; /* get base weight */
|
||||
switch(wh->o_type) {
|
||||
case ARMOR:
|
||||
/*
|
||||
* subtract 10% for each enchantment
|
||||
* this will add weight for negative items
|
||||
*/
|
||||
ac = armors[wh->o_which].a_class - wh->o_ac;
|
||||
weight = ((weight*10) - (weight*ac)) / 10;
|
||||
if (weight < 0) weight = 0;
|
||||
when WEAPON:
|
||||
if ((wh->o_hplus + wh->o_dplus) > 0)
|
||||
weight /= 2;
|
||||
}
|
||||
if(wh->o_flags & ISCURSED)
|
||||
weight += weight / 5; /* 20% more for cursed */
|
||||
weight *= wh->o_count;
|
||||
return(weight);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* playenc:
|
||||
* Get hero's carrying ability above norm
|
||||
*/
|
||||
playenc()
|
||||
{
|
||||
return ((str_compute()-8)*50);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* totalenc:
|
||||
* Get total weight that the hero can carry
|
||||
*/
|
||||
totalenc()
|
||||
{
|
||||
reg int wtotal;
|
||||
|
||||
wtotal = NORMENCB + playenc();
|
||||
switch(hungry_state) {
|
||||
case F_OKAY:
|
||||
case F_HUNGRY: ; /* no change */
|
||||
when F_WEAK: wtotal -= wtotal / 10; /* 10% off weak */
|
||||
when F_FAINT: wtotal /= 2; /* 50% off faint */
|
||||
}
|
||||
return(wtotal);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* whgtchk:
|
||||
* See if the hero can carry his pack
|
||||
*/
|
||||
|
||||
wghtchk()
|
||||
{
|
||||
reg int dropchk, err = TRUE;
|
||||
reg char ch;
|
||||
int wghtchk();
|
||||
|
||||
inwhgt = TRUE;
|
||||
if (pstats.s_pack > pstats.s_carry) {
|
||||
ch = CCHAR( mvwinch(stdscr, hero.y, hero.x) );
|
||||
if((ch != FLOOR && ch != PASSAGE)) {
|
||||
extinguish(wghtchk);
|
||||
fuse(wghtchk,TRUE,1,AFTER);
|
||||
inwhgt = FALSE;
|
||||
return;
|
||||
}
|
||||
extinguish(wghtchk);
|
||||
msg("Your pack is too heavy for you");
|
||||
do {
|
||||
dropchk = drop(NULL);
|
||||
if(dropchk == FALSE) {
|
||||
mpos = 0;
|
||||
msg("You must drop something");
|
||||
}
|
||||
if(dropchk == TRUE)
|
||||
err = FALSE;
|
||||
} while(err);
|
||||
}
|
||||
inwhgt = FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* hitweight:
|
||||
* Gets the fighting ability according to current weight
|
||||
* This returns a +1 hit for light pack weight
|
||||
* 0 hit for medium pack weight
|
||||
* -1 hit for heavy pack weight
|
||||
*/
|
||||
|
||||
hitweight()
|
||||
{
|
||||
return(2 - foodlev);
|
||||
}
|
||||
1579
arogue5/fight.c
Normal file
1579
arogue5/fight.c
Normal file
File diff suppressed because it is too large
Load diff
497
arogue5/init.c
Normal file
497
arogue5/init.c
Normal file
|
|
@ -0,0 +1,497 @@
|
|||
/*
|
||||
* global variable initializaton
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "curses.h"
|
||||
#include <ctype.h>
|
||||
#include "rogue.h"
|
||||
#include "mach_dep.h"
|
||||
|
||||
|
||||
char *rainbow[NCOLORS] = {
|
||||
|
||||
"amber", "aquamarine", "beige",
|
||||
"black", "blue", "brown",
|
||||
"clear", "crimson", "ecru",
|
||||
"gold", "green", "grey",
|
||||
"indigo", "khaki", "lavender",
|
||||
"magenta", "orange", "pink",
|
||||
"plaid", "purple", "red",
|
||||
"silver", "saffron", "scarlet",
|
||||
"tan", "tangerine", "topaz",
|
||||
"turquoise", "vermilion", "violet",
|
||||
"white", "yellow",
|
||||
};
|
||||
|
||||
char *sylls[NSYLLS] = {
|
||||
"a", "ab", "ag", "aks", "ala", "an", "ankh","app", "arg", "arze",
|
||||
"ash", "ban", "bar", "bat", "bek", "bie", "bin", "bit", "bjor",
|
||||
"blu", "bot", "bu", "byt", "comp","con", "cos", "cre", "dalf",
|
||||
"dan", "den", "do", "e", "eep", "el", "eng", "er", "ere", "erk",
|
||||
"esh", "evs", "fa", "fid", "for", "fri", "fu", "gan", "gar",
|
||||
"glen","gop", "gre", "ha", "he", "hyd", "i", "ing", "ion", "ip",
|
||||
"ish", "it", "ite", "iv", "jo", "kho", "kli", "klis","la", "lech",
|
||||
"man", "mar", "me", "mi", "mic", "mik", "mon", "mung","mur",
|
||||
"nej", "nelg","nep", "ner", "nes", "nes", "nih", "nin", "o", "od",
|
||||
"ood", "org", "orn", "ox", "oxy", "pay", "pet", "ple", "plu", "po",
|
||||
"pot", "prok","re", "rea", "rhov","ri", "ro", "rog", "rok", "rol",
|
||||
"sa", "san", "sat", "see", "sef", "seh", "shu", "ski", "sna",
|
||||
"sne", "snik","sno", "so", "sol", "sri", "sta", "sun", "ta",
|
||||
"tab", "tem", "ther","ti", "tox", "trol","tue", "turs","u",
|
||||
"ulk", "um", "un", "uni", "ur", "val", "viv", "vly", "vom", "wah",
|
||||
"wed", "werg","wex", "whon","wun", "xo", "y", "yot", "yu",
|
||||
"zant","zap", "zeb", "zim", "zok", "zon", "zum",
|
||||
};
|
||||
|
||||
char *stones[NSTONES] = {
|
||||
"agate", "alexandrite", "amethyst",
|
||||
"azurite", "bloodstone", "cairngorm",
|
||||
"carnelian", "chalcedony", "chrysoberyl",
|
||||
"chrysolite", "chrysoprase", "citrine",
|
||||
"coral", "diamond", "emerald",
|
||||
"garnet", "heliotrope", "hematite",
|
||||
"hyacinth", "jacinth", "jade",
|
||||
"jargoon", "jasper", "kryptonite",
|
||||
"lapus lazuli", "malachite", "mocca stone",
|
||||
"moonstone", "obsidian", "olivine",
|
||||
"onyx", "opal", "pearl",
|
||||
"peridot", "quartz", "rhodochrosite",
|
||||
"rhodolite", "ruby", "sapphire",
|
||||
"sardonyx", "serpintine", "spinel",
|
||||
"tiger eye", "topaz", "tourmaline",
|
||||
"turquoise", "zircon",
|
||||
};
|
||||
|
||||
char *wood[NWOOD] = {
|
||||
"avocado wood", "balsa", "banyan", "birch",
|
||||
"cedar", "cherry", "cinnibar", "dogwood",
|
||||
"driftwood", "ebony", "eucalyptus", "hemlock",
|
||||
"ironwood", "mahogany", "manzanita", "maple",
|
||||
"oak", "pine", "redwood", "rosewood",
|
||||
"teak", "walnut", "zebra wood", "persimmon wood",
|
||||
};
|
||||
|
||||
char *metal[NMETAL] = {
|
||||
"aluminium", "bone", "brass", "bronze",
|
||||
"copper", "chromium", "iron", "lead",
|
||||
"magnesium", "pewter", "platinum", "silver",
|
||||
"steel", "tin", "titanium", "zinc",
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* make sure all the percentages specified in the tables add up to the
|
||||
* right amounts
|
||||
*/
|
||||
badcheck(name, magic, bound)
|
||||
char *name;
|
||||
register struct magic_item *magic;
|
||||
register int bound;
|
||||
{
|
||||
register struct magic_item *end;
|
||||
|
||||
if (magic[bound - 1].mi_prob == 1000)
|
||||
return;
|
||||
printf("\nBad percentages for %s:\n", name);
|
||||
for (end = &magic[bound] ; magic < end ; magic++)
|
||||
printf("%4d%% %s\n", magic->mi_prob, magic->mi_name);
|
||||
printf(retstr);
|
||||
fflush(stdout);
|
||||
while (getchar() != '\n')
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* init_colors:
|
||||
* Initialize the potion color scheme for this time
|
||||
*/
|
||||
|
||||
init_colors()
|
||||
{
|
||||
register int i, j;
|
||||
bool used[NCOLORS];
|
||||
|
||||
for(i = 0; i < NCOLORS; i++)
|
||||
used[i] = FALSE;
|
||||
|
||||
for (i = 0 ; i < MAXPOTIONS ; i++)
|
||||
{
|
||||
do
|
||||
j = rnd(NCOLORS);
|
||||
until (!used[j]);
|
||||
used[j] = TRUE;
|
||||
p_colors[i] = rainbow[j];
|
||||
p_know[i] = FALSE;
|
||||
p_guess[i] = NULL;
|
||||
if (i > 0)
|
||||
p_magic[i].mi_prob += p_magic[i-1].mi_prob;
|
||||
}
|
||||
badcheck("potions", p_magic, MAXPOTIONS);
|
||||
}
|
||||
|
||||
/*
|
||||
* init_materials:
|
||||
* Initialize the construction materials for wands and staffs
|
||||
*/
|
||||
|
||||
init_materials()
|
||||
{
|
||||
register int i, j;
|
||||
register char *str;
|
||||
bool metused[NMETAL], woodused[NWOOD];
|
||||
|
||||
for(i = 0; i < NWOOD; i++)
|
||||
woodused[i] = FALSE;
|
||||
|
||||
for(i = 0; i < NMETAL; i++)
|
||||
metused[i] = FALSE;
|
||||
|
||||
for (i = 0 ; i < MAXSTICKS ; i++)
|
||||
{
|
||||
for (;;)
|
||||
if (rnd(100) > 50)
|
||||
{
|
||||
j = rnd(NMETAL);
|
||||
|
||||
if (!metused[j])
|
||||
{
|
||||
ws_type[i] = "wand";
|
||||
str = metal[j];
|
||||
metused[j] = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
j = rnd(NWOOD);
|
||||
|
||||
if (!woodused[j])
|
||||
{
|
||||
ws_type[i] = "staff";
|
||||
str = wood[j];
|
||||
woodused[j] = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ws_made[i] = str;
|
||||
ws_know[i] = FALSE;
|
||||
ws_guess[i] = NULL;
|
||||
if (i > 0)
|
||||
ws_magic[i].mi_prob += ws_magic[i-1].mi_prob;
|
||||
}
|
||||
badcheck("sticks", ws_magic, MAXSTICKS);
|
||||
}
|
||||
|
||||
/*
|
||||
* do any initialization for miscellaneous magic
|
||||
*/
|
||||
|
||||
init_misc()
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i=0; i < MAXMM; i++) {
|
||||
m_know[i] = FALSE;
|
||||
m_guess[i] = NULL;
|
||||
if (i > 0)
|
||||
m_magic[i].mi_prob += m_magic[i-1].mi_prob;
|
||||
}
|
||||
|
||||
badcheck("miscellaneous magic", m_magic, MAXMM);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* init_names:
|
||||
* Generate the names of the various scrolls
|
||||
*/
|
||||
|
||||
init_names()
|
||||
{
|
||||
register int nsyl;
|
||||
register char *cp, *sp;
|
||||
register int i, nwords;
|
||||
|
||||
for (i = 0 ; i < MAXSCROLLS ; i++)
|
||||
{
|
||||
cp = prbuf;
|
||||
nwords = rnd(COLS/20) + 1 + (COLS > 40 ? 1 : 0);
|
||||
while(nwords--)
|
||||
{
|
||||
nsyl = rnd(3)+1;
|
||||
while(nsyl--)
|
||||
{
|
||||
sp = sylls[rnd((sizeof sylls) / (sizeof (char *)))];
|
||||
while(*sp)
|
||||
*cp++ = *sp++;
|
||||
}
|
||||
*cp++ = ' ';
|
||||
}
|
||||
*--cp = '\0';
|
||||
s_names[i] = (char *) new(strlen(prbuf)+1);
|
||||
s_know[i] = FALSE;
|
||||
s_guess[i] = NULL;
|
||||
strcpy(s_names[i], prbuf);
|
||||
if (i > 0)
|
||||
s_magic[i].mi_prob += s_magic[i-1].mi_prob;
|
||||
}
|
||||
badcheck("scrolls", s_magic, MAXSCROLLS);
|
||||
}
|
||||
|
||||
/*
|
||||
* init_player:
|
||||
* roll up the rogue
|
||||
*/
|
||||
|
||||
init_player()
|
||||
{
|
||||
int stat_total, ch = 0, wpt = 0, i, j;
|
||||
struct linked_list *weap_item, *armor_item, *food_item;
|
||||
struct object *obj;
|
||||
char *class;
|
||||
|
||||
weap_item = armor_item = NULL;
|
||||
|
||||
if (char_type == -1) {
|
||||
/* See what type character will be */
|
||||
wclear(hw);
|
||||
touchwin(hw);
|
||||
mvwaddstr(hw,2,0,"[1] Fighter\n[2] Magician\n[3] Cleric\n[4] Thief");
|
||||
mvwaddstr(hw, 0, 0, "What character class do you desire? ");
|
||||
draw(hw);
|
||||
char_type = (wgetch(hw) - '0');
|
||||
while (char_type < 1 || char_type > 4) {
|
||||
mvwaddstr(hw,0,0,"Please enter a character type between 1 and 4: ");
|
||||
draw(hw);
|
||||
char_type = (wgetch(hw) - '0');
|
||||
}
|
||||
char_type--;
|
||||
}
|
||||
player.t_ctype = char_type;
|
||||
player.t_quiet = 0;
|
||||
pack = NULL;
|
||||
|
||||
#ifdef WIZARD
|
||||
/*
|
||||
* allow me to describe a super character
|
||||
*/
|
||||
if (wizard && md_getuid() == AUTHOR && strcmp(getenv("SUPER"),"YES") == 0) {
|
||||
pstats.s_str = 25;
|
||||
pstats.s_intel = 25;
|
||||
pstats.s_wisdom = 25;
|
||||
pstats.s_dext = 25;
|
||||
pstats.s_const = 25;
|
||||
pstats.s_charisma = 25;
|
||||
pstats.s_exp = 7500000L;
|
||||
pstats.s_lvl = 20;
|
||||
pstats.s_hpt = 500;
|
||||
pstats.s_carry = totalenc();
|
||||
strcpy(pstats.s_dmg,"3d4");
|
||||
if (player.t_ctype == C_FIGHTER)
|
||||
weap_item = spec_item(WEAPON, TWOSWORD, 5, 5);
|
||||
else
|
||||
weap_item = spec_item(WEAPON, SWORD, 5, 5);
|
||||
obj = OBJPTR(weap_item);
|
||||
obj->o_flags |= ISKNOW;
|
||||
add_pack(weap_item, TRUE, NULL);
|
||||
cur_weapon = obj;
|
||||
j = PLATE_ARMOR;
|
||||
if (player.t_ctype == C_THIEF)
|
||||
j = STUDDED_LEATHER;
|
||||
armor_item = spec_item(ARMOR, j, 10, 0);
|
||||
obj = OBJPTR(armor_item);
|
||||
obj->o_flags |= (ISKNOW | ISPROT);
|
||||
obj->o_weight = armors[j].a_wght;
|
||||
add_pack(armor_item, TRUE, NULL);
|
||||
cur_armor = obj;
|
||||
purse += 10000;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
{
|
||||
wclear(hw);
|
||||
do {
|
||||
if (armor_item != NULL) {
|
||||
o_discard(armor_item);
|
||||
armor_item = NULL;
|
||||
}
|
||||
if (weap_item != NULL) {
|
||||
o_discard(weap_item);
|
||||
weap_item = NULL;
|
||||
}
|
||||
pstats.s_lvl = 1;
|
||||
pstats.s_exp = 0L;
|
||||
pstats.s_hpt = 12 + rnd(10);
|
||||
pstats.s_str = 7 + rnd(5);
|
||||
pstats.s_intel = 7 + rnd(5);
|
||||
pstats.s_wisdom = 7 + rnd(5);
|
||||
pstats.s_dext = 7 + rnd(5);
|
||||
pstats.s_const = 14 + rnd(5);
|
||||
pstats.s_charisma = 7 + rnd(5);
|
||||
|
||||
/* Now for the special ability */
|
||||
switch (char_type) {
|
||||
case C_FIGHTER: pstats.s_str = (rnd(10) == 7) ? 18 : 16;
|
||||
when C_MAGICIAN: pstats.s_intel = (rnd(10) == 7) ? 18 : 16;
|
||||
when C_CLERIC: pstats.s_wisdom= (rnd(10) == 7) ? 18 : 16;
|
||||
when C_THIEF: pstats.s_dext = (rnd(10) == 7) ? 18 : 16;
|
||||
}
|
||||
strcpy(pstats.s_dmg,"1d4");
|
||||
stat_total =pstats.s_str + pstats.s_intel + pstats.s_wisdom +
|
||||
pstats.s_dext + pstats.s_const;
|
||||
/*
|
||||
* since the player can re-roll stats at will, keep the maximum
|
||||
* to some reasonable limit
|
||||
*/
|
||||
if (stat_total > MAXSTATS)
|
||||
pstats.s_const -= (stat_total - MAXSTATS);
|
||||
pstats.s_carry = totalenc();
|
||||
|
||||
/*
|
||||
* Give the rogue his weaponry.
|
||||
*/
|
||||
do {
|
||||
i = rnd(8); /* number of acceptable weapons */
|
||||
switch(i) {
|
||||
case 0: ch = 25; wpt = MACE;
|
||||
when 1: ch = 25; wpt = SWORD;
|
||||
when 2: ch = 20; wpt = BATTLEAXE;
|
||||
when 3: ch = 20; wpt = TRIDENT;
|
||||
when 4: ch = 20; wpt = SPETUM;
|
||||
when 5: ch = 20; wpt = BARDICHE;
|
||||
when 6: ch = 15; wpt = PIKE;
|
||||
when 7: ch = 20; wpt = HALBERD;
|
||||
}
|
||||
} while(rnd(100) > ch);
|
||||
if (player.t_ctype == C_FIGHTER)
|
||||
wpt = TWOSWORD;
|
||||
weap_item = spec_item(WEAPON, wpt, rnd(2), rnd(2)+1);
|
||||
obj = OBJPTR(weap_item);
|
||||
obj->o_flags |= ISKNOW;
|
||||
/*
|
||||
* And his suit of armor.......
|
||||
* Thieves can only wear leather armor
|
||||
* fighters get better armor on an average
|
||||
*/
|
||||
if (player.t_ctype == C_THIEF)
|
||||
j = STUDDED_LEATHER;
|
||||
else {
|
||||
if (player.t_ctype == C_FIGHTER)
|
||||
i = 50 + rnd(50);
|
||||
else
|
||||
i = rnd(100);
|
||||
j = 0;
|
||||
while (armors[j].a_prob < i)
|
||||
j++;
|
||||
}
|
||||
armor_item = spec_item(ARMOR, j, 0, 0);
|
||||
obj = OBJPTR(armor_item);
|
||||
obj->o_flags |= ISKNOW;
|
||||
obj->o_weight = armors[j].a_wght;
|
||||
switch(player.t_ctype) {
|
||||
case C_FIGHTER: class = "fighter";
|
||||
when C_MAGICIAN:class = "magic user";
|
||||
when C_CLERIC: class = "cleric";
|
||||
when C_THIEF: class = "thief";
|
||||
otherwise: class = "unknown";
|
||||
}
|
||||
wmove(hw, 2, 0);
|
||||
wprintw(hw, "You have rolled a %s with the following attributes:",class);
|
||||
wmove(hw,4,0);
|
||||
wprintw(hw, " Int: %2d", pstats.s_intel);
|
||||
wprintw(hw, " Str: %2d", pstats.s_str);
|
||||
wprintw(hw, " Wis: %2d", pstats.s_wisdom);
|
||||
wprintw(hw, " Dex: %2d", pstats.s_dext);
|
||||
wprintw(hw, " Const: %2d", pstats.s_const);
|
||||
wclrtoeol(hw);
|
||||
wmove(hw, 6, 0);
|
||||
wprintw(hw, " Hp: %2d", pstats.s_hpt);
|
||||
wclrtoeol(hw);
|
||||
mvwaddstr(hw, 8, 5, inv_name(OBJPTR(weap_item), FALSE));
|
||||
wclrtoeol(hw);
|
||||
mvwaddstr(hw, 9, 5, inv_name(OBJPTR(armor_item), FALSE));
|
||||
wclrtoeol(hw);
|
||||
mvwaddstr(hw,0,0,"Would you like to re-roll the character? ");
|
||||
draw(hw);
|
||||
} while(wgetch(hw) == 'y');
|
||||
|
||||
obj = OBJPTR(weap_item);
|
||||
add_pack(weap_item, TRUE, NULL);
|
||||
cur_weapon = obj;
|
||||
obj = OBJPTR(armor_item);
|
||||
add_pack(armor_item, TRUE, NULL);
|
||||
cur_armor = obj;
|
||||
}
|
||||
/*
|
||||
* Give him some food
|
||||
*/
|
||||
food_item = spec_item(FOOD, 0, 0, 0);
|
||||
obj = OBJPTR(food_item);
|
||||
obj->o_weight = things[TYP_FOOD].mi_wght;
|
||||
add_pack(food_item, TRUE, NULL);
|
||||
pstats.s_arm = 10;
|
||||
max_stats = pstats;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* init_stones:
|
||||
* Initialize the ring stone setting scheme for this time
|
||||
*/
|
||||
|
||||
init_stones()
|
||||
{
|
||||
register int i, j;
|
||||
bool used[NSTONES];
|
||||
|
||||
for (i = 0; i < NSTONES; i++)
|
||||
used[i] = FALSE;
|
||||
|
||||
for (i = 0 ; i < MAXRINGS ; i++)
|
||||
{
|
||||
do
|
||||
j = rnd(NSTONES);
|
||||
until (!used[j]);
|
||||
|
||||
used[j] = TRUE;
|
||||
r_stones[i] = stones[j];
|
||||
r_know[i] = FALSE;
|
||||
r_guess[i] = NULL;
|
||||
if (i > 0)
|
||||
r_magic[i].mi_prob += r_magic[i-1].mi_prob;
|
||||
}
|
||||
badcheck("rings", r_magic, MAXRINGS);
|
||||
}
|
||||
|
||||
/*
|
||||
* init_things
|
||||
* Initialize the probabilities for types of things
|
||||
*/
|
||||
init_things()
|
||||
{
|
||||
register struct magic_item *mp;
|
||||
|
||||
for (mp = &things[1] ; mp < &things[NUMTHINGS] ; mp++)
|
||||
mp->mi_prob += (mp-1)->mi_prob;
|
||||
badcheck("things", things, NUMTHINGS);
|
||||
}
|
||||
|
||||
|
||||
489
arogue5/io.c
Normal file
489
arogue5/io.c
Normal file
|
|
@ -0,0 +1,489 @@
|
|||
/*
|
||||
* Various input/output functions
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "curses.h"
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include "rogue.h"
|
||||
|
||||
/*
|
||||
* msg:
|
||||
* Display a message at the top of the screen.
|
||||
*/
|
||||
|
||||
static char msgbuf[BUFSIZ];
|
||||
static int newpos = 0;
|
||||
|
||||
/*VARARGS1*/
|
||||
msg(char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
/*
|
||||
* if the string is "", just clear the line
|
||||
*/
|
||||
if (*fmt == '\0')
|
||||
{
|
||||
overwrite(cw,msgw);
|
||||
wmove(msgw, 0, 0);
|
||||
clearok(msgw, FALSE);
|
||||
draw(msgw);
|
||||
mpos = 0;
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* otherwise add to the message and flush it out
|
||||
*/
|
||||
va_start(ap,fmt);
|
||||
doadd(fmt, ap);
|
||||
va_end(ap);
|
||||
endmsg();
|
||||
}
|
||||
|
||||
/*
|
||||
* add things to the current message
|
||||
*/
|
||||
addmsg(char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap,fmt);
|
||||
doadd(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/*
|
||||
* Display a new msg (giving him a chance to see the previous one if it
|
||||
* is up there with the --More--)
|
||||
*/
|
||||
endmsg()
|
||||
{
|
||||
strncpy(huh, msgbuf, sizeof(huh));
|
||||
|
||||
huh[ sizeof(huh) - 1 ] = 0;
|
||||
|
||||
if (mpos)
|
||||
{
|
||||
wmove(msgw, 0, mpos);
|
||||
waddstr(msgw, morestr);
|
||||
draw(cw);
|
||||
draw(msgw);
|
||||
wait_for(msgw,' ');
|
||||
overwrite(cw,msgw);
|
||||
wmove(msgw,0,0);
|
||||
touchwin(cw);
|
||||
}
|
||||
else {
|
||||
overwrite(cw,msgw);
|
||||
wmove(msgw,0,0);
|
||||
}
|
||||
waddstr(msgw, msgbuf);
|
||||
mpos = newpos;
|
||||
newpos = 0;
|
||||
msgbuf[0] = '\0';
|
||||
draw(cw);
|
||||
clearok(msgw, FALSE);
|
||||
draw(msgw);
|
||||
}
|
||||
|
||||
doadd(char *fmt, va_list ap)
|
||||
{
|
||||
/*
|
||||
* Do the sprintf into newmsg and append to msgbuf
|
||||
*/
|
||||
|
||||
vsnprintf(&msgbuf[newpos], sizeof(msgbuf)-newpos-1, fmt, ap);
|
||||
|
||||
newpos = strlen(msgbuf);
|
||||
}
|
||||
|
||||
/*
|
||||
* step_ok:
|
||||
* returns true if it is ok for type to step on ch
|
||||
* flgptr will be NULL if we don't know what the monster is yet!
|
||||
*/
|
||||
|
||||
step_ok(y, x, can_on_monst, flgptr)
|
||||
register int y, x, can_on_monst;
|
||||
register struct thing *flgptr;
|
||||
{
|
||||
/* can_on_monst = MONSTOK if all we care about are physical obstacles */
|
||||
register struct linked_list *item;
|
||||
char ch;
|
||||
|
||||
/* What is here? Don't check monster window if MONSTOK is set */
|
||||
if (can_on_monst == MONSTOK) ch = CCHAR( mvinch(y, x) );
|
||||
else ch = CCHAR( winat(y, x) );
|
||||
|
||||
switch (ch)
|
||||
{
|
||||
case ' ':
|
||||
case '|':
|
||||
case '-':
|
||||
case SECRETDOOR:
|
||||
if (flgptr && on(*flgptr, CANINWALL)) return(TRUE);
|
||||
return FALSE;
|
||||
when SCROLL:
|
||||
if (can_on_monst == MONSTOK) return(TRUE); /* Not a real obstacle */
|
||||
/*
|
||||
* If it is a scroll, it might be a scare monster scroll
|
||||
* so we need to look it up to see what type it is.
|
||||
*/
|
||||
if (flgptr && flgptr->t_ctype == C_MONSTER) {
|
||||
item = find_obj(y, x);
|
||||
if (item != NULL &&
|
||||
(OBJPTR(item))->o_which==S_SCARE &&
|
||||
(flgptr == NULL || flgptr->t_stats.s_intel < 16))
|
||||
return(FALSE); /* All but smart ones are scared */
|
||||
}
|
||||
return(TRUE);
|
||||
otherwise:
|
||||
return (!isalpha(ch));
|
||||
}
|
||||
}
|
||||
/*
|
||||
* shoot_ok:
|
||||
* returns true if it is ok for type to shoot over ch
|
||||
*/
|
||||
|
||||
shoot_ok(ch)
|
||||
{
|
||||
switch (ch)
|
||||
{
|
||||
case ' ':
|
||||
case '|':
|
||||
case '-':
|
||||
case SECRETDOOR:
|
||||
case FOREST:
|
||||
return FALSE;
|
||||
default:
|
||||
return (!isalpha(ch));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* readchar:
|
||||
* flushes stdout so that screen is up to date and then returns
|
||||
* getchar.
|
||||
*/
|
||||
|
||||
readchar()
|
||||
{
|
||||
int ch;
|
||||
|
||||
ch = md_readchar(cw);
|
||||
|
||||
if ((ch == 3) || (ch == 0))
|
||||
{
|
||||
quit(0);
|
||||
return(27);
|
||||
}
|
||||
|
||||
return(ch);
|
||||
}
|
||||
|
||||
/*
|
||||
* status:
|
||||
* Display the important stats line. Keep the cursor where it was.
|
||||
*/
|
||||
|
||||
status(display)
|
||||
bool display; /* is TRUE, display unconditionally */
|
||||
{
|
||||
register struct stats *stat_ptr, *max_ptr;
|
||||
register int oy = 0, ox = 0, temp;
|
||||
register char *pb;
|
||||
static char buf[LINELEN];
|
||||
static int hpwidth = 0, s_hungry = -1;
|
||||
static int s_lvl = -1, s_pur, s_hp = -1, s_str, maxs_str,
|
||||
s_ac = 0;
|
||||
static short s_intel, s_dext, s_wisdom, s_const, s_charisma;
|
||||
static short maxs_intel, maxs_dext, maxs_wisdom, maxs_const, maxs_charisma;
|
||||
static unsigned long s_exp = 0;
|
||||
static int s_carry, s_pack;
|
||||
bool first_line=FALSE;
|
||||
|
||||
/* Use a mini status version if we have a small window */
|
||||
if (COLS < 80) {
|
||||
ministat();
|
||||
return;
|
||||
}
|
||||
|
||||
stat_ptr = &pstats;
|
||||
max_ptr = &max_stats;
|
||||
|
||||
/*
|
||||
* If nothing has changed in the first line, then skip it
|
||||
*/
|
||||
if (!display &&
|
||||
s_lvl == level &&
|
||||
s_intel == stat_ptr->s_intel &&
|
||||
s_wisdom == stat_ptr->s_wisdom &&
|
||||
s_dext == dex_compute() &&
|
||||
s_const == stat_ptr->s_const &&
|
||||
s_charisma == stat_ptr->s_charisma &&
|
||||
s_str == str_compute() &&
|
||||
s_pack == stat_ptr->s_pack &&
|
||||
s_carry == stat_ptr->s_carry &&
|
||||
maxs_intel == max_ptr->s_intel &&
|
||||
maxs_wisdom == max_ptr->s_wisdom &&
|
||||
maxs_dext == max_ptr->s_dext &&
|
||||
maxs_const == max_ptr->s_const &&
|
||||
maxs_charisma == max_ptr->s_charisma &&
|
||||
maxs_str == max_ptr->s_str ) goto line_two;
|
||||
|
||||
/* Display the first line */
|
||||
first_line = TRUE;
|
||||
getyx(cw, oy, ox);
|
||||
sprintf(buf, "Int:%d(%d) Str:%d", stat_ptr->s_intel,
|
||||
max_ptr->s_intel, str_compute());
|
||||
|
||||
/* Maximum strength */
|
||||
pb = &buf[strlen(buf)];
|
||||
sprintf(pb, "(%d)", max_ptr->s_str);
|
||||
|
||||
pb = &buf[strlen(buf)];
|
||||
sprintf(pb, " Wis:%d(%d) Dxt:%d(%d) Const:%d(%d) Carry:%d(%d)",
|
||||
stat_ptr->s_wisdom,max_ptr->s_wisdom,dex_compute(),max_ptr->s_dext,
|
||||
stat_ptr->s_const,max_ptr->s_const,stat_ptr->s_pack/10,
|
||||
stat_ptr->s_carry/10);
|
||||
|
||||
/* Update first line status */
|
||||
s_intel = stat_ptr->s_intel;
|
||||
s_wisdom = stat_ptr->s_wisdom;
|
||||
s_dext = dex_compute();
|
||||
s_const = stat_ptr->s_const;
|
||||
s_charisma = stat_ptr->s_charisma;
|
||||
s_str = str_compute();
|
||||
s_pack = stat_ptr->s_pack;
|
||||
s_carry = stat_ptr->s_carry;
|
||||
maxs_intel = max_ptr->s_intel;
|
||||
maxs_wisdom = max_ptr->s_wisdom;
|
||||
maxs_dext = max_ptr->s_dext;
|
||||
maxs_const = max_ptr->s_const;
|
||||
maxs_charisma = max_ptr->s_charisma;
|
||||
maxs_str = max_ptr->s_str;
|
||||
|
||||
/* Print the line */
|
||||
mvwaddstr(cw, LINES - 2, 0, buf);
|
||||
wclrtoeol(cw);
|
||||
|
||||
/*
|
||||
* If nothing has changed since the last status, don't
|
||||
* bother.
|
||||
*/
|
||||
line_two:
|
||||
if (!display &&
|
||||
s_hp == stat_ptr->s_hpt &&
|
||||
s_exp == stat_ptr->s_exp &&
|
||||
s_pur == purse &&
|
||||
s_ac == ac_compute() - dext_prot(s_dext) &&
|
||||
s_lvl == level &&
|
||||
s_hungry == hungry_state ) return;
|
||||
|
||||
if (!first_line) getyx(cw, oy, ox);
|
||||
if (s_hp != max_ptr->s_hpt)
|
||||
{
|
||||
temp = s_hp = max_ptr->s_hpt;
|
||||
for (hpwidth = 0; temp; hpwidth++)
|
||||
temp /= 10;
|
||||
}
|
||||
sprintf(buf, "Lvl:%d Au:%d Hp:%*d(%*d) Ac:%d Exp:%d/%lu %s",
|
||||
level, purse, hpwidth, stat_ptr->s_hpt, hpwidth, max_ptr->s_hpt,
|
||||
ac_compute() - dext_prot(s_dext),stat_ptr->s_lvl, stat_ptr->s_exp,
|
||||
cnames[player.t_ctype][min(stat_ptr->s_lvl-1, 10)]);
|
||||
|
||||
/*
|
||||
* Save old status
|
||||
*/
|
||||
s_lvl = level;
|
||||
s_pur = purse;
|
||||
s_hp = stat_ptr->s_hpt;
|
||||
s_exp = stat_ptr->s_exp;
|
||||
s_ac = ac_compute() - dext_prot(s_dext);
|
||||
mvwaddstr(cw, LINES - 1, 0, buf);
|
||||
switch (hungry_state)
|
||||
{
|
||||
case F_OKAY: ;
|
||||
when F_HUNGRY:
|
||||
waddstr(cw, " Hungry");
|
||||
when F_WEAK:
|
||||
waddstr(cw, " Weak");
|
||||
when F_FAINT:
|
||||
waddstr(cw, " Fainting");
|
||||
}
|
||||
wclrtoeol(cw);
|
||||
s_hungry = hungry_state;
|
||||
wmove(cw, oy, ox);
|
||||
}
|
||||
|
||||
ministat()
|
||||
{
|
||||
register int oy, ox, temp;
|
||||
static char buf[LINELEN];
|
||||
static int hpwidth = 0;
|
||||
static int s_lvl = -1, s_pur, s_hp = -1;
|
||||
|
||||
/*
|
||||
* If nothing has changed since the last status, don't
|
||||
* bother.
|
||||
*/
|
||||
if (s_hp == pstats.s_hpt && s_pur == purse && s_lvl == level)
|
||||
return;
|
||||
|
||||
getyx(cw, oy, ox);
|
||||
if (s_hp != max_stats.s_hpt)
|
||||
{
|
||||
temp = s_hp = max_stats.s_hpt;
|
||||
for (hpwidth = 0; temp; hpwidth++)
|
||||
temp /= 10;
|
||||
}
|
||||
sprintf(buf, "Lv: %d Au: %-5d Hp: %*d(%*d)",
|
||||
level, purse, hpwidth, pstats.s_hpt, hpwidth, max_stats.s_hpt);
|
||||
|
||||
/*
|
||||
* Save old status
|
||||
*/
|
||||
s_lvl = level;
|
||||
s_pur = purse;
|
||||
s_hp = pstats.s_hpt;
|
||||
mvwaddstr(cw, LINES - 1, 0, buf);
|
||||
wclrtoeol(cw);
|
||||
wmove(cw, oy, ox);
|
||||
}
|
||||
|
||||
/*
|
||||
* wait_for
|
||||
* Sit around until the guy types the right key
|
||||
*/
|
||||
|
||||
wait_for(win,ch)
|
||||
WINDOW *win;
|
||||
register char ch;
|
||||
{
|
||||
register char c;
|
||||
|
||||
if (ch == '\n')
|
||||
while ((c = wgetch(win)) != '\n' && c != '\r')
|
||||
continue;
|
||||
else
|
||||
while (wgetch(win) != ch)
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* show_win:
|
||||
* function used to display a window and wait before returning
|
||||
*/
|
||||
|
||||
show_win(scr, message)
|
||||
register WINDOW *scr;
|
||||
char *message;
|
||||
{
|
||||
mvwaddstr(scr, 0, 0, message);
|
||||
touchwin(scr);
|
||||
wmove(scr, hero.y, hero.x);
|
||||
draw(scr);
|
||||
wait_for(scr,' ');
|
||||
clearok(cw, TRUE);
|
||||
touchwin(cw);
|
||||
}
|
||||
|
||||
/*
|
||||
* dbotline:
|
||||
* Displays message on bottom line and waits for a space to return
|
||||
*/
|
||||
dbotline(scr,message)
|
||||
WINDOW *scr;
|
||||
char *message;
|
||||
{
|
||||
mvwaddstr(scr,LINES-1,0,message);
|
||||
draw(scr);
|
||||
wait_for(scr,' ');
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* restscr:
|
||||
* Restores the screen to the terminal
|
||||
*/
|
||||
restscr(scr)
|
||||
WINDOW *scr;
|
||||
{
|
||||
clearok(scr,TRUE);
|
||||
touchwin(scr);
|
||||
}
|
||||
|
||||
/*
|
||||
* netread:
|
||||
* Read a byte, short, or long machine independently
|
||||
* Always returns the value as an unsigned long.
|
||||
*/
|
||||
|
||||
unsigned long
|
||||
netread(error, size, stream)
|
||||
int *error;
|
||||
int size;
|
||||
FILE *stream;
|
||||
{
|
||||
unsigned long result = 0L, /* What we read in */
|
||||
partial; /* Partial value */
|
||||
int nextc, /* The next byte */
|
||||
i; /* To index through the result a byte at a time */
|
||||
|
||||
/* Be sure we have a right sized chunk */
|
||||
if (size < 1 || size > 4) {
|
||||
*error = 1;
|
||||
return(0L);
|
||||
}
|
||||
|
||||
for (i=0; i<size; i++) {
|
||||
nextc = getc(stream);
|
||||
if (nextc == EOF) {
|
||||
*error = 1;
|
||||
return(0L);
|
||||
}
|
||||
else {
|
||||
partial = (unsigned long) (nextc & 0xff);
|
||||
partial <<= 8*i;
|
||||
result |= partial;
|
||||
}
|
||||
}
|
||||
|
||||
*error = 0;
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* netwrite:
|
||||
* Write out a byte, short, or long machine independently.
|
||||
*/
|
||||
|
||||
netwrite(value, size, stream)
|
||||
unsigned long value; /* What to write */
|
||||
int size; /* How much to write out */
|
||||
FILE *stream; /* Where to write it */
|
||||
{
|
||||
int i; /* Goes through value one byte at a time */
|
||||
char outc; /* The next character to be written */
|
||||
|
||||
/* Be sure we have a right sized chunk */
|
||||
if (size < 1 || size > 4) return(0);
|
||||
|
||||
for (i=0; i<size; i++) {
|
||||
outc = (char) ((value >> (8 * i)) & 0xff);
|
||||
putc(outc, stream);
|
||||
}
|
||||
return(size);
|
||||
}
|
||||
185
arogue5/list.c
Normal file
185
arogue5/list.c
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* Functions for dealing with linked lists of goodies
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "curses.h"
|
||||
#include "rogue.h"
|
||||
|
||||
/*
|
||||
* detach:
|
||||
* Takes an item out of whatever linked list it might be in
|
||||
*/
|
||||
|
||||
_detach(list, item)
|
||||
register struct linked_list **list, *item;
|
||||
{
|
||||
if (*list == item)
|
||||
*list = next(item);
|
||||
if (prev(item) != NULL) item->l_prev->l_next = next(item);
|
||||
if (next(item) != NULL) item->l_next->l_prev = prev(item);
|
||||
item->l_next = NULL;
|
||||
item->l_prev = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* _attach:
|
||||
* add an item to the head of a list
|
||||
*/
|
||||
|
||||
_attach(list, item)
|
||||
register struct linked_list **list, *item;
|
||||
{
|
||||
if (*list != NULL)
|
||||
{
|
||||
item->l_next = *list;
|
||||
(*list)->l_prev = item;
|
||||
item->l_prev = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
item->l_next = NULL;
|
||||
item->l_prev = NULL;
|
||||
}
|
||||
|
||||
*list = item;
|
||||
}
|
||||
|
||||
/*
|
||||
* o_free_list:
|
||||
* Throw the whole object list away
|
||||
*/
|
||||
|
||||
_o_free_list(ptr)
|
||||
register struct linked_list **ptr;
|
||||
{
|
||||
register struct linked_list *item;
|
||||
|
||||
while (*ptr != NULL)
|
||||
{
|
||||
item = *ptr;
|
||||
*ptr = next(item);
|
||||
o_discard(item);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* o_discard:
|
||||
* free up an item and its object(and maybe contents)
|
||||
*/
|
||||
|
||||
o_discard(item)
|
||||
register struct linked_list *item;
|
||||
{
|
||||
register struct object *obj;
|
||||
obj = OBJPTR(item);
|
||||
if (obj->contents != NULL)
|
||||
o_free_list(obj->contents);
|
||||
total -= 2;
|
||||
FREE(item->l_data);
|
||||
FREE(item);
|
||||
}
|
||||
|
||||
/*
|
||||
* t_free_list:
|
||||
* Throw the whole thing list away
|
||||
*/
|
||||
|
||||
_t_free_list(ptr)
|
||||
register struct linked_list **ptr;
|
||||
{
|
||||
register struct linked_list *item;
|
||||
|
||||
while (*ptr != NULL)
|
||||
{
|
||||
item = *ptr;
|
||||
*ptr = next(item);
|
||||
t_discard(item);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* t_discard:
|
||||
* free up an item and its thing
|
||||
*/
|
||||
|
||||
t_discard(item)
|
||||
struct linked_list *item;
|
||||
{
|
||||
total -= 2;
|
||||
FREE(item->l_data);
|
||||
FREE(item);
|
||||
}
|
||||
|
||||
/*
|
||||
* destroy_item:
|
||||
* get rid of an item structure -- don't worry about contents
|
||||
*/
|
||||
|
||||
destroy_item(item)
|
||||
register struct linked_list *item;
|
||||
{
|
||||
total--;
|
||||
FREE(item);
|
||||
}
|
||||
|
||||
/*
|
||||
* new_item
|
||||
* get a new item with a specified size
|
||||
*/
|
||||
|
||||
struct linked_list *
|
||||
new_item(size)
|
||||
int size;
|
||||
{
|
||||
register struct linked_list *item;
|
||||
|
||||
if ((item = (struct linked_list *) new(sizeof *item)) == NULL)
|
||||
msg("Ran out of memory for header after %d items", total);
|
||||
if ((item->l_data = new(size)) == NULL)
|
||||
msg("Ran out of memory for data after %d items", total);
|
||||
item->l_next = item->l_prev = NULL;
|
||||
return item;
|
||||
}
|
||||
|
||||
/*
|
||||
* creat_item:
|
||||
* Create just an item structure -- don't make any contents
|
||||
*/
|
||||
|
||||
struct linked_list *
|
||||
creat_item()
|
||||
{
|
||||
register struct linked_list *item;
|
||||
|
||||
if ((item = (struct linked_list *) new(sizeof *item)) == NULL)
|
||||
msg("Ran out of memory for header after %d items", total);
|
||||
item->l_next = item->l_prev = NULL;
|
||||
return item;
|
||||
}
|
||||
|
||||
char *
|
||||
new(size)
|
||||
int size;
|
||||
{
|
||||
register char *space = ALLOC(size);
|
||||
static char errbuf[LINELEN];
|
||||
|
||||
if (space == NULL) {
|
||||
sprintf(errbuf,"Rogue ran out of memory (used = %d, wanted = %d).",
|
||||
md_memused(), size);
|
||||
fatal(errbuf);
|
||||
}
|
||||
total++;
|
||||
return space;
|
||||
}
|
||||
64
arogue5/mach_dep.h
Normal file
64
arogue5/mach_dep.h
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* machine dependicies
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
/*
|
||||
* define that the wizard commands exist
|
||||
*/
|
||||
#define WIZARD 1
|
||||
|
||||
/*
|
||||
* define if you want to limit scores to one per class per userid
|
||||
*/
|
||||
#undef LIMITSCORE
|
||||
|
||||
/*
|
||||
* where scorefile should live
|
||||
*/
|
||||
#define SCOREFILE "/bnr/contrib/lib/rogue/scorefile"
|
||||
|
||||
/*
|
||||
* Variables for checking to make sure the system isn't too loaded
|
||||
* for people to play
|
||||
*/
|
||||
|
||||
#undef MAXUSERS /*40*/ /* max number of users for this game */
|
||||
#undef MAXLOAD /*40*/ /* 10 * max 15 minute load average */
|
||||
|
||||
#undef CHECKTIME /*15*/ /* number of minutes between load checks */
|
||||
/* if not defined checks are only on startup */
|
||||
|
||||
#ifdef MAXLOAD
|
||||
#define LOADAV /* defined if rogue should provide loadav() */
|
||||
|
||||
#ifdef LOADAV
|
||||
#define NAMELIST "/unix" /* where the system namelist lives */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef MAXUSERS
|
||||
#define UCOUNT /* defined if rogue should provide ucount() */
|
||||
|
||||
#ifdef UCOUNT
|
||||
#define UTMP "/etc/utmp" /* where utmp file lives */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#undef AUTHOR /*212*/
|
||||
|
||||
/*
|
||||
* define the current author of the program for "special handling"
|
||||
*/
|
||||
#ifndef AUTHOR
|
||||
#define AUTHOR 0 /* Default to root if not specified above */
|
||||
#endif
|
||||
530
arogue5/main.c
Normal file
530
arogue5/main.c
Normal file
|
|
@ -0,0 +1,530 @@
|
|||
/*
|
||||
* Rogue
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "curses.h"
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include "mach_dep.h"
|
||||
#include "network.h"
|
||||
#include "rogue.h"
|
||||
|
||||
#ifdef CHECKTIME
|
||||
static int num_checks; /* times we've gone over in checkout() */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* fruits that you get at startup
|
||||
*/
|
||||
static char *funfruit[] = {
|
||||
"candleberry", "caprifig", "dewberry", "elderberry",
|
||||
"gooseberry", "guanabana", "hagberry", "ilama",
|
||||
"imbu", "jaboticaba", "jujube", "litchi",
|
||||
"mombin", "pitanga", "prickly pear", "rambutan",
|
||||
"sapodilla", "soursop", "sweetsop", "whortleberry",
|
||||
"jellybean", "apple", "strawberry", "blueberry",
|
||||
"peach", "banana"
|
||||
};
|
||||
#define NFRUIT (sizeof(funfruit) / sizeof (char *))
|
||||
|
||||
main(argc, argv, envp)
|
||||
char **argv;
|
||||
char **envp;
|
||||
{
|
||||
register char *env;
|
||||
int lowtime;
|
||||
time_t now;
|
||||
char *roguedir = md_getroguedir();
|
||||
|
||||
md_init();
|
||||
|
||||
/*
|
||||
* get home and options from environment
|
||||
*/
|
||||
|
||||
strncpy(home,md_gethomedir(),LINELEN);
|
||||
|
||||
/* Get default save file */
|
||||
strcpy(file_name, home);
|
||||
strcat(file_name, "arogue58.sav");
|
||||
|
||||
/* Get default score file */
|
||||
strcpy(score_file, roguedir);
|
||||
|
||||
if (*score_file)
|
||||
strcat(score_file,"/");
|
||||
|
||||
strcat(score_file, "arogue58.scr");
|
||||
|
||||
if ((env = getenv("ROGUEOPTS")) != NULL)
|
||||
parse_opts(env);
|
||||
|
||||
if (whoami[0] == '\0')
|
||||
strucpy(whoami, md_getusername(), strlen(md_getusername()));
|
||||
|
||||
if (env == NULL || fruit[0] == '\0') {
|
||||
md_srand((long)(getpid()+time(0)));
|
||||
strcpy(fruit, funfruit[rnd(NFRUIT)]);
|
||||
}
|
||||
|
||||
/*
|
||||
* check for print-score option
|
||||
*/
|
||||
if (argc == 2 && strcmp(argv[1], "-s") == 0)
|
||||
{
|
||||
waswizard = TRUE;
|
||||
score(0, SCOREIT, 0);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#ifdef NUMNET
|
||||
/*
|
||||
* Check for a network update
|
||||
*/
|
||||
if (argc == 2 && strcmp(argv[1], "-u") == 0) {
|
||||
unsigned long netread();
|
||||
int errcheck, errors = 0;
|
||||
unsigned long amount;
|
||||
short monster;
|
||||
|
||||
/* Read in the amount and monster values to pass to score */
|
||||
amount = netread(&errcheck, sizeof(unsigned long), stdin);
|
||||
if (errcheck) errors++;
|
||||
|
||||
monster = (short) netread(&errcheck, sizeof(short), stdin);
|
||||
if (errcheck) errors++;
|
||||
|
||||
/* Now do the update if there were no errors */
|
||||
if (errors) exit(1);
|
||||
else {
|
||||
score(amount, UPDATE, monster);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WIZARD
|
||||
/*
|
||||
* Check to see if he is a wizard
|
||||
*/
|
||||
if (argc >= 2 && argv[1][0] == '\0')
|
||||
if (strcmp(PASSWD, md_crypt(md_getpass("Wizard's password: "), "Si")) == 0)
|
||||
{
|
||||
printf("Hail Mighty Wizard\n");
|
||||
wizard = TRUE;
|
||||
argv++;
|
||||
argc--;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MAXLOAD|MAXUSERS
|
||||
if (too_much() && !wizard && !author())
|
||||
{
|
||||
printf("Sorry, %s, but the system is too loaded now.\n", whoami);
|
||||
printf("Try again later. Meanwhile, why not enjoy a%s %s?\n",
|
||||
vowelstr(fruit), fruit);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
if (argc == 2)
|
||||
if (!restore(argv[1], envp)) /* Note: restore will never return */
|
||||
exit(1);
|
||||
lowtime = (int) time(&now);
|
||||
dnum = (wizard && getenv("SEED") != NULL ?
|
||||
atoi(getenv("SEED")) :
|
||||
lowtime + getpid());
|
||||
if (wizard)
|
||||
printf("Hello %s, welcome to dungeon #%d\n", whoami, dnum);
|
||||
else
|
||||
printf("Hello %s, just a moment while I dig the dungeon...\n", whoami);
|
||||
fflush(stdout);
|
||||
seed = dnum;
|
||||
md_srand(seed);
|
||||
|
||||
init_things(); /* Set up probabilities of things */
|
||||
init_colors(); /* Set up colors of potions */
|
||||
init_stones(); /* Set up stone settings of rings */
|
||||
init_materials(); /* Set up materials of wands */
|
||||
initscr(); /* Start up cursor package */
|
||||
init_names(); /* Set up names of scrolls */
|
||||
init_misc(); /* Set up miscellaneous magic */
|
||||
if (LINES < 24 || COLS < 80) {
|
||||
printf("\nERROR: screen size to small for rogue\n");
|
||||
byebye(-1);
|
||||
}
|
||||
|
||||
if ((whoami == NULL) || (*whoami == '\0') || (strcmp(whoami,"dosuser")==0))
|
||||
{
|
||||
echo();
|
||||
mvaddstr(23,2,"Rogue's Name? ");
|
||||
wgetnstr(stdscr,whoami,LINELEN);
|
||||
noecho();
|
||||
}
|
||||
|
||||
if ((whoami == NULL) || (*whoami == '\0'))
|
||||
strcpy(whoami,"Rodney");
|
||||
|
||||
setup();
|
||||
/*
|
||||
* Set up windows
|
||||
*/
|
||||
cw = newwin(LINES, COLS, 0, 0);
|
||||
mw = newwin(LINES, COLS, 0, 0);
|
||||
hw = newwin(LINES, COLS, 0, 0);
|
||||
msgw = newwin(4, COLS, 0, 0);
|
||||
keypad(cw,1);
|
||||
keypad(msgw,1);
|
||||
|
||||
init_player(); /* Roll up the rogue */
|
||||
waswizard = wizard;
|
||||
new_level(NORMLEV); /* Draw current level */
|
||||
/*
|
||||
* Start up daemons and fuses
|
||||
*/
|
||||
daemon(doctor, &player, AFTER);
|
||||
fuse(swander, 0, WANDERTIME, AFTER);
|
||||
daemon(stomach, 0, AFTER);
|
||||
daemon(runners, 0, AFTER);
|
||||
if (player.t_ctype == C_THIEF)
|
||||
daemon(trap_look, 0, AFTER);
|
||||
|
||||
/* Choose a quest item */
|
||||
quest_item = rnd(MAXRELIC);
|
||||
msg("You have been quested to retrieve the %s....",
|
||||
rel_magic[quest_item].mi_name);
|
||||
mpos = 0;
|
||||
playit();
|
||||
}
|
||||
|
||||
/*
|
||||
* endit:
|
||||
* Exit the program abnormally.
|
||||
*/
|
||||
void
|
||||
endit(int sig)
|
||||
{
|
||||
NOOP(sig);
|
||||
|
||||
fatal("Ok, if you want to exit that badly, I'll have to allow it\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* fatal:
|
||||
* Exit the program, printing a message.
|
||||
*/
|
||||
|
||||
fatal(s)
|
||||
char *s;
|
||||
{
|
||||
clear();
|
||||
move(LINES-2, 0);
|
||||
printw("%s", s);
|
||||
draw(stdscr);
|
||||
endwin();
|
||||
printf("\n"); /* So the cursor doesn't stop at the end of the line */
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* rnd:
|
||||
* Pick a very random number.
|
||||
*/
|
||||
|
||||
rnd(range)
|
||||
register int range;
|
||||
{
|
||||
return(range == 0 ? 0 : md_rand() % range);
|
||||
}
|
||||
|
||||
/*
|
||||
* roll:
|
||||
* roll a number of dice
|
||||
*/
|
||||
|
||||
roll(number, sides)
|
||||
register int number, sides;
|
||||
{
|
||||
register int dtotal = 0;
|
||||
|
||||
while(number--)
|
||||
dtotal += rnd(sides)+1;
|
||||
return dtotal;
|
||||
}
|
||||
# ifdef SIGTSTP
|
||||
/*
|
||||
* handle stop and start signals
|
||||
*/
|
||||
void
|
||||
tstp(int a)
|
||||
{
|
||||
mvcur(0, COLS - 1, LINES - 1, 0);
|
||||
endwin();
|
||||
fflush(stdout);
|
||||
kill(0, SIGTSTP);
|
||||
signal(SIGTSTP, tstp);
|
||||
raw();
|
||||
noecho();
|
||||
keypad(cw,1);
|
||||
clearok(curscr, TRUE);
|
||||
touchwin(cw);
|
||||
draw(cw);
|
||||
md_flushinp();
|
||||
}
|
||||
# endif
|
||||
|
||||
setup()
|
||||
{
|
||||
#ifdef CHECKTIME
|
||||
int checkout();
|
||||
#endif
|
||||
|
||||
#ifndef DUMP
|
||||
#ifdef SIGHUP
|
||||
signal(SIGHUP, auto_save);
|
||||
#endif
|
||||
signal(SIGILL, bugkill);
|
||||
#ifdef SIGTRAP
|
||||
signal(SIGTRAP, bugkill);
|
||||
#endif
|
||||
#ifdef SIGIOT
|
||||
signal(SIGIOT, bugkill);
|
||||
#endif
|
||||
#if 0
|
||||
signal(SIGEMT, bugkill);
|
||||
signal(SIGFPE, bugkill);
|
||||
signal(SIGBUS, bugkill);
|
||||
signal(SIGSEGV, bugkill);
|
||||
signal(SIGSYS, bugkill);
|
||||
signal(SIGPIPE, bugkill);
|
||||
#endif
|
||||
signal(SIGTERM, auto_save);
|
||||
#endif
|
||||
|
||||
signal(SIGINT, quit);
|
||||
#ifndef DUMP
|
||||
#ifdef SIGQUIT
|
||||
signal(SIGQUIT, endit);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef SIGTSTP
|
||||
signal(SIGTSTP, tstp);
|
||||
#endif
|
||||
#ifdef CHECKTIME
|
||||
if (!author())
|
||||
{
|
||||
signal(SIGALRM, checkout);
|
||||
alarm(CHECKTIME * 60);
|
||||
num_checks = 0;
|
||||
}
|
||||
#endif
|
||||
crmode(); /* Cbreak mode */
|
||||
noecho(); /* Echo off */
|
||||
}
|
||||
|
||||
/*
|
||||
* playit:
|
||||
* The main loop of the program. Loop until the game is over,
|
||||
* refreshing things and looking at the proper times.
|
||||
*/
|
||||
|
||||
playit()
|
||||
{
|
||||
register char *opts;
|
||||
|
||||
|
||||
/*
|
||||
* parse environment declaration of options
|
||||
*/
|
||||
if ((opts = getenv("ROGUEOPTS")) != NULL)
|
||||
parse_opts(opts);
|
||||
|
||||
|
||||
player.t_oldpos = hero;
|
||||
oldrp = roomin(&hero);
|
||||
after = TRUE;
|
||||
while (playing)
|
||||
command(); /* Command execution */
|
||||
endit(0);
|
||||
}
|
||||
|
||||
#if MAXLOAD|MAXUSERS
|
||||
/*
|
||||
* see if the system is being used too much for this game
|
||||
*/
|
||||
too_much()
|
||||
{
|
||||
#ifdef MAXLOAD
|
||||
double avec[3];
|
||||
#endif
|
||||
|
||||
#ifdef MAXLOAD
|
||||
loadav(avec);
|
||||
return (avec[2] > (MAXLOAD / 10.0));
|
||||
#else
|
||||
return (ucount() > MAXUSERS);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* author:
|
||||
* See if a user is an author of the program
|
||||
*/
|
||||
author()
|
||||
{
|
||||
switch (md_getuid()) {
|
||||
#if AUTHOR
|
||||
case AUTHOR:
|
||||
#endif
|
||||
case 0:
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef CHECKTIME
|
||||
checkout()
|
||||
{
|
||||
static char *msgs[] = {
|
||||
"The system is too loaded for games. Please leave in %d minutes",
|
||||
"Please save your game. You have %d minutes",
|
||||
"This is your last chance. You had better leave in %d minutes",
|
||||
};
|
||||
int checktime;
|
||||
|
||||
signal(SIGALRM, checkout);
|
||||
if (!holiday() && !author()) {
|
||||
wclear(cw);
|
||||
mvwaddstr(cw, LINES / 2, 0,
|
||||
"Game time is over. Your game is being saved.\n\n");
|
||||
draw(cw);
|
||||
auto_save(); /* NO RETURN */
|
||||
}
|
||||
if (too_much()) {
|
||||
if (num_checks >= 3)
|
||||
fatal("You didn't listen, so now you are DEAD !!\n");
|
||||
checktime = CHECKTIME / (num_checks + 1);
|
||||
chmsg(msgs[num_checks++], checktime);
|
||||
alarm(checktime * 60);
|
||||
}
|
||||
else {
|
||||
if (num_checks) {
|
||||
chmsg("The load has dropped. You have a reprieve.");
|
||||
num_checks = 0;
|
||||
}
|
||||
alarm(CHECKTIME * 60);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* checkout()'s version of msg. If we are in the middle of a shell, do a
|
||||
* printf instead of a msg to avoid the refresh.
|
||||
*/
|
||||
chmsg(fmt, arg)
|
||||
char *fmt;
|
||||
int arg;
|
||||
{
|
||||
if (in_shell) {
|
||||
printf(fmt, arg);
|
||||
putchar('\n');
|
||||
fflush(stdout);
|
||||
}
|
||||
else
|
||||
msg(fmt, arg);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LOADAV
|
||||
|
||||
#include <nlist.h>
|
||||
|
||||
struct nlist avenrun =
|
||||
{
|
||||
"_avenrun"
|
||||
};
|
||||
|
||||
loadav(avg)
|
||||
reg double *avg;
|
||||
{
|
||||
reg int kmem;
|
||||
|
||||
if ((kmem = open("/dev/kmem", 0)) < 0)
|
||||
goto bad;
|
||||
nlist(NAMELIST, &avenrun);
|
||||
if (avenrun.n_type == 0) {
|
||||
bad:
|
||||
avg[0] = avg[1] = avg[2] = 0.0;
|
||||
return;
|
||||
}
|
||||
lseek(kmem, (long) avenrun.n_value, 0);
|
||||
read(kmem, avg, 3 * sizeof (double));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef UCOUNT
|
||||
/*
|
||||
* ucount:
|
||||
* Count the number of people on the system
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <utmp.h>
|
||||
struct utmp buf;
|
||||
ucount()
|
||||
{
|
||||
reg struct utmp *up;
|
||||
reg FILE *utmp;
|
||||
reg int count;
|
||||
|
||||
if ((utmp = fopen(UTMP, "r")) == NULL)
|
||||
return 0;
|
||||
|
||||
up = &buf;
|
||||
count = 0;
|
||||
while (fread(up, 1, sizeof (*up), utmp) > 0)
|
||||
if (buf.ut_type == USER_PROCESS)
|
||||
count++;
|
||||
fclose(utmp);
|
||||
return count;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* holiday:
|
||||
* Returns TRUE when it is a good time to play rogue
|
||||
*/
|
||||
holiday()
|
||||
{
|
||||
time_t now;
|
||||
struct tm *localtime();
|
||||
reg struct tm *ntime;
|
||||
|
||||
time(&now); /* get the current time */
|
||||
ntime = localtime(&now);
|
||||
if(ntime->tm_wday == 0 || ntime->tm_wday == 6)
|
||||
return TRUE; /* OK on Sat & Sun */
|
||||
if(ntime->tm_hour < 8 || ntime->tm_hour >= 17)
|
||||
return TRUE; /* OK before 8AM & after 5PM */
|
||||
if(ntime->tm_yday <= 7 || ntime->tm_yday >= 350)
|
||||
return TRUE; /* OK during Christmas */
|
||||
#if 0 /* not for now */
|
||||
if (access("/usr/tmp/.ryes",0) == 0)
|
||||
return TRUE; /* if author permission */
|
||||
#endif
|
||||
|
||||
return FALSE; /* All other times are bad */
|
||||
}
|
||||
369
arogue5/maze.c
Normal file
369
arogue5/maze.c
Normal file
|
|
@ -0,0 +1,369 @@
|
|||
/*
|
||||
* maze
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Super-Rogue"
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "curses.h"
|
||||
#include "rogue.h"
|
||||
|
||||
struct cell {
|
||||
char y_pos;
|
||||
char x_pos;
|
||||
};
|
||||
|
||||
struct bordercells {
|
||||
char num_pos; /* number of frontier cells next to you */
|
||||
struct cell conn[4]; /* the y,x position of above cell */
|
||||
} border_cells;
|
||||
|
||||
static char *frontier,
|
||||
*bits;
|
||||
static int maze_lines,
|
||||
maze_cols;
|
||||
char *moffset(),
|
||||
*foffset();
|
||||
|
||||
|
||||
/*
|
||||
* crankout:
|
||||
* Does actual drawing of maze to window
|
||||
*/
|
||||
crankout()
|
||||
{
|
||||
reg int x, y;
|
||||
|
||||
for (y = 0; y < LINES - 3; y++) {
|
||||
move(y + 1, 0);
|
||||
for (x = 0; x < COLS - 1; x++) {
|
||||
if (*moffset(y, x)) { /* here is a wall */
|
||||
if(y==0 || y==LINES-4) /* top or bottom line */
|
||||
addch('-');
|
||||
else if(x==0 || x==COLS-2) /* left | right side */
|
||||
addch('|');
|
||||
else if (y % 2 == 0 && x % 2 == 0) {
|
||||
if(*moffset(y, x-1) || *moffset(y, x+1))
|
||||
addch('-');
|
||||
else
|
||||
addch('|');
|
||||
}
|
||||
else if (y % 2 == 0)
|
||||
addch('-');
|
||||
else
|
||||
addch('|');
|
||||
}
|
||||
else
|
||||
addch(FLOOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* domaze:
|
||||
* Draw the maze on this level.
|
||||
*/
|
||||
do_maze()
|
||||
{
|
||||
reg int least;
|
||||
reg struct room *rp;
|
||||
reg struct linked_list *item;
|
||||
reg struct object *obj;
|
||||
int cnt;
|
||||
bool treas;
|
||||
coord tp;
|
||||
|
||||
for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) {
|
||||
rp->r_flags = ISGONE; /* kill all rooms */
|
||||
rp->r_fires = NULL; /* no fires */
|
||||
}
|
||||
rp = &rooms[0]; /* point to only room */
|
||||
rp->r_flags = ISDARK; /* mazes always dark */
|
||||
rp->r_pos.x = 0; /* room fills whole screen */
|
||||
rp->r_pos.y = 1;
|
||||
rp->r_max.x = COLS - 1;
|
||||
rp->r_max.y = LINES - 3;
|
||||
draw_maze(); /* put maze into window */
|
||||
/*
|
||||
* add some gold to make it worth looking for
|
||||
*/
|
||||
item = spec_item(GOLD, NULL, NULL, NULL);
|
||||
obj = OBJPTR(item);
|
||||
obj->o_count *= (rnd(10) + 1); /* add in one large hunk */
|
||||
attach(lvl_obj, item);
|
||||
cnt = 0;
|
||||
do {
|
||||
rnd_pos(rp, &tp);
|
||||
} until (mvinch(tp.y, tp.x) == FLOOR || cnt++ > 5000);
|
||||
mvaddch(tp.y, tp.x, GOLD);
|
||||
obj->o_pos = tp;
|
||||
/*
|
||||
* add in some food to make sure he has enough
|
||||
*/
|
||||
item = spec_item(FOOD, NULL, NULL, NULL);
|
||||
obj = OBJPTR(item);
|
||||
attach(lvl_obj, item);
|
||||
do {
|
||||
rnd_pos(rp, &tp);
|
||||
} until (mvinch(tp.y, tp.x) == FLOOR || cnt++ > 5000);
|
||||
mvaddch(tp.y, tp.x, FOOD);
|
||||
obj->o_pos = tp;
|
||||
if (rnd(100) < 10) { /* 10% for treasure maze */
|
||||
treas = TRUE;
|
||||
least = 6;
|
||||
debug("treasure maze");
|
||||
}
|
||||
else { /* normal maze level */
|
||||
least = 1;
|
||||
treas = FALSE;
|
||||
}
|
||||
genmonsters(least, treas);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* draw_maze:
|
||||
* Generate and draw the maze on the screen
|
||||
*/
|
||||
draw_maze()
|
||||
{
|
||||
reg int i, j, more;
|
||||
reg char *ptr;
|
||||
|
||||
maze_lines = (LINES - 3) / 2;
|
||||
maze_cols = (COLS - 1) / 2;
|
||||
bits = ALLOC((LINES - 3) * (COLS - 1));
|
||||
frontier = ALLOC(maze_lines * maze_cols);
|
||||
ptr = frontier;
|
||||
while (ptr < (frontier + (maze_lines * maze_cols)))
|
||||
*ptr++ = TRUE;
|
||||
for (i = 0; i < LINES - 3; i++) {
|
||||
for (j = 0; j < COLS - 1; j++) {
|
||||
if (i % 2 == 1 && j % 2 == 1)
|
||||
*moffset(i, j) = FALSE; /* floor */
|
||||
else
|
||||
*moffset(i, j) = TRUE; /* wall */
|
||||
}
|
||||
}
|
||||
for (i = 0; i < maze_lines; i++) {
|
||||
for (j = 0; j < maze_cols; j++) {
|
||||
do
|
||||
more = findcells(i,j);
|
||||
while(more != 0);
|
||||
}
|
||||
}
|
||||
crankout();
|
||||
FREE(frontier);
|
||||
FREE(bits);
|
||||
}
|
||||
|
||||
/*
|
||||
* findcells:
|
||||
* Figure out cells to open up
|
||||
*/
|
||||
findcells(y,x)
|
||||
reg int x, y;
|
||||
{
|
||||
reg int rtpos, i;
|
||||
|
||||
*foffset(y, x) = FALSE;
|
||||
border_cells.num_pos = 0;
|
||||
if (y < maze_lines - 1) { /* look below */
|
||||
if (*foffset(y + 1, x)) {
|
||||
border_cells.conn[border_cells.num_pos].y_pos = y + 1;
|
||||
border_cells.conn[border_cells.num_pos].x_pos = x;
|
||||
border_cells.num_pos += 1;
|
||||
}
|
||||
}
|
||||
if (y > 0) { /* look above */
|
||||
if (*foffset(y - 1, x)) {
|
||||
border_cells.conn[border_cells.num_pos].y_pos = y - 1;
|
||||
border_cells.conn[border_cells.num_pos].x_pos = x;
|
||||
border_cells.num_pos += 1;
|
||||
|
||||
}
|
||||
}
|
||||
if (x < maze_cols - 1) { /* look right */
|
||||
if (*foffset(y, x + 1)) {
|
||||
border_cells.conn[border_cells.num_pos].y_pos = y;
|
||||
border_cells.conn[border_cells.num_pos].x_pos = x + 1;
|
||||
border_cells.num_pos += 1;
|
||||
}
|
||||
}
|
||||
if (x > 0) { /* look left */
|
||||
if (*foffset(y, x - 1)) {
|
||||
border_cells.conn[border_cells.num_pos].y_pos = y;
|
||||
border_cells.conn[border_cells.num_pos].x_pos = x - 1;
|
||||
border_cells.num_pos += 1;
|
||||
|
||||
}
|
||||
}
|
||||
if (border_cells.num_pos == 0) /* no neighbors available */
|
||||
return 0;
|
||||
else {
|
||||
i = rnd(border_cells.num_pos);
|
||||
rtpos = border_cells.num_pos - 1;
|
||||
rmwall(border_cells.conn[i].y_pos, border_cells.conn[i].x_pos, y, x);
|
||||
return rtpos;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* foffset:
|
||||
* Calculate memory address for frontier
|
||||
*/
|
||||
char *
|
||||
foffset(y, x)
|
||||
int y, x;
|
||||
{
|
||||
|
||||
return (frontier + (y * maze_cols) + x);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Maze_view:
|
||||
* Returns true if the player can see the specified location within
|
||||
* the confines of a maze (within one column or row)
|
||||
*/
|
||||
|
||||
bool
|
||||
maze_view(y, x)
|
||||
int y, x;
|
||||
{
|
||||
register int start, goal, delta, ycheck = 0, xcheck = 0, absy, absx, see_radius;
|
||||
register bool row;
|
||||
char ch; /* What we are standing on (or near) */
|
||||
|
||||
/* Get the absolute value of y and x differences */
|
||||
absy = hero.y - y;
|
||||
absx = hero.x - x;
|
||||
if (absy < 0) absy = -absy;
|
||||
if (absx < 0) absx = -absx;
|
||||
|
||||
/* If we are standing in a wall, we can see a bit more */
|
||||
switch (ch = CCHAR( winat(hero.y, hero.x) )) {
|
||||
case '|':
|
||||
case '-':
|
||||
case WALL:
|
||||
case SECRETDOOR:
|
||||
case DOOR:
|
||||
see_radius = 2;
|
||||
otherwise:
|
||||
see_radius = 1;
|
||||
}
|
||||
|
||||
/* Must be within one or two rows or columns */
|
||||
if (absy > see_radius && absx > see_radius) return(FALSE);
|
||||
|
||||
if (absx > see_radius) { /* Go along row */
|
||||
start = hero.x;
|
||||
goal = x;
|
||||
ycheck = hero.y;
|
||||
row = TRUE;
|
||||
}
|
||||
else { /* Go along column */
|
||||
start = hero.y;
|
||||
goal = y;
|
||||
xcheck = hero.x;
|
||||
row = FALSE;
|
||||
}
|
||||
|
||||
if (start <= goal) delta = 1;
|
||||
else delta = -1;
|
||||
|
||||
/* Start one past where we are standing */
|
||||
if (start != goal) start += delta;
|
||||
|
||||
/* If we are in a wall, we want to look in the area outside the wall */
|
||||
if (see_radius > 1) {
|
||||
if (row) {
|
||||
/* See if above us it okay first */
|
||||
switch (winat(ycheck, start)) {
|
||||
case '|':
|
||||
case '-':
|
||||
case WALL:
|
||||
case DOOR:
|
||||
case SECRETDOOR:
|
||||
/* No good, try one up */
|
||||
if (y > hero.y) ycheck++;
|
||||
else ycheck--;
|
||||
otherwise:
|
||||
see_radius = 1; /* Just look straight over the row */
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* See if above us it okay first */
|
||||
switch (winat(start, xcheck)) {
|
||||
case '|':
|
||||
case '-':
|
||||
case WALL:
|
||||
case DOOR:
|
||||
case SECRETDOOR:
|
||||
/* No good, try one over */
|
||||
if (x > hero.x) xcheck++;
|
||||
else xcheck--;
|
||||
otherwise:
|
||||
see_radius = 1; /* Just look straight up the column */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check boundary again */
|
||||
if (absy > see_radius && absx > see_radius) return(FALSE);
|
||||
|
||||
while (start != goal) {
|
||||
if (row) xcheck = start;
|
||||
else ycheck = start;
|
||||
switch (winat(ycheck, xcheck)) {
|
||||
case '|':
|
||||
case '-':
|
||||
case WALL:
|
||||
case DOOR:
|
||||
case SECRETDOOR:
|
||||
return(FALSE);
|
||||
}
|
||||
start += delta;
|
||||
}
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* moffset:
|
||||
* Calculate memory address for bits
|
||||
*/
|
||||
char *
|
||||
moffset(y, x)
|
||||
int y, x;
|
||||
{
|
||||
|
||||
return (bits + (y * (COLS - 1)) + x);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* rmwall:
|
||||
* Removes appropriate walls from the maze
|
||||
*/
|
||||
rmwall(newy, newx, oldy, oldx)
|
||||
int newy, newx, oldy, oldx;
|
||||
{
|
||||
reg int xdif,ydif;
|
||||
|
||||
xdif = newx - oldx;
|
||||
ydif = newy - oldy;
|
||||
|
||||
*moffset((oldy * 2) + ydif + 1, (oldx * 2) + xdif + 1) = FALSE;
|
||||
findcells(newy, newx);
|
||||
}
|
||||
1194
arogue5/mdport.c
Normal file
1194
arogue5/mdport.c
Normal file
File diff suppressed because it is too large
Load diff
736
arogue5/misc.c
Normal file
736
arogue5/misc.c
Normal file
|
|
@ -0,0 +1,736 @@
|
|||
/*
|
||||
* routines dealing specifically with miscellaneous magic
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "curses.h"
|
||||
#include <ctype.h>
|
||||
#include "rogue.h"
|
||||
|
||||
/*
|
||||
* See if a monster has some magic it can use. Use it and return TRUE if so.
|
||||
*/
|
||||
bool
|
||||
m_use_item(monster, monst_pos, defend_pos)
|
||||
register struct thing *monster;
|
||||
register coord *monst_pos, *defend_pos;
|
||||
{
|
||||
register struct linked_list *pitem;
|
||||
register struct object *obj;
|
||||
register coord *shoot_dir = can_shoot(monst_pos, defend_pos);
|
||||
int dist=DISTANCE(monst_pos->y, monst_pos->x, defend_pos->y, defend_pos->x);
|
||||
|
||||
for (pitem=monster->t_pack; pitem; pitem=next(pitem)) {
|
||||
obj = OBJPTR(pitem);
|
||||
if (obj->o_type != RELIC) continue; /* Only care about relics now */
|
||||
switch (obj->o_which) {
|
||||
case MING_STAFF: {
|
||||
static struct object missile = {
|
||||
MISSILE, {0,0}, "", 0, "", "0d4 " , NULL, 0, WS_MISSILE, 100, 1
|
||||
};
|
||||
|
||||
if (shoot_dir != NULL) {
|
||||
sprintf(missile.o_hurldmg, "%dd4", monster->t_stats.s_lvl);
|
||||
do_motion(&missile, shoot_dir->y, shoot_dir->x, monster);
|
||||
hit_monster(unc(missile.o_pos), &missile, monster);
|
||||
return(TRUE);
|
||||
}
|
||||
}
|
||||
when ASMO_ROD:
|
||||
/* The bolt must be able to reach the defendant */
|
||||
if (shoot_dir != NULL && dist < BOLT_LENGTH * BOLT_LENGTH) {
|
||||
char *name;
|
||||
|
||||
switch (rnd(3)) { /* Select a function */
|
||||
case 0: name = "lightning bolt";
|
||||
when 1: name = "flame";
|
||||
otherwise: name = "ice";
|
||||
}
|
||||
shoot_bolt( monster,
|
||||
*monst_pos,
|
||||
*shoot_dir,
|
||||
FALSE,
|
||||
monster->t_index,
|
||||
name,
|
||||
roll(monster->t_stats.s_lvl,6));
|
||||
return(TRUE);
|
||||
}
|
||||
when BRIAN_MANDOLIN:
|
||||
/* The defendant must be the player and within 2 spaces */
|
||||
if (ce(*defend_pos, hero) && dist < 9 && no_command == 0 &&
|
||||
rnd(100) < 33) {
|
||||
if (!save(VS_MAGIC, &player, -4) &&
|
||||
!ISWEARING(R_ALERT)) {
|
||||
msg("Some beautiful music enthralls you.");
|
||||
no_command += FREEZETIME;
|
||||
}
|
||||
else msg("You wince at a sour note.");
|
||||
return(TRUE);
|
||||
}
|
||||
when GERYON_HORN:
|
||||
/* The defendant must be the player and within 2 spaces */
|
||||
if (ce(*defend_pos, hero) && dist < 9 &&
|
||||
(off(player, ISFLEE) || player.t_dest != &monster->t_pos)
|
||||
&& rnd(100) < 33) {
|
||||
if (!ISWEARING(R_HEROISM) &&
|
||||
!save(VS_MAGIC, &player, -4)) {
|
||||
turn_on(player, ISFLEE);
|
||||
player.t_dest = &monster->t_pos;
|
||||
msg("A shrill blast terrifies you.");
|
||||
}
|
||||
else msg("A shrill blast sends chills up your spine.");
|
||||
return(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* add something to the contents of something else
|
||||
*/
|
||||
put_contents(bag, item)
|
||||
register struct object *bag; /* the holder of the items */
|
||||
register struct linked_list *item; /* the item to put inside */
|
||||
{
|
||||
register struct linked_list *titem;
|
||||
register struct object *tobj;
|
||||
|
||||
bag->o_ac++;
|
||||
tobj = OBJPTR(item);
|
||||
for (titem = bag->contents; titem != NULL; titem = next(titem)) {
|
||||
if ((OBJPTR(titem))->o_which == tobj->o_which)
|
||||
break;
|
||||
}
|
||||
if (titem == NULL) { /* if not a duplicate put at beginning */
|
||||
attach(bag->contents, item);
|
||||
}
|
||||
else {
|
||||
item->l_prev = titem;
|
||||
item->l_next = titem->l_next;
|
||||
if (next(titem) != NULL)
|
||||
(titem->l_next)->l_prev = item;
|
||||
titem->l_next = item;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* remove something from something else
|
||||
*/
|
||||
take_contents(bag, item)
|
||||
register struct object *bag; /* the holder of the items */
|
||||
register struct linked_list *item;
|
||||
{
|
||||
|
||||
if (bag->o_ac <= 0) {
|
||||
msg("Nothing to take out");
|
||||
return;
|
||||
}
|
||||
bag->o_ac--;
|
||||
detach(bag->contents, item);
|
||||
if (!add_pack(item, FALSE, NULL))
|
||||
put_contents(bag, item);
|
||||
}
|
||||
|
||||
|
||||
do_bag(item)
|
||||
register struct linked_list *item;
|
||||
{
|
||||
|
||||
register struct linked_list *titem = NULL;
|
||||
register struct object *obj;
|
||||
bool doit = TRUE;
|
||||
|
||||
obj = OBJPTR(item);
|
||||
while (doit) {
|
||||
msg("What do you want to do? (* for a list): ");
|
||||
mpos = 0;
|
||||
switch (readchar()) {
|
||||
case EOF:
|
||||
case ESCAPE:
|
||||
msg ("");
|
||||
doit = FALSE;
|
||||
when '1':
|
||||
inventory(obj->contents, ALL);
|
||||
|
||||
when '2':
|
||||
if (obj->o_ac >= MAXCONTENTS) {
|
||||
msg("the %s is full", m_magic[obj->o_which].mi_name);
|
||||
break;
|
||||
}
|
||||
switch (obj->o_which) {
|
||||
case MM_BEAKER: titem = get_item(pack, "put in", POTION);
|
||||
when MM_BOOK: titem = get_item(pack, "put in", SCROLL);
|
||||
}
|
||||
if (titem == NULL)
|
||||
break;
|
||||
detach(pack, titem);
|
||||
inpack--;
|
||||
put_contents(obj, titem);
|
||||
|
||||
when '3':
|
||||
titem = get_item(obj->contents,"take out",ALL);
|
||||
if (titem == NULL)
|
||||
break;
|
||||
take_contents(obj, titem);
|
||||
|
||||
when '4':
|
||||
switch (obj->o_which) {
|
||||
case MM_BEAKER:
|
||||
titem = get_item(obj->contents,"quaff",ALL);
|
||||
if (titem == NULL)
|
||||
break;
|
||||
obj->o_ac--;
|
||||
detach(obj->contents, titem);
|
||||
quaff((OBJPTR(titem))->o_which,
|
||||
(OBJPTR(titem))->o_flags & (ISCURSED | ISBLESSED),
|
||||
TRUE);
|
||||
o_discard(titem);
|
||||
when MM_BOOK:
|
||||
if (on(player, ISBLIND)) {
|
||||
msg("You can't see to read anything");
|
||||
break;
|
||||
}
|
||||
titem = get_item(obj->contents,"read",ALL);
|
||||
if (titem == NULL)
|
||||
break;
|
||||
obj->o_ac--;
|
||||
detach(obj->contents, titem);
|
||||
read_scroll((OBJPTR(titem))->o_which,
|
||||
(OBJPTR(titem))->o_flags & (ISCURSED|ISBLESSED),
|
||||
TRUE);
|
||||
o_discard(titem);
|
||||
}
|
||||
doit = FALSE;
|
||||
|
||||
otherwise:
|
||||
wclear(hw);
|
||||
touchwin(hw);
|
||||
mvwaddstr(hw,0,0,"The following operations are available:");
|
||||
mvwaddstr(hw,2,0,"[1]\tInventory\n");
|
||||
wprintw(hw,"[2]\tPut something in the %s\n",
|
||||
m_magic[obj->o_which].mi_name);
|
||||
wprintw(hw,"[3]\tTake something out of the %s\n",
|
||||
m_magic[obj->o_which].mi_name);
|
||||
switch(obj->o_which) {
|
||||
case MM_BEAKER: waddstr(hw,"[4]\tQuaff a potion\n");
|
||||
when MM_BOOK: waddstr(hw,"[4]\tRead a scroll\n");
|
||||
}
|
||||
waddstr(hw,"[ESC]\tLeave this menu\n");
|
||||
mvwaddstr(hw, LINES-1, 0, spacemsg);
|
||||
draw(hw);
|
||||
wait_for (hw,' ');
|
||||
clearok(cw, TRUE);
|
||||
touchwin(cw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
do_panic()
|
||||
{
|
||||
register int x,y;
|
||||
register struct linked_list *mon;
|
||||
register struct thing *th;
|
||||
|
||||
for (x = hero.x-2; x <= hero.x+2; x++) {
|
||||
for (y = hero.y-2; y <= hero.y+2; y++) {
|
||||
if (y < 1 || x < 0 || y > LINES - 3 || x > COLS - 1)
|
||||
continue;
|
||||
if (isalpha(mvwinch(mw, y, x))) {
|
||||
if ((mon = find_mons(y, x)) != NULL) {
|
||||
th = THINGPTR(mon);
|
||||
if (!on(*th, ISUNDEAD) && !save(VS_MAGIC, th, 0)) {
|
||||
turn_on(*th, ISFLEE);
|
||||
turn_on(*th, WASTURNED);
|
||||
|
||||
/* If monster was suffocating, stop it */
|
||||
if (on(*th, DIDSUFFOCATE)) {
|
||||
turn_off(*th, DIDSUFFOCATE);
|
||||
extinguish(suffocate);
|
||||
}
|
||||
|
||||
/* If monster held us, stop it */
|
||||
if (on(*th, DIDHOLD) && (--hold_count == 0))
|
||||
turn_off(player, ISHELD);
|
||||
turn_off(*th, DIDHOLD);
|
||||
}
|
||||
runto(th, &hero);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* print miscellaneous magic bonuses
|
||||
*/
|
||||
char *
|
||||
misc_name(obj)
|
||||
register struct object *obj;
|
||||
{
|
||||
static char buf[LINELEN];
|
||||
char buf1[LINELEN];
|
||||
|
||||
buf[0] = '\0';
|
||||
buf1[0] = '\0';
|
||||
if (!(obj->o_flags & ISKNOW))
|
||||
return (m_magic[obj->o_which].mi_name);
|
||||
switch (obj->o_which) {
|
||||
case MM_BRACERS:
|
||||
case MM_PROTECT:
|
||||
strcat(buf, num(obj->o_ac, 0));
|
||||
strcat(buf, " ");
|
||||
}
|
||||
switch (obj->o_which) {
|
||||
case MM_G_OGRE:
|
||||
case MM_G_DEXTERITY:
|
||||
case MM_JEWEL:
|
||||
case MM_STRANGLE:
|
||||
case MM_R_POWERLESS:
|
||||
case MM_DANCE:
|
||||
if (obj->o_flags & ISCURSED)
|
||||
strcat(buf, "cursed ");
|
||||
}
|
||||
strcat(buf, m_magic[obj->o_which].mi_name);
|
||||
switch (obj->o_which) {
|
||||
case MM_JUG:
|
||||
if (obj->o_ac == JUG_EMPTY)
|
||||
strcat(buf1, " [empty]");
|
||||
else if (p_know[obj->o_ac])
|
||||
sprintf(buf1, " [containing a potion of %s (%s)]",
|
||||
p_magic[obj->o_ac].mi_name,
|
||||
p_colors[obj->o_ac]);
|
||||
else sprintf(buf1, " [containing a%s %s liquid]",
|
||||
vowelstr(p_colors[obj->o_ac]),
|
||||
p_colors[obj->o_ac]);
|
||||
when MM_BEAKER:
|
||||
case MM_BOOK: {
|
||||
sprintf(buf1, " [containing %d]", obj->o_ac);
|
||||
}
|
||||
when MM_OPEN:
|
||||
case MM_HUNGER:
|
||||
sprintf(buf1, " [%d ring%s]", obj->o_charges,
|
||||
obj->o_charges == 1 ? "" : "s");
|
||||
when MM_DRUMS:
|
||||
sprintf(buf1, " [%d beat%s]", obj->o_charges,
|
||||
obj->o_charges == 1 ? "" : "s");
|
||||
when MM_DISAPPEAR:
|
||||
case MM_CHOKE:
|
||||
sprintf(buf1, " [%d pinch%s]", obj->o_charges,
|
||||
obj->o_charges == 1 ? "" : "es");
|
||||
when MM_KEOGHTOM:
|
||||
sprintf(buf1, " [%d application%s]", obj->o_charges,
|
||||
obj->o_charges == 1 ? "" : "s");
|
||||
when MM_SKILLS:
|
||||
switch (obj->o_ac) {
|
||||
case C_MAGICIAN: strcpy(buf1, " [magic user]");
|
||||
when C_FIGHTER: strcpy(buf1, " [fighter]");
|
||||
when C_CLERIC: strcpy(buf1, " [cleric]");
|
||||
when C_THIEF: strcpy(buf1, " [thief]");
|
||||
}
|
||||
}
|
||||
strcat (buf, buf1);
|
||||
return buf;
|
||||
}
|
||||
|
||||
use_emori()
|
||||
{
|
||||
char selection; /* Cloak function */
|
||||
int state = 0; /* Menu state */
|
||||
|
||||
msg("What do you want to do? (* for a list): ");
|
||||
do {
|
||||
selection = tolower(readchar());
|
||||
switch (selection) {
|
||||
case '*':
|
||||
if (state != 1) {
|
||||
wclear(hw);
|
||||
touchwin(hw);
|
||||
mvwaddstr(hw, 2, 0, "[1] Fly\n[2] Stop flying\n");
|
||||
waddstr(hw, "[3] Turn invisible\n[4] Turn Visible\n");
|
||||
mvwaddstr(hw, 0, 0, "What do you want to do? ");
|
||||
draw(hw);
|
||||
state = 1; /* Now in prompt window */
|
||||
}
|
||||
break;
|
||||
|
||||
case ESCAPE:
|
||||
if (state == 1) {
|
||||
clearok(cw, TRUE); /* Set up for redraw */
|
||||
touchwin(cw);
|
||||
}
|
||||
msg("");
|
||||
|
||||
after = FALSE;
|
||||
return;
|
||||
|
||||
when '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
if (state == 1) { /* In prompt window */
|
||||
clearok(cw, TRUE); /* Set up for redraw */
|
||||
touchwin(cw);
|
||||
}
|
||||
|
||||
msg("");
|
||||
|
||||
state = 2; /* Finished */
|
||||
break;
|
||||
|
||||
default:
|
||||
if (state == 1) { /* In the prompt window */
|
||||
mvwaddstr(hw, 0, 0,
|
||||
"Please enter a selection between 1 and 4: ");
|
||||
draw(hw);
|
||||
}
|
||||
else { /* Normal window */
|
||||
mpos = 0;
|
||||
msg("Please enter a selection between 1 and 4: ");
|
||||
}
|
||||
}
|
||||
} while (state != 2);
|
||||
|
||||
/* We now must have a selection between 1 and 4 */
|
||||
switch (selection) {
|
||||
case '1': /* Fly */
|
||||
if (on(player, ISFLY)) {
|
||||
extinguish(land); /* Extinguish in case of potion */
|
||||
msg("%slready flying.", terse ? "A" : "You are a");
|
||||
}
|
||||
else {
|
||||
msg("You feel lighter than air!");
|
||||
turn_on(player, ISFLY);
|
||||
}
|
||||
when '2': /* Stop flying */
|
||||
if (off(player, ISFLY))
|
||||
msg("%sot flying.", terse ? "N" : "You are n");
|
||||
else {
|
||||
if (find_slot(land))
|
||||
msg("%sot flying by the cloak.",
|
||||
terse ? "N" : "You are n");
|
||||
else land();
|
||||
}
|
||||
when '3': /* Turn invisible */
|
||||
if (off(player, ISINVIS)) {
|
||||
turn_on(player, ISINVIS);
|
||||
msg("You have a tingling feeling all over your body");
|
||||
PLAYER = IPLAYER;
|
||||
light(&hero);
|
||||
}
|
||||
else {
|
||||
extinguish(appear); /* Extinguish in case of potion */
|
||||
extinguish(dust_appear);/* dust of disappearance */
|
||||
msg("%slready invisible.", terse ? "A" : "You are a");
|
||||
}
|
||||
when '4': /* Turn visible */
|
||||
if (off(player, ISINVIS))
|
||||
msg("%sot invisible.", terse ? "N" : "You are n");
|
||||
else {
|
||||
if (find_slot(appear) || find_slot(dust_appear))
|
||||
msg("%sot invisible by the cloak.",
|
||||
terse ? "N" : "You are n");
|
||||
else appear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
use_mm(which)
|
||||
int which;
|
||||
{
|
||||
register struct object *obj = NULL;
|
||||
register struct linked_list *item = NULL;
|
||||
bool cursed, blessed, is_mm;
|
||||
char buf[LINELEN];
|
||||
|
||||
cursed = FALSE;
|
||||
is_mm = FALSE;
|
||||
|
||||
if (which < 0) { /* A real miscellaneous magic item */
|
||||
is_mm = TRUE;
|
||||
item = get_item(pack, "use", USEABLE);
|
||||
/*
|
||||
* Make certain that it is a micellaneous magic item
|
||||
*/
|
||||
if (item == NULL)
|
||||
return;
|
||||
|
||||
obj = OBJPTR(item);
|
||||
cursed = (obj->o_flags & ISCURSED) != 0;
|
||||
blessed = (obj->o_flags & ISBLESSED) != 0;
|
||||
which = obj->o_which;
|
||||
}
|
||||
|
||||
if (obj->o_type == RELIC) { /* An artifact */
|
||||
is_mm = FALSE;
|
||||
switch (obj->o_which) {
|
||||
case EMORI_CLOAK:
|
||||
use_emori();
|
||||
when BRIAN_MANDOLIN:
|
||||
/* Put monsters around us to sleep */
|
||||
read_scroll(S_HOLD, 0, FALSE);
|
||||
when GERYON_HORN:
|
||||
/* Chase close monsters away */
|
||||
msg("The horn blasts a shrill tone.");
|
||||
do_panic();
|
||||
when HEIL_ANKH:
|
||||
case YENDOR_AMULET:
|
||||
/* Nothing happens by this mode */
|
||||
msg("Nothing happens.");
|
||||
}
|
||||
}
|
||||
else switch (which) { /* Miscellaneous Magic */
|
||||
/*
|
||||
* the jug of alchemy manufactures potions when you drink
|
||||
* the potion it will make another after a while
|
||||
*/
|
||||
case MM_JUG:
|
||||
if (obj->o_ac == JUG_EMPTY) {
|
||||
msg("The jug is empty");
|
||||
break;
|
||||
}
|
||||
quaff (obj->o_ac, NULL, FALSE);
|
||||
obj->o_ac = JUG_EMPTY;
|
||||
fuse (alchemy, obj, ALCHEMYTIME, AFTER);
|
||||
if (!(obj->o_flags & ISKNOW))
|
||||
whatis(item);
|
||||
|
||||
/*
|
||||
* the beaker of plentiful potions is used to hold potions
|
||||
* the book of infinite spells is used to hold scrolls
|
||||
*/
|
||||
when MM_BEAKER:
|
||||
case MM_BOOK:
|
||||
do_bag(item);
|
||||
|
||||
/*
|
||||
* the chime of opening opens up secret doors
|
||||
*/
|
||||
when MM_OPEN:
|
||||
{
|
||||
register struct linked_list *exit;
|
||||
register struct room *rp;
|
||||
register coord *cp;
|
||||
|
||||
if (obj->o_charges <= 0) {
|
||||
msg("The chime is cracked!");
|
||||
break;
|
||||
}
|
||||
obj->o_charges--;
|
||||
msg("chime... chime... hime... ime... me... e...");
|
||||
if ((rp = roomin(&hero)) == NULL) {
|
||||
search(FALSE, TRUE); /* Non-failing search for door */
|
||||
break;
|
||||
}
|
||||
for (exit = rp->r_exit; exit != NULL; exit = next(exit)) {
|
||||
cp = DOORPTR(exit);
|
||||
if (winat(cp->y, cp->x) == SECRETDOOR) {
|
||||
mvaddch (cp->y, cp->x, DOOR);
|
||||
if (cansee (cp->y, cp->x))
|
||||
mvwaddch(cw, cp->y, cp->x, DOOR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* the chime of hunger just makes the hero hungry
|
||||
*/
|
||||
when MM_HUNGER:
|
||||
if (obj->o_charges <= 0) {
|
||||
msg("The chime is cracked!");
|
||||
break;
|
||||
}
|
||||
obj->o_charges--;
|
||||
food_left = MORETIME + 5;
|
||||
msg(terse ? "Getting hungry" : "You are starting to get hungry");
|
||||
hungry_state = F_HUNGRY;
|
||||
aggravate();
|
||||
|
||||
/*
|
||||
* the drums of panic make all creatures within two squares run
|
||||
* from the hero in panic unless they save or they are mindless
|
||||
* undead
|
||||
*/
|
||||
when MM_DRUMS:
|
||||
if (obj->o_charges <= 0) {
|
||||
msg("The drum is broken!");
|
||||
break;
|
||||
}
|
||||
obj->o_charges--;
|
||||
/*
|
||||
* dust of disappearance makes the player invisible for a while
|
||||
*/
|
||||
when MM_DISAPPEAR:
|
||||
m_know[MM_DISAPPEAR] = TRUE;
|
||||
if (obj->o_charges <= 0) {
|
||||
msg("No more dust!");
|
||||
break;
|
||||
}
|
||||
obj->o_charges--;
|
||||
msg("aaAAACHOOOooo. Cough. Cough. Sneeze. Sneeze.");
|
||||
if (!find_slot(dust_appear)) {
|
||||
turn_on(player, ISINVIS);
|
||||
fuse(dust_appear, 0, DUSTTIME, AFTER);
|
||||
PLAYER = IPLAYER;
|
||||
light(&hero);
|
||||
}
|
||||
else lengthen(dust_appear, DUSTTIME);
|
||||
|
||||
/*
|
||||
* dust of choking and sneezing can kill the hero if he misses
|
||||
* the save
|
||||
*/
|
||||
when MM_CHOKE:
|
||||
m_know[MM_CHOKE] = TRUE;
|
||||
if (obj->o_charges <= 0) {
|
||||
msg("No more dust!");
|
||||
break;
|
||||
}
|
||||
obj->o_charges--;
|
||||
msg("aaAAACHOOOooo. Cough. Cough. Sneeze. Sneeze.");
|
||||
if (!save(VS_POISON, &player, 0)) {
|
||||
msg ("You choke to death!!! --More--");
|
||||
pstats.s_hpt = -1; /* in case he hangs up the phone */
|
||||
wait_for(cw,' ');
|
||||
death(D_CHOKE);
|
||||
}
|
||||
else {
|
||||
msg("You begin to cough and choke uncontrollably");
|
||||
if (find_slot(unchoke))
|
||||
lengthen(unchoke, DUSTTIME);
|
||||
else
|
||||
fuse(unchoke, 0, DUSTTIME, AFTER);
|
||||
turn_on(player, ISHUH);
|
||||
turn_on(player, ISBLIND);
|
||||
light(&hero);
|
||||
}
|
||||
|
||||
when MM_KEOGHTOM:
|
||||
/*
|
||||
* this is a very powerful healing ointment
|
||||
* but it takes a while to put on...
|
||||
*/
|
||||
if (obj->o_charges <= 0) {
|
||||
msg("The jar is empty!");
|
||||
break;
|
||||
}
|
||||
obj->o_charges--;
|
||||
waste_time();
|
||||
if (on(player, HASDISEASE)) {
|
||||
extinguish(cure_disease);
|
||||
cure_disease();
|
||||
msg(terse ? "You feel yourself improving."
|
||||
: "You begin to feel yourself improving again.");
|
||||
}
|
||||
if (on(player, HASINFEST)) {
|
||||
turn_off(player, HASINFEST);
|
||||
infest_dam = 0;
|
||||
msg(terse ? "You feel yourself improving."
|
||||
: "You begin to feel yourself improving again.");
|
||||
}
|
||||
if (on(player, DOROT)) {
|
||||
msg("You feel your skin returning to normal.");
|
||||
turn_off(player, DOROT);
|
||||
}
|
||||
pstats.s_hpt += roll(pstats.s_lvl, 6);
|
||||
if (pstats.s_hpt > max_stats.s_hpt)
|
||||
pstats.s_hpt = max_stats.s_hpt;
|
||||
sight();
|
||||
msg("You begin to feel much better.");
|
||||
|
||||
/*
|
||||
* The book has a character class associated with it.
|
||||
* if your class matches that of the book, it will raise your
|
||||
* level by one. If your class does not match the one of the book,
|
||||
* it change your class to that of book.
|
||||
* Note that it takes a while to read.
|
||||
*/
|
||||
when MM_SKILLS:
|
||||
detach (pack, item);
|
||||
inpack--;
|
||||
waste_time();
|
||||
waste_time();
|
||||
waste_time();
|
||||
waste_time();
|
||||
waste_time();
|
||||
if (obj->o_ac == player.t_ctype) {
|
||||
msg("You feel more skillful");
|
||||
raise_level(TRUE);
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* reset his class and then use check_level to reset hit
|
||||
* points and the right level for his exp pts
|
||||
* drop exp pts by 10%
|
||||
*/
|
||||
long save;
|
||||
|
||||
msg("You feel like a whole new person!");
|
||||
/*
|
||||
* if he becomes a thief he has to have leather armor
|
||||
*/
|
||||
if (obj->o_ac == C_THIEF &&
|
||||
cur_armor != NULL &&
|
||||
cur_armor->o_which != LEATHER &&
|
||||
cur_armor->o_which != STUDDED_LEATHER )
|
||||
cur_armor->o_which = STUDDED_LEATHER;
|
||||
/*
|
||||
* if he's changing from a fighter then may have to change
|
||||
* his sword since only fighter can use two-handed
|
||||
* and bastard swords
|
||||
*/
|
||||
if (player.t_ctype == C_FIGHTER &&
|
||||
cur_weapon != NULL &&
|
||||
cur_weapon->o_type == WEAPON &&
|
||||
(cur_weapon->o_which== BASWORD ||
|
||||
cur_weapon->o_which== TWOSWORD ))
|
||||
cur_weapon->o_which = SWORD;
|
||||
|
||||
/*
|
||||
* if he was a thief then take out the trap_look() daemon
|
||||
*/
|
||||
if (player.t_ctype == C_THIEF)
|
||||
kill_daemon(trap_look);
|
||||
/*
|
||||
* if he becomes a thief then add the trap_look() daemon
|
||||
*/
|
||||
if (obj->o_ac == C_THIEF)
|
||||
daemon(trap_look, 0, AFTER);
|
||||
char_type = player.t_ctype = obj->o_ac;
|
||||
save = pstats.s_hpt;
|
||||
max_stats.s_hpt = pstats.s_hpt = 0;
|
||||
max_stats.s_lvl = pstats.s_lvl = 0;
|
||||
max_stats.s_exp = pstats.s_exp -= pstats.s_exp/10;
|
||||
check_level(TRUE);
|
||||
if (pstats.s_hpt > save) /* don't add to current hits */
|
||||
pstats.s_hpt = save;
|
||||
}
|
||||
|
||||
otherwise:
|
||||
msg("What a strange magic item you have!");
|
||||
}
|
||||
status(FALSE);
|
||||
if (is_mm && m_know[which] && m_guess[which]) {
|
||||
free(m_guess[which]);
|
||||
m_guess[which] = NULL;
|
||||
}
|
||||
else if (is_mm &&
|
||||
!m_know[which] &&
|
||||
askme &&
|
||||
(obj->o_flags & ISKNOW) == 0 &&
|
||||
m_guess[which] == NULL) {
|
||||
msg(terse ? "Call it: " : "What do you want to call it? ");
|
||||
if (get_str(buf, cw) == NORM) {
|
||||
m_guess[which] = new((unsigned int) strlen(buf) + 1);
|
||||
strcpy(m_guess[which], buf);
|
||||
}
|
||||
}
|
||||
if (item != NULL && which == MM_SKILLS)
|
||||
o_discard(item);
|
||||
updpack(TRUE);
|
||||
}
|
||||
1034
arogue5/monsters.c
Normal file
1034
arogue5/monsters.c
Normal file
File diff suppressed because it is too large
Load diff
1386
arogue5/move.c
Normal file
1386
arogue5/move.c
Normal file
File diff suppressed because it is too large
Load diff
21
arogue5/network.h
Normal file
21
arogue5/network.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Networking information -- should not vary among networking machines
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#define SYSLEN 9
|
||||
#define LOGLEN 8
|
||||
#define NUMNET 6
|
||||
#undef NUMNET
|
||||
struct network {
|
||||
char *system;
|
||||
char *rogue;
|
||||
};
|
||||
extern struct network Network[];
|
||||
|
||||
/* This system's name -- should not be defined if uname() is available */
|
||||
579
arogue5/new_level.c
Normal file
579
arogue5/new_level.c
Normal file
|
|
@ -0,0 +1,579 @@
|
|||
/*
|
||||
* new_level: Dig and draw a new level
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "curses.h"
|
||||
#include "rogue.h"
|
||||
#define TERRASAVE 3
|
||||
|
||||
new_level(ltype)
|
||||
LEVTYPE ltype; /* designates type of level to create */
|
||||
{
|
||||
register int rm = 0, i, cnt;
|
||||
register char ch;
|
||||
register struct linked_list *item;
|
||||
register struct thing *tp;
|
||||
register struct object *obj;
|
||||
int waslit = 0; /* Was the previous outside level lit? */
|
||||
int starty = 0, startx = 0, deltay = 0, deltax = 0;
|
||||
bool fresh=TRUE, vert = 0, top;
|
||||
struct room *rp;
|
||||
struct linked_list *nitem, *savmonst=NULL, *savitems=NULL;
|
||||
coord stairs = { 0, 0 };
|
||||
|
||||
if (wizard) {
|
||||
msg("Turns: %d", turns); /* Number of turns for last level */
|
||||
mpos = 0;
|
||||
}
|
||||
|
||||
/* Start player off right */
|
||||
turn_off(player, ISHELD);
|
||||
turn_off(player, ISFLEE);
|
||||
extinguish(suffocate);
|
||||
hold_count = 0;
|
||||
trap_tries = 0;
|
||||
|
||||
/* Are we just entering a dungeon? If so, how big is it? */
|
||||
if (ltype != OUTSIDE && nfloors < 0) nfloors = HARDER+10 + rnd(11);
|
||||
|
||||
if (level > max_level)
|
||||
max_level = level;
|
||||
|
||||
/* Are we starting a new outside level? */
|
||||
if (ltype == OUTSIDE) {
|
||||
register int i, j;
|
||||
|
||||
/* Save some information prior to clearing the screen */
|
||||
if (level == -1 || mvinch(hero.y, hero.x) == '-') vert = TRUE;
|
||||
else vert = FALSE;
|
||||
|
||||
if (level == -1) {
|
||||
fresh = TRUE;
|
||||
starty = 2;
|
||||
startx = 1;
|
||||
deltay = deltax = 1;
|
||||
level = 0; /* Restore the level */
|
||||
}
|
||||
else { /* Copy several lines of the terrain to the other end */
|
||||
char cch; /* Copy character */
|
||||
|
||||
/* Was the area dark (not magically lit)? */
|
||||
if (!(rooms[0].r_flags & ISDARK)) waslit = 1;
|
||||
|
||||
fresh = FALSE;
|
||||
if ((vert && hero.y == 1) || (!vert && hero.x == 0)) top = TRUE;
|
||||
else top = FALSE;
|
||||
for (i=0; i<TERRASAVE; i++) {
|
||||
if (vert)
|
||||
for (j=1; j<COLS-1; j++) {
|
||||
if (top) {
|
||||
cch = CCHAR( mvinch(i+2, j) );
|
||||
mvaddch(LINES-6+i, j, cch);
|
||||
}
|
||||
else {
|
||||
cch = CCHAR( mvinch(LINES-4-i, j) );
|
||||
mvaddch(4-i, j, cch);
|
||||
}
|
||||
}
|
||||
else
|
||||
for (j=2; j<LINES-3; j++) {
|
||||
if (top) {
|
||||
cch = CCHAR( mvinch(j, i+1) );
|
||||
mvaddch(j, COLS-4+i, cch);
|
||||
}
|
||||
else {
|
||||
cch = CCHAR( mvinch(j, COLS-2-i) );
|
||||
mvaddch(j, 3-i, cch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vert) {
|
||||
startx = deltax = 1;
|
||||
if (top) {
|
||||
starty = LINES-4-TERRASAVE;
|
||||
deltay = -1;
|
||||
}
|
||||
else {
|
||||
starty = TERRASAVE + 2;
|
||||
deltay = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
starty = 2;
|
||||
deltay = 1;
|
||||
if (top) {
|
||||
startx = COLS-2-TERRASAVE;
|
||||
deltax = -1;
|
||||
}
|
||||
else {
|
||||
deltax = 1;
|
||||
startx = TERRASAVE + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if any monsters should be saved */
|
||||
for (item = mlist; item != NULL; item = nitem) {
|
||||
nitem = next(item);
|
||||
tp = THINGPTR(item);
|
||||
if (vert) {
|
||||
if (top) {
|
||||
if (tp->t_pos.y < TERRASAVE + 2)
|
||||
tp->t_pos.y += LINES - 5 - TERRASAVE;
|
||||
else continue;
|
||||
}
|
||||
else {
|
||||
if (tp->t_pos.y > LINES - 4 - TERRASAVE)
|
||||
tp->t_pos.y += 5 + TERRASAVE - LINES;
|
||||
else continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (top) {
|
||||
if (tp->t_pos.x < TERRASAVE + 1)
|
||||
tp->t_pos.x += COLS - 2 - TERRASAVE;
|
||||
else continue;
|
||||
}
|
||||
else {
|
||||
if (tp->t_pos.x > COLS - 2 - TERRASAVE)
|
||||
tp->t_pos.x += 2 + TERRASAVE - COLS;
|
||||
else continue;
|
||||
}
|
||||
}
|
||||
detach(mlist, item);
|
||||
attach(savmonst, item);
|
||||
}
|
||||
|
||||
/* Check if any treasure should be saved */
|
||||
for (item = lvl_obj; item != NULL; item = nitem) {
|
||||
nitem = next(item);
|
||||
obj = OBJPTR(item);
|
||||
if (vert) {
|
||||
if (top) {
|
||||
if (obj->o_pos.y < TERRASAVE + 2)
|
||||
obj->o_pos.y += LINES - 5 - TERRASAVE;
|
||||
else continue;
|
||||
}
|
||||
else {
|
||||
if (obj->o_pos.y > LINES - 4 - TERRASAVE)
|
||||
obj->o_pos.y += 5 + TERRASAVE - LINES;
|
||||
else continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (top) {
|
||||
if (obj->o_pos.x < TERRASAVE + 1)
|
||||
obj->o_pos.x += COLS - 2 - TERRASAVE;
|
||||
else continue;
|
||||
}
|
||||
else {
|
||||
if (obj->o_pos.x > COLS - 2 - TERRASAVE)
|
||||
obj->o_pos.x += 2 + TERRASAVE - COLS;
|
||||
else continue;
|
||||
}
|
||||
}
|
||||
detach(lvl_obj, item);
|
||||
attach(savitems, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
wclear(cw);
|
||||
wclear(mw);
|
||||
if (fresh) clear();
|
||||
/*
|
||||
* check to see if he missed a UNIQUE, If he did then put it back
|
||||
* in the monster table for next time
|
||||
*/
|
||||
for (item = mlist; item != NULL; item = next(item)) {
|
||||
tp = THINGPTR(item);
|
||||
if (on(*tp, ISUNIQUE))
|
||||
monsters[tp->t_index].m_normal = TRUE;
|
||||
}
|
||||
/*
|
||||
* Free up the monsters on the last level
|
||||
*/
|
||||
t_free_list(monst_dead);
|
||||
t_free_list(mlist);
|
||||
o_free_list(lvl_obj); /* Free up previous objects (if any) */
|
||||
for (rp = rooms; rp < &rooms[MAXROOMS]; rp++)
|
||||
t_free_list(rp->r_exit); /* Free up the exit lists */
|
||||
|
||||
levtype = ltype;
|
||||
foods_this_level = 0; /* food for hero this level */
|
||||
if (ltype == POSTLEV) {
|
||||
do_post(); /* do post stuff */
|
||||
}
|
||||
else if (ltype == MAZELEV) {
|
||||
do_maze();
|
||||
no_food++;
|
||||
put_things(ltype); /* Place objects (if any) */
|
||||
}
|
||||
else if (ltype == OUTSIDE) {
|
||||
init_terrain();
|
||||
do_terrain(starty, startx, deltay, deltax, (bool) (fresh || !vert));
|
||||
no_food++;
|
||||
put_things(ltype);
|
||||
|
||||
/* Should we magically light this area? */
|
||||
if (waslit) rooms[0].r_flags &= ~ISDARK;
|
||||
}
|
||||
else {
|
||||
do_rooms(); /* Draw rooms */
|
||||
do_passages(); /* Draw passages */
|
||||
no_food++;
|
||||
put_things(ltype); /* Place objects (if any) */
|
||||
}
|
||||
/*
|
||||
* Place the staircase down. Only a small chance for an outside stairway.
|
||||
*/
|
||||
if (ltype != OUTSIDE || roll(1, 4) == 4) {
|
||||
cnt = 0;
|
||||
do {
|
||||
rm = rnd_room();
|
||||
rnd_pos(&rooms[rm], &stairs);
|
||||
} until (mvinch(stairs.y, stairs.x) == FLOOR || cnt++ > 5000);
|
||||
addch(STAIRS);
|
||||
}
|
||||
/*
|
||||
* maybe add a trading post
|
||||
*/
|
||||
if (level > 5 && rnd(11) == 7 && ltype == NORMLEV) {
|
||||
cnt = 0;
|
||||
do {
|
||||
rm = rnd_room();
|
||||
if (rooms[rm].r_flags & ISTREAS)
|
||||
continue;
|
||||
rnd_pos(&rooms[rm], &stairs);
|
||||
} until (winat(stairs.y, stairs.x) == FLOOR || cnt++ > 5000);
|
||||
addch(POST);
|
||||
}
|
||||
if (ltype != POSTLEV) { /* Add monsters that fell through */
|
||||
nitem = tlist;
|
||||
while (nitem != NULL) {
|
||||
item = nitem;
|
||||
nitem = next(item); /* because detach and attach mess up ptrs */
|
||||
tp = THINGPTR(item);
|
||||
cnt = 0;
|
||||
do {
|
||||
rm = rnd_room();
|
||||
rnd_pos(&rooms[rm], &tp->t_pos);
|
||||
} until (cnt++ > 5000 || winat(tp->t_pos.y, tp->t_pos.x) == FLOOR);
|
||||
mvwaddch(mw, tp->t_pos.y, tp->t_pos.x, tp->t_type);
|
||||
tp->t_oldch = CCHAR( mvwinch(cw, tp->t_pos.y, tp->t_pos.x) );
|
||||
|
||||
/*
|
||||
* If it has a fire, mark it
|
||||
*/
|
||||
if (on(*tp, HASFIRE)) {
|
||||
register struct linked_list *fire_item;
|
||||
|
||||
fire_item = creat_item();
|
||||
ldata(fire_item) = (char *) tp;
|
||||
attach(rooms[rm].r_fires, fire_item);
|
||||
rooms[rm].r_flags |= HASFIRE;
|
||||
}
|
||||
turn_off(*tp, ISELSEWHERE);
|
||||
detach(tlist, item);
|
||||
attach(mlist, item);
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore any saved monsters */
|
||||
for (item = savmonst; item != NULL; item = nitem) {
|
||||
nitem = next(item);
|
||||
tp = THINGPTR(item);
|
||||
mvwaddch(mw, tp->t_pos.y, tp->t_pos.x, tp->t_type);
|
||||
tp->t_oldch = CCHAR( mvwinch(cw, tp->t_pos.y, tp->t_pos.x) );
|
||||
|
||||
/*
|
||||
* If it has a fire, mark it
|
||||
*/
|
||||
if (on(*tp, HASFIRE)) {
|
||||
register struct linked_list *fire_item;
|
||||
|
||||
fire_item = creat_item();
|
||||
ldata(fire_item) = (char *) tp;
|
||||
attach(rooms[rm].r_fires, fire_item);
|
||||
rooms[rm].r_flags |= HASFIRE;
|
||||
}
|
||||
|
||||
detach(savmonst, item);
|
||||
attach(mlist, item);
|
||||
}
|
||||
|
||||
/* Restore any saved objects */
|
||||
for(item = savitems; item != NULL; item = nitem) {
|
||||
nitem = next(item);
|
||||
obj = OBJPTR(item);
|
||||
mvaddch(obj->o_pos.y, obj->o_pos.x, obj->o_type);
|
||||
detach(savitems, item);
|
||||
attach(lvl_obj, item);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Place the traps (except for trading post)
|
||||
*/
|
||||
ntraps = 0; /* No traps yet */
|
||||
if (levtype == NORMLEV) {
|
||||
if (rnd(10) < vlevel) {
|
||||
ntraps = rnd(vlevel/4)+1;
|
||||
if (ntraps > MAXTRAPS)
|
||||
ntraps = MAXTRAPS;
|
||||
i = ntraps;
|
||||
while (i--)
|
||||
{
|
||||
cnt = 0;
|
||||
do {
|
||||
rm = rnd_room();
|
||||
if (rooms[rm].r_flags & ISTREAS)
|
||||
continue;
|
||||
rnd_pos(&rooms[rm], &stairs);
|
||||
} until (winat(stairs.y, stairs.x) == FLOOR || cnt++ > 5000);
|
||||
|
||||
traps[i].tr_flags = 0;
|
||||
|
||||
/* If we are at the bottom, we can't set a trap door */
|
||||
if (level >= nfloors) ch = (char) rnd(7) + 1;
|
||||
else ch = (char) rnd(8);
|
||||
|
||||
switch((int) ch) {
|
||||
case 0: ch = TRAPDOOR;
|
||||
when 1: ch = BEARTRAP;
|
||||
when 2: ch = SLEEPTRAP;
|
||||
when 3: ch = ARROWTRAP;
|
||||
when 4: ch = TELTRAP;
|
||||
when 5: ch = DARTTRAP;
|
||||
when 6: ch = POOL;
|
||||
traps[i].tr_flags = ISFOUND;
|
||||
when 7: ch = MAZETRAP;
|
||||
}
|
||||
addch(ch);
|
||||
traps[i].tr_type = ch;
|
||||
traps[i].tr_show = FLOOR;
|
||||
traps[i].tr_pos = stairs;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fresh) { /* A whole new picture */
|
||||
cnt = 0;
|
||||
do {
|
||||
rm = rnd_room();
|
||||
if (rooms[rm].r_flags & ISTREAS)
|
||||
continue;
|
||||
rnd_pos(&rooms[rm], &hero);
|
||||
} until( cnt++ > 5000 ||
|
||||
(winat(hero.y, hero.x) == FLOOR &&
|
||||
DISTANCE(hero.y, hero.x, stairs.y, stairs.x) > 16));
|
||||
}
|
||||
else { /* We're extending into an adjacent outside plane */
|
||||
rm = 0;
|
||||
if (vert) {
|
||||
if (hero.y == 1) hero.y = LINES - 3 - TERRASAVE; /* Top to bottom */
|
||||
else hero.y = TERRASAVE + 1; /* Bottom to top */
|
||||
}
|
||||
else {
|
||||
if (hero.x == 0) hero.x = COLS - 1 - TERRASAVE; /* Right to left */
|
||||
else hero.x = TERRASAVE; /* Left to right */
|
||||
}
|
||||
}
|
||||
oldrp = &rooms[rm]; /* Set the current room */
|
||||
player.t_oldpos = player.t_pos; /* Set the current position */
|
||||
if (ISWEARING(R_AGGR) ||
|
||||
(cur_misc[WEAR_JEWEL] != NULL &&
|
||||
cur_misc[WEAR_JEWEL]->o_which == MM_JEWEL))
|
||||
aggravate();
|
||||
light(&hero);
|
||||
wmove(cw, hero.y, hero.x);
|
||||
waddch(cw, PLAYER);
|
||||
|
||||
if (level > cur_max)
|
||||
cur_max = level;
|
||||
|
||||
status(TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Pick a room that is really there
|
||||
*/
|
||||
|
||||
rnd_room()
|
||||
{
|
||||
register int rm;
|
||||
|
||||
if (levtype != NORMLEV)
|
||||
rm = 0;
|
||||
else do
|
||||
{
|
||||
rm = rnd(MAXROOMS);
|
||||
} while (rooms[rm].r_flags & ISGONE);
|
||||
return rm;
|
||||
}
|
||||
|
||||
/*
|
||||
* put_things:
|
||||
* put potions and scrolls on this level
|
||||
*/
|
||||
|
||||
put_things(ltype)
|
||||
LEVTYPE ltype; /* designates type of level to create */
|
||||
{
|
||||
register int i, rm, cnt;
|
||||
register struct object *cur;
|
||||
register struct linked_list *item, *exitptr;
|
||||
bool got_unique = FALSE;
|
||||
int length, width;
|
||||
coord tp, *exit;
|
||||
|
||||
/*
|
||||
* The only way to get new stuff is to go down into the dungeon.
|
||||
*/
|
||||
if (level <= cur_max)
|
||||
return;
|
||||
|
||||
/*
|
||||
* There is a chance that there is a treasure room on this level
|
||||
* Increasing chance after level 9
|
||||
*/
|
||||
if (ltype != MAZELEV && rnd(HARDER) < level - 8) {
|
||||
register j;
|
||||
register struct room *rp;
|
||||
|
||||
/* Count the number of free spaces */
|
||||
i = 0; /* 0 tries */
|
||||
do {
|
||||
rp = &rooms[rnd_room()];
|
||||
width = rp->r_max.y - 2;
|
||||
length = rp->r_max.x - 2;
|
||||
} until ((width*length >= MAXTREAS) || (i++ > MAXROOMS*4));
|
||||
|
||||
/* Mark the room as a treasure room */
|
||||
rp->r_flags |= ISTREAS;
|
||||
|
||||
/* Make all the doors secret doors */
|
||||
for (exitptr = rp->r_exit; exitptr; exitptr = next(exitptr)) {
|
||||
exit = DOORPTR(exitptr);
|
||||
move(exit->y, exit->x);
|
||||
addch(SECRETDOOR);
|
||||
}
|
||||
|
||||
/*
|
||||
* check to see if there are any monsters in room already
|
||||
*/
|
||||
for (item = mlist; item != NULL; item = next(item)) {
|
||||
register struct thing *tp;
|
||||
|
||||
tp = THINGPTR(item);
|
||||
if (rp == roomin(&tp->t_pos)) {
|
||||
turn_on(*tp, ISMEAN);
|
||||
if (off(*tp, CANINWALL)) {
|
||||
tp->t_dest = &hero;
|
||||
turn_on(*tp, ISRUN);
|
||||
}
|
||||
if (on(*tp, ISUNIQUE))
|
||||
got_unique = TRUE;
|
||||
|
||||
/* If it is a mimic, undisguise it */
|
||||
if (on(*tp, ISDISGUISE))
|
||||
turn_off(*tp, ISDISGUISE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Put in the monsters and treasures */
|
||||
for (j=1; j<rp->r_max.y-1; j++)
|
||||
for (i=1; i<rp->r_max.x-1; i++) {
|
||||
coord trp;
|
||||
|
||||
trp.y = rp->r_pos.y+j;
|
||||
trp.x = rp->r_pos.x+i;
|
||||
|
||||
/* Monsters */
|
||||
if ((rnd(100) < (MAXTREAS*100)/(width*length)) &&
|
||||
(mvwinch(mw, rp->r_pos.y+j, rp->r_pos.x+i) == ' ')) {
|
||||
register struct thing *tp;
|
||||
|
||||
/* Make a monster */
|
||||
item = new_item(sizeof *tp);
|
||||
tp = THINGPTR(item);
|
||||
|
||||
/*
|
||||
* Put it there and aggravate it (unless it can escape)
|
||||
* only put one UNIQUE per treasure room at most
|
||||
*/
|
||||
if (got_unique)
|
||||
new_monster(item,randmonster(FALSE, TRUE),&trp,TRUE);
|
||||
else
|
||||
new_monster(item,randmonster(FALSE, FALSE),&trp,TRUE);
|
||||
if (on(*tp, ISUNIQUE)) {
|
||||
got_unique = TRUE;
|
||||
carry_obj(tp, monsters[tp->t_index].m_carry);
|
||||
}
|
||||
turn_on(*tp, ISMEAN);
|
||||
if (off(*tp, CANINWALL)) {
|
||||
tp->t_dest = &hero;
|
||||
turn_on(*tp, ISRUN);
|
||||
}
|
||||
|
||||
/* If it is a mimic, undisguise it */
|
||||
if (on(*tp, ISDISGUISE))
|
||||
turn_off(*tp, ISDISGUISE);
|
||||
|
||||
if (on(*tp, HASFIRE)) {
|
||||
register struct linked_list *fire_item;
|
||||
|
||||
fire_item = creat_item();
|
||||
ldata(fire_item) = (char *) tp;
|
||||
attach(rp->r_fires, fire_item);
|
||||
rp->r_flags |= HASFIRE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Treasures */
|
||||
if ((rnd(100) < (MAXTREAS*100)/(width*length)) &&
|
||||
(mvinch(rp->r_pos.y+j, rp->r_pos.x+i) == FLOOR)) {
|
||||
item = new_thing(ALL);
|
||||
attach(lvl_obj, item);
|
||||
cur = OBJPTR(item);
|
||||
|
||||
mvaddch(trp.y, trp.x, cur->o_type);
|
||||
cur->o_pos = trp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Do MAXOBJ attempts to put things on a level
|
||||
*/
|
||||
for (i = 0; i < MAXOBJ; i++)
|
||||
if (rnd(100) < 45) {
|
||||
/*
|
||||
* Pick a new object and link it in the list
|
||||
*/
|
||||
item = new_thing(ALL);
|
||||
attach(lvl_obj, item);
|
||||
cur = OBJPTR(item);
|
||||
/*
|
||||
* Put it somewhere
|
||||
*/
|
||||
cnt = 0;
|
||||
do {
|
||||
rm = rnd_room();
|
||||
rnd_pos(&rooms[rm], &tp);
|
||||
} until (winat(tp.y, tp.x) == FLOOR || cnt++ > 500);
|
||||
mvaddch(tp.y, tp.x, cur->o_type);
|
||||
cur->o_pos = tp;
|
||||
}
|
||||
}
|
||||
469
arogue5/options.c
Normal file
469
arogue5/options.c
Normal file
|
|
@ -0,0 +1,469 @@
|
|||
/*
|
||||
* This file has all the code for the option command.
|
||||
* I would rather this command were not necessary, but
|
||||
* it is the only way to keep the wolves off of my back.
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "curses.h"
|
||||
#include <ctype.h>
|
||||
#include "rogue.h"
|
||||
|
||||
#define NUM_OPTS (sizeof optlist / sizeof (OPTION))
|
||||
|
||||
|
||||
/*
|
||||
* description of an option and what to do with it
|
||||
*/
|
||||
struct optstruct {
|
||||
char *o_name; /* option name */
|
||||
char *o_prompt; /* prompt for interactive entry */
|
||||
int *o_opt; /* pointer to thing to set */
|
||||
int (*o_putfunc)(); /* function to print value */
|
||||
int (*o_getfunc)(); /* function to get value interactively */
|
||||
};
|
||||
|
||||
typedef struct optstruct OPTION;
|
||||
|
||||
int put_bool(),
|
||||
get_bool(),
|
||||
put_str(),
|
||||
get_str(),
|
||||
put_abil(),
|
||||
get_abil(),
|
||||
get_quest(),
|
||||
put_quest();
|
||||
|
||||
OPTION optlist[] = {
|
||||
{"terse", "Terse output: ",
|
||||
(int *) &terse, put_bool, get_bool },
|
||||
{"flush", "Flush typeahead during battle: ",
|
||||
(int *) &fight_flush, put_bool, get_bool },
|
||||
{"jump", "Show position only at end of run: ",
|
||||
(int *) &jump, put_bool, get_bool },
|
||||
{"step", "Do inventories one line at a time: ",
|
||||
(int *) &slow_invent, put_bool, get_bool },
|
||||
{"askme", "Ask me about unidentified things: ",
|
||||
(int *) &askme, put_bool, get_bool },
|
||||
{"pickup", "Pick things up automatically: ",
|
||||
(int *) &auto_pickup, put_bool, get_bool },
|
||||
{"name", "Name: ",
|
||||
(int *) whoami, put_str, get_str },
|
||||
{"fruit", "Fruit: ",
|
||||
(int *) fruit, put_str, get_str },
|
||||
{"file", "Save file: ",
|
||||
(int *) file_name, put_str, get_str },
|
||||
{"score", "Score file: ",
|
||||
(int *) score_file, put_str, get_str },
|
||||
{"class", "Character class: ",
|
||||
(int *)&char_type, put_abil, get_abil },
|
||||
{"quest", "Quest item: ",
|
||||
(int *) &quest_item, put_quest, get_quest }
|
||||
};
|
||||
|
||||
/*
|
||||
* The ability field is read-only
|
||||
*/
|
||||
get_abil(abil, win)
|
||||
int *abil;
|
||||
WINDOW *win;
|
||||
{
|
||||
register int oy, ox;
|
||||
|
||||
getyx(win, oy, ox);
|
||||
put_abil(abil, win);
|
||||
get_ro(win, oy, ox);
|
||||
}
|
||||
|
||||
/*
|
||||
* The quest field is read-only
|
||||
*/
|
||||
get_quest(quest, win)
|
||||
int *quest;
|
||||
WINDOW *win;
|
||||
{
|
||||
register int oy, ox;
|
||||
|
||||
getyx(win, oy, ox);
|
||||
waddstr(win, rel_magic[*quest].mi_name);
|
||||
get_ro(win, oy, ox);
|
||||
}
|
||||
|
||||
/*
|
||||
* get_ro:
|
||||
* "Get" a read-only value.
|
||||
*/
|
||||
|
||||
get_ro(win, oy, ox)
|
||||
WINDOW *win;
|
||||
register int oy, ox;
|
||||
{
|
||||
register int ny, nx;
|
||||
register bool op_bad;
|
||||
|
||||
op_bad = TRUE;
|
||||
getyx(win, ny, nx);
|
||||
while(op_bad)
|
||||
{
|
||||
wmove(win, oy, ox);
|
||||
draw(win);
|
||||
switch (wgetch(win))
|
||||
{
|
||||
case '\n':
|
||||
case '\r':
|
||||
op_bad = FALSE;
|
||||
break;
|
||||
case '\033':
|
||||
case '\007':
|
||||
return QUIT;
|
||||
case '-':
|
||||
return MINUS;
|
||||
default:
|
||||
mvwaddstr(win, ny, nx + 5, "(no change allowed)");
|
||||
}
|
||||
}
|
||||
wmove(win, ny, nx + 5);
|
||||
wclrtoeol(win);
|
||||
wmove(win, ny, nx);
|
||||
waddch(win, '\n');
|
||||
return NORM;
|
||||
}
|
||||
|
||||
/*
|
||||
* allow changing a boolean option and print it out
|
||||
*/
|
||||
|
||||
get_bool(bp, win)
|
||||
bool *bp;
|
||||
WINDOW *win;
|
||||
{
|
||||
register int oy, ox;
|
||||
register bool op_bad;
|
||||
|
||||
op_bad = TRUE;
|
||||
getyx(win, oy, ox);
|
||||
waddstr(win, *bp ? "True" : "False");
|
||||
while(op_bad)
|
||||
{
|
||||
wmove(win, oy, ox);
|
||||
draw(win);
|
||||
switch (wgetch(win))
|
||||
{
|
||||
case 't':
|
||||
case 'T':
|
||||
*bp = TRUE;
|
||||
op_bad = FALSE;
|
||||
break;
|
||||
case 'f':
|
||||
case 'F':
|
||||
*bp = FALSE;
|
||||
op_bad = FALSE;
|
||||
break;
|
||||
case '\n':
|
||||
case '\r':
|
||||
op_bad = FALSE;
|
||||
break;
|
||||
case '\033':
|
||||
case '\007':
|
||||
return QUIT;
|
||||
case '-':
|
||||
return MINUS;
|
||||
default:
|
||||
mvwaddstr(win, oy, ox + 10, "(T or F)");
|
||||
}
|
||||
}
|
||||
wmove(win, oy, ox);
|
||||
wclrtoeol(win);
|
||||
waddstr(win, *bp ? "True" : "False");
|
||||
waddch(win, '\n');
|
||||
return NORM;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* set a string option
|
||||
*/
|
||||
get_str(opt, win)
|
||||
register char *opt;
|
||||
WINDOW *win;
|
||||
{
|
||||
register char *sp;
|
||||
register int c, oy, ox;
|
||||
char buf[LINELEN];
|
||||
|
||||
draw(win);
|
||||
getyx(win, oy, ox);
|
||||
/*
|
||||
* loop reading in the string, and put it in a temporary buffer
|
||||
*/
|
||||
for (sp = buf;
|
||||
(c = wgetch(win)) != '\n' &&
|
||||
c != '\r' &&
|
||||
c != '\033' &&
|
||||
c != '\007' &&
|
||||
sp < &buf[LINELEN-1];
|
||||
wclrtoeol(win), draw(win))
|
||||
{
|
||||
if (c == -1)
|
||||
continue;
|
||||
else if (c == md_erasechar()) /* process erase character */
|
||||
{
|
||||
if (sp > buf)
|
||||
{
|
||||
register int i;
|
||||
|
||||
sp--;
|
||||
for (i = strlen(unctrl(*sp)); i; i--)
|
||||
waddch(win, '\b');
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if (c == md_killchar()) /* process kill character */
|
||||
{
|
||||
sp = buf;
|
||||
wmove(win, oy, ox);
|
||||
continue;
|
||||
}
|
||||
else if (sp == buf)
|
||||
if (c == '-' && win == hw) /* To move back a line in hw */
|
||||
break;
|
||||
else if (c == '~')
|
||||
{
|
||||
strcpy(buf, home);
|
||||
waddstr(win, home);
|
||||
sp += strlen(home);
|
||||
continue;
|
||||
}
|
||||
*sp++ = c;
|
||||
waddstr(win, unctrl(c));
|
||||
}
|
||||
*sp = '\0';
|
||||
if (sp > buf) /* only change option if something has been typed */
|
||||
strucpy(opt, buf, strlen(buf));
|
||||
wmove(win, oy, ox);
|
||||
waddstr(win, opt);
|
||||
waddch(win, '\n');
|
||||
draw(win);
|
||||
if (win == cw)
|
||||
mpos += (int)(sp - buf);
|
||||
if (c == '-')
|
||||
return MINUS;
|
||||
else if (c == '\033' || c == '\007')
|
||||
return QUIT;
|
||||
else
|
||||
return NORM;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* print and then set options from the terminal
|
||||
*/
|
||||
option()
|
||||
{
|
||||
register OPTION *op;
|
||||
register int retval;
|
||||
|
||||
wclear(hw);
|
||||
touchwin(hw);
|
||||
/*
|
||||
* Display current values of options
|
||||
*/
|
||||
for (op = optlist; op <= &optlist[NUM_OPTS-1]; op++)
|
||||
{
|
||||
waddstr(hw, op->o_prompt);
|
||||
(*op->o_putfunc)(op->o_opt, hw);
|
||||
waddch(hw, '\n');
|
||||
}
|
||||
/*
|
||||
* Set values
|
||||
*/
|
||||
wmove(hw, 0, 0);
|
||||
for (op = optlist; op <= &optlist[NUM_OPTS-1]; op++)
|
||||
{
|
||||
waddstr(hw, op->o_prompt);
|
||||
if ((retval = (*op->o_getfunc)(op->o_opt, hw)))
|
||||
if (retval == QUIT)
|
||||
break;
|
||||
else if (op > optlist) { /* MINUS */
|
||||
wmove(hw, (int)(op - optlist) - 1, 0);
|
||||
op -= 2;
|
||||
}
|
||||
else /* trying to back up beyond the top */
|
||||
{
|
||||
putchar('\007');
|
||||
wmove(hw, 0, 0);
|
||||
op--;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Switch back to original screen
|
||||
*/
|
||||
mvwaddstr(hw, LINES-1, 0, spacemsg);
|
||||
draw(hw);
|
||||
wait_for(hw,' ');
|
||||
clearok(cw, TRUE);
|
||||
touchwin(cw);
|
||||
after = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* parse options from string, usually taken from the environment.
|
||||
* the string is a series of comma seperated values, with booleans
|
||||
* being stated as "name" (true) or "noname" (false), and strings
|
||||
* being "name=....", with the string being defined up to a comma
|
||||
* or the end of the entire option string.
|
||||
*/
|
||||
|
||||
parse_opts(str)
|
||||
register char *str;
|
||||
{
|
||||
register char *sp;
|
||||
register OPTION *op;
|
||||
register int len;
|
||||
|
||||
while (*str)
|
||||
{
|
||||
/*
|
||||
* Get option name
|
||||
*/
|
||||
for (sp = str; isalpha(*sp); sp++)
|
||||
continue;
|
||||
len = (int)(sp - str);
|
||||
/*
|
||||
* Look it up and deal with it
|
||||
*/
|
||||
for (op = optlist; op <= &optlist[NUM_OPTS-1]; op++)
|
||||
if (EQSTR(str, op->o_name, len))
|
||||
{
|
||||
if (op->o_putfunc == put_bool) /* if option is a boolean */
|
||||
*(bool *)op->o_opt = TRUE;
|
||||
else /* string option */
|
||||
{
|
||||
register char *start;
|
||||
char value[80];
|
||||
|
||||
/*
|
||||
* Skip to start of string value
|
||||
*/
|
||||
for (str = sp + 1; *str == '='; str++)
|
||||
continue;
|
||||
if (*str == '~')
|
||||
{
|
||||
strcpy((char *) value, home);
|
||||
start = (char *) value + strlen(home);
|
||||
while (*++str == '/')
|
||||
continue;
|
||||
}
|
||||
else
|
||||
start = (char *) value;
|
||||
/*
|
||||
* Skip to end of string value
|
||||
*/
|
||||
for (sp = str + 1; *sp && *sp != ','; sp++)
|
||||
continue;
|
||||
strucpy(start, str, sp - str);
|
||||
|
||||
/* Put the value into the option field */
|
||||
if (op->o_putfunc != put_abil)
|
||||
strcpy((char *)op->o_opt, value);
|
||||
|
||||
else if (*op->o_opt == -1) { /* Only init ability once */
|
||||
register int len = strlen(value);
|
||||
|
||||
if (isupper(value[0])) value[0] = tolower(value[0]);
|
||||
if (EQSTR(value, "fighter", len))
|
||||
*op->o_opt = C_FIGHTER;
|
||||
else if (EQSTR(value, "magic", min(len, 5)))
|
||||
*op->o_opt = C_MAGICIAN;
|
||||
else if (EQSTR(value, "cleric", len))
|
||||
*op->o_opt = C_CLERIC;
|
||||
else if (EQSTR(value, "thief", len))
|
||||
*op->o_opt = C_THIEF;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* check for "noname" for booleans
|
||||
*/
|
||||
else if (op->o_putfunc == put_bool
|
||||
&& EQSTR(str, "no", 2) && EQSTR(str + 2, op->o_name, len - 2))
|
||||
{
|
||||
*(bool *)op->o_opt = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* skip to start of next option name
|
||||
*/
|
||||
while (*sp && !isalpha(*sp))
|
||||
sp++;
|
||||
str = sp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* print the character type
|
||||
*/
|
||||
put_abil(ability, win)
|
||||
int *ability;
|
||||
WINDOW *win;
|
||||
{
|
||||
char *abil;
|
||||
|
||||
switch (*ability) {
|
||||
case C_MAGICIAN:abil = "Magic User";
|
||||
when C_FIGHTER: abil = "Fighter";
|
||||
when C_CLERIC: abil = "Cleric";
|
||||
when C_THIEF: abil = "Thief";
|
||||
otherwise: abil = "??";
|
||||
}
|
||||
waddstr(win, abil);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* print out the quest
|
||||
*/
|
||||
|
||||
put_quest(quest, win)
|
||||
int *quest;
|
||||
WINDOW *win;
|
||||
{
|
||||
waddstr(win, rel_magic[*quest].mi_name);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* put out a boolean
|
||||
*/
|
||||
put_bool(b, win)
|
||||
bool *b;
|
||||
WINDOW *win;
|
||||
{
|
||||
waddstr(win, *b ? "True" : "False");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* put out a string
|
||||
*/
|
||||
put_str(str, win)
|
||||
char *str;
|
||||
WINDOW *win;
|
||||
{
|
||||
waddstr(win, str);
|
||||
}
|
||||
210
arogue5/outside.c
Normal file
210
arogue5/outside.c
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
/*
|
||||
* functions for dealing with the "outside" level
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "curses.h"
|
||||
#include "rogue.h"
|
||||
|
||||
extern char rnd_terrain(), get_terrain();
|
||||
|
||||
/*
|
||||
* init_terrain:
|
||||
* Get the single "outside room" set up correctly
|
||||
*/
|
||||
|
||||
void
|
||||
init_terrain()
|
||||
{
|
||||
register struct room *rp;
|
||||
|
||||
for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) {
|
||||
rp->r_flags = ISGONE; /* kill all rooms */
|
||||
rp->r_fires = NULL; /* no fires */
|
||||
}
|
||||
rp = &rooms[0]; /* point to only room */
|
||||
rp->r_flags = ISDARK; /* outside is always dark */
|
||||
rp->r_pos.x = 0; /* room fills whole screen */
|
||||
rp->r_pos.y = 1;
|
||||
rp->r_max.x = COLS;
|
||||
rp->r_max.y = LINES - 3;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
do_terrain(basey, basex, deltay, deltax, fresh)
|
||||
int basey, basex, deltay, deltax;
|
||||
bool fresh;
|
||||
{
|
||||
register cury, curx; /* Current y and x positions */
|
||||
|
||||
/* Lay out the boundary */
|
||||
for (cury=1; cury<LINES-2; cury++) { /* Vertical "walls" */
|
||||
mvaddch(cury, 0, '|');
|
||||
mvaddch(cury, COLS-1, '|');
|
||||
}
|
||||
for (curx=0; curx<COLS; curx++) { /* Horizontal "walls" */
|
||||
mvaddch(1, curx, '-');
|
||||
mvaddch(LINES-3, curx, '-');
|
||||
}
|
||||
|
||||
/* If we are not continuing, let's start out with a line of terrain */
|
||||
if (fresh) {
|
||||
char ch; /* Next char to add */
|
||||
|
||||
/* Move to the starting point (should be (1, 0)) */
|
||||
move(basey, basex);
|
||||
curx = basex;
|
||||
|
||||
/* Start with some random terrain */
|
||||
if (basex == 0) {
|
||||
ch = rnd_terrain();
|
||||
addch(ch);
|
||||
}
|
||||
else ch = CCHAR( mvinch(basey, basex) );
|
||||
|
||||
curx += deltax;
|
||||
|
||||
/* Fill in the rest of the line */
|
||||
while (curx > 0 && curx < COLS-1) {
|
||||
/* Put in the next piece */
|
||||
ch = get_terrain(ch, '\0', '\0', '\0');
|
||||
mvaddch(basey, curx, ch);
|
||||
curx += deltax;
|
||||
}
|
||||
|
||||
basey++; /* Advance to next line */
|
||||
}
|
||||
|
||||
/* Fill in the rest of the lines */
|
||||
cury = basey;
|
||||
while (cury > 1 && cury < LINES - 3) {
|
||||
curx = basex;
|
||||
while (curx > 0 && curx < COLS-1) {
|
||||
register char left, top_left, top, top_right;
|
||||
register int left_pos, top_pos;
|
||||
|
||||
/* Get the surrounding terrain */
|
||||
left_pos = curx - deltax;
|
||||
top_pos = cury - deltay;
|
||||
|
||||
left = CCHAR( mvinch(cury, left_pos) );
|
||||
top_left = CCHAR( mvinch(top_pos, left_pos) );
|
||||
top = CCHAR( mvinch(top_pos, curx) );
|
||||
top_right = CCHAR( mvinch(top_pos, curx + deltax) );
|
||||
|
||||
/* Put the piece of terrain on the map */
|
||||
mvaddch(cury, curx, get_terrain(left, top_left, top, top_right));
|
||||
|
||||
/* Get the next x coordinate */
|
||||
curx += deltax;
|
||||
}
|
||||
|
||||
/* Get the next y coordinate */
|
||||
cury += deltay;
|
||||
}
|
||||
genmonsters(5, (bool) 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* do_paths:
|
||||
* draw at least a single path-way through the terrain
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* rnd_terrain:
|
||||
* return a weighted, random type of outside terrain
|
||||
*/
|
||||
|
||||
char
|
||||
rnd_terrain()
|
||||
{
|
||||
int chance = rnd(100);
|
||||
|
||||
/* Forest is most likely */
|
||||
if (chance < 60) return(FOREST);
|
||||
|
||||
/* Next comes meadow */
|
||||
if (chance < 90) return(FLOOR);
|
||||
|
||||
/* Then comes lakes */
|
||||
if (chance < 97) return(POOL);
|
||||
|
||||
/* Finally, mountains */
|
||||
return(WALL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_terrain:
|
||||
* return a terrain weighted by what is surrounding
|
||||
*/
|
||||
|
||||
char
|
||||
get_terrain(one, two, three, four)
|
||||
char one, two, three, four;
|
||||
{
|
||||
register int i;
|
||||
int forest = 0, mountain = 0, lake = 0, meadow = 0, total = 0;
|
||||
char surrounding[4];
|
||||
|
||||
surrounding[0] = one;
|
||||
surrounding[1] = two;
|
||||
surrounding[2] = three;
|
||||
surrounding[3] = four;
|
||||
|
||||
for (i=0; i<4; i++)
|
||||
switch (surrounding[i]) {
|
||||
case FOREST:
|
||||
forest++;
|
||||
total++;
|
||||
|
||||
when WALL:
|
||||
mountain++;
|
||||
total++;
|
||||
|
||||
when POOL:
|
||||
lake++;
|
||||
total++;
|
||||
|
||||
when FLOOR:
|
||||
meadow++;
|
||||
total++;
|
||||
}
|
||||
|
||||
/* Should we continue mountain? */
|
||||
if (rnd(total+1) < mountain) return(WALL);
|
||||
|
||||
/* Should we continue lakes? */
|
||||
if (rnd(total+1) < lake) return(POOL);
|
||||
|
||||
/* Should we continue meadow? */
|
||||
if (rnd(total+1) < meadow) return(FLOOR);
|
||||
|
||||
/* Should we continue forest? */
|
||||
if (rnd(total+2) < forest) return(FOREST);
|
||||
|
||||
/* Return something random */
|
||||
return(rnd_terrain());
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* lake_check:
|
||||
* Determine if the player would drown
|
||||
*/
|
||||
|
||||
void
|
||||
lake_check(place)
|
||||
coord *place;
|
||||
{
|
||||
NOOP(place);
|
||||
}
|
||||
1143
arogue5/pack.c
Normal file
1143
arogue5/pack.c
Normal file
File diff suppressed because it is too large
Load diff
284
arogue5/passages.c
Normal file
284
arogue5/passages.c
Normal file
|
|
@ -0,0 +1,284 @@
|
|||
/*
|
||||
* Draw the connecting passages
|
||||
*
|
||||
* @(#)passages.c 3.4 (Berkeley) 6/15/81
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "curses.h"
|
||||
#include "rogue.h"
|
||||
|
||||
/*
|
||||
* do_passages:
|
||||
* Draw all the passages on a level.
|
||||
*/
|
||||
|
||||
do_passages()
|
||||
{
|
||||
register struct rdes *r1, *r2 = NULL;
|
||||
register int i, j;
|
||||
register int roomcount;
|
||||
static struct rdes
|
||||
{
|
||||
bool conn[MAXROOMS]; /* possible to connect to room i? */
|
||||
bool isconn[MAXROOMS]; /* connection been made to room i? */
|
||||
bool ingraph; /* this room in graph already? */
|
||||
} rdes[MAXROOMS] = {
|
||||
{ { 0, 1, 0, 1, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||
{ { 1, 0, 1, 0, 1, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||
{ { 0, 1, 0, 0, 0, 1, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||
{ { 1, 0, 0, 0, 1, 0, 1, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||
{ { 0, 1, 0, 1, 0, 1, 0, 1, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||
{ { 0, 0, 1, 0, 1, 0, 0, 0, 1 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||
{ { 0, 0, 0, 1, 0, 0, 0, 1, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||
{ { 0, 0, 0, 0, 1, 0, 1, 0, 1 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||
{ { 0, 0, 0, 0, 0, 1, 0, 1, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
|
||||
};
|
||||
|
||||
/*
|
||||
* reinitialize room graph description
|
||||
*/
|
||||
for (r1 = rdes; r1 <= &rdes[MAXROOMS-1]; r1++)
|
||||
{
|
||||
for (j = 0; j < MAXROOMS; j++)
|
||||
r1->isconn[j] = FALSE;
|
||||
r1->ingraph = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* starting with one room, connect it to a random adjacent room and
|
||||
* then pick a new room to start with.
|
||||
*/
|
||||
roomcount = 1;
|
||||
r1 = &rdes[rnd(MAXROOMS)];
|
||||
r1->ingraph = TRUE;
|
||||
do
|
||||
{
|
||||
/*
|
||||
* find a room to connect with
|
||||
*/
|
||||
j = 0;
|
||||
for (i = 0; i < MAXROOMS; i++)
|
||||
if (r1->conn[i] && !rdes[i].ingraph && rnd(++j) == 0)
|
||||
r2 = &rdes[i];
|
||||
/*
|
||||
* if no adjacent rooms are outside the graph, pick a new room
|
||||
* to look from
|
||||
*/
|
||||
if (j == 0)
|
||||
{
|
||||
do
|
||||
r1 = &rdes[rnd(MAXROOMS)];
|
||||
until (r1->ingraph);
|
||||
}
|
||||
/*
|
||||
* otherwise, connect new room to the graph, and draw a tunnel
|
||||
* to it
|
||||
*/
|
||||
else
|
||||
{
|
||||
r2->ingraph = TRUE;
|
||||
i = (int)(r1 - rdes);
|
||||
j = (int)(r2 - rdes);
|
||||
conn(i, j);
|
||||
r1->isconn[j] = TRUE;
|
||||
r2->isconn[i] = TRUE;
|
||||
roomcount++;
|
||||
}
|
||||
} while (roomcount < MAXROOMS);
|
||||
|
||||
/*
|
||||
* attempt to add passages to the graph a random number of times so
|
||||
* that there isn't just one unique passage through it.
|
||||
*/
|
||||
for (roomcount = rnd(5); roomcount > 0; roomcount--)
|
||||
{
|
||||
r1 = &rdes[rnd(MAXROOMS)]; /* a random room to look from */
|
||||
/*
|
||||
* find an adjacent room not already connected
|
||||
*/
|
||||
j = 0;
|
||||
for (i = 0; i < MAXROOMS; i++)
|
||||
if (r1->conn[i] && !r1->isconn[i] && rnd(++j) == 0)
|
||||
r2 = &rdes[i];
|
||||
/*
|
||||
* if there is one, connect it and look for the next added
|
||||
* passage
|
||||
*/
|
||||
if (j != 0)
|
||||
{
|
||||
i = (int)(r1 - rdes);
|
||||
j = (int)(r2 - rdes);
|
||||
conn(i, j);
|
||||
r1->isconn[j] = TRUE;
|
||||
r2->isconn[i] = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* conn:
|
||||
* Draw a corridor from a room in a certain direction.
|
||||
*/
|
||||
|
||||
conn(r1, r2)
|
||||
int r1, r2;
|
||||
{
|
||||
register struct room *rpf, *rpt = NULL;
|
||||
register char rmt;
|
||||
register int distance = 0, turn_spot = 0, turn_distance = 0;
|
||||
register int rm;
|
||||
register char direc;
|
||||
coord delta = { 0, 0 }, curr, turn_delta = { 0, 0 }, spos = { 0, 0 }, epos = { 0, 0 };
|
||||
|
||||
if (r1 < r2)
|
||||
{
|
||||
rm = r1;
|
||||
if (r1 + 1 == r2)
|
||||
direc = 'r';
|
||||
else
|
||||
direc = 'd';
|
||||
}
|
||||
else
|
||||
{
|
||||
rm = r2;
|
||||
if (r2 + 1 == r1)
|
||||
direc = 'r';
|
||||
else
|
||||
direc = 'd';
|
||||
}
|
||||
rpf = &rooms[rm];
|
||||
/*
|
||||
* Set up the movement variables, in two cases:
|
||||
* first drawing one down.
|
||||
*/
|
||||
if (direc == 'd')
|
||||
{
|
||||
rmt = rm + 3; /* room # of dest */
|
||||
rpt = &rooms[rmt]; /* room pointer of dest */
|
||||
delta.x = 0; /* direction of move */
|
||||
delta.y = 1;
|
||||
spos.x = rpf->r_pos.x; /* start of move */
|
||||
spos.y = rpf->r_pos.y;
|
||||
epos.x = rpt->r_pos.x; /* end of move */
|
||||
epos.y = rpt->r_pos.y;
|
||||
if (!(rpf->r_flags & ISGONE)) /* if not gone pick door pos */
|
||||
{
|
||||
spos.x += rnd(rpf->r_max.x-2)+1;
|
||||
spos.y += rpf->r_max.y-1;
|
||||
}
|
||||
if (!(rpt->r_flags & ISGONE))
|
||||
epos.x += rnd(rpt->r_max.x-2)+1;
|
||||
distance = abs(spos.y - epos.y) - 1; /* distance to move */
|
||||
turn_delta.y = 0; /* direction to turn */
|
||||
turn_delta.x = (spos.x < epos.x ? 1 : -1);
|
||||
turn_distance = abs(spos.x - epos.x); /* how far to turn */
|
||||
turn_spot = rnd(distance-1) + 1; /* where turn starts */
|
||||
}
|
||||
else if (direc == 'r') /* setup for moving right */
|
||||
{
|
||||
rmt = rm + 1;
|
||||
rpt = &rooms[rmt];
|
||||
delta.x = 1;
|
||||
delta.y = 0;
|
||||
spos.x = rpf->r_pos.x;
|
||||
spos.y = rpf->r_pos.y;
|
||||
epos.x = rpt->r_pos.x;
|
||||
epos.y = rpt->r_pos.y;
|
||||
if (!(rpf->r_flags & ISGONE))
|
||||
{
|
||||
spos.x += rpf->r_max.x-1;
|
||||
spos.y += rnd(rpf->r_max.y-2)+1;
|
||||
}
|
||||
if (!(rpt->r_flags & ISGONE))
|
||||
epos.y += rnd(rpt->r_max.y-2)+1;
|
||||
distance = abs(spos.x - epos.x) - 1;
|
||||
turn_delta.y = (spos.y < epos.y ? 1 : -1);
|
||||
turn_delta.x = 0;
|
||||
turn_distance = abs(spos.y - epos.y);
|
||||
turn_spot = rnd(distance-1) + 1;
|
||||
}
|
||||
else
|
||||
debug("error in connection tables");
|
||||
/*
|
||||
* Draw in the doors on either side of the passage or just put #'s
|
||||
* if the rooms are gone.
|
||||
*/
|
||||
if (!(rpf->r_flags & ISGONE)) door(rpf, &spos);
|
||||
else
|
||||
{
|
||||
cmov(spos);
|
||||
addch('#');
|
||||
}
|
||||
if (!(rpt->r_flags & ISGONE)) door(rpt, &epos);
|
||||
else
|
||||
{
|
||||
cmov(epos);
|
||||
addch('#');
|
||||
}
|
||||
/*
|
||||
* Get ready to move...
|
||||
*/
|
||||
curr.x = spos.x;
|
||||
curr.y = spos.y;
|
||||
while(distance)
|
||||
{
|
||||
/*
|
||||
* Move to new position
|
||||
*/
|
||||
curr.x += delta.x;
|
||||
curr.y += delta.y;
|
||||
/*
|
||||
* Check if we are at the turn place, if so do the turn
|
||||
*/
|
||||
if (distance == turn_spot && turn_distance > 0)
|
||||
while(turn_distance--)
|
||||
{
|
||||
cmov(curr);
|
||||
addch(PASSAGE);
|
||||
curr.x += turn_delta.x;
|
||||
curr.y += turn_delta.y;
|
||||
}
|
||||
/*
|
||||
* Continue digging along
|
||||
*/
|
||||
cmov(curr);
|
||||
addch(PASSAGE);
|
||||
distance--;
|
||||
}
|
||||
curr.x += delta.x;
|
||||
curr.y += delta.y;
|
||||
if (!ce(curr, epos))
|
||||
msg("Warning, connectivity problem on this level.");
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a door or possibly a secret door
|
||||
* also enters the door in the exits array of the room.
|
||||
*/
|
||||
|
||||
door(rm, cp)
|
||||
register struct room *rm;
|
||||
register coord *cp;
|
||||
{
|
||||
struct linked_list *newroom;
|
||||
coord *exit;
|
||||
|
||||
cmov(*cp);
|
||||
addch( (rnd(10) < level - 1 && rnd(100) < 20 ? SECRETDOOR : DOOR) );
|
||||
|
||||
/* Insert the new room into the linked list of rooms */
|
||||
newroom = new_item(sizeof(coord));
|
||||
exit = DOORPTR(newroom);
|
||||
*exit = *cp;
|
||||
attach(rm->r_exit, newroom);
|
||||
}
|
||||
587
arogue5/player.c
Normal file
587
arogue5/player.c
Normal file
|
|
@ -0,0 +1,587 @@
|
|||
/*
|
||||
* This file contains functions for dealing with special player abilities
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "curses.h"
|
||||
#include "rogue.h"
|
||||
|
||||
|
||||
/*
|
||||
* affect:
|
||||
* cleric affecting undead
|
||||
*/
|
||||
|
||||
affect()
|
||||
{
|
||||
register struct linked_list *item;
|
||||
register struct thing *tp;
|
||||
register const char *mname;
|
||||
bool see;
|
||||
coord new_pos;
|
||||
|
||||
if (player.t_ctype != C_CLERIC && cur_relic[HEIL_ANKH] == 0) {
|
||||
msg("Only clerics can affect undead.");
|
||||
return;
|
||||
}
|
||||
|
||||
new_pos.y = hero.y + delta.y;
|
||||
new_pos.x = hero.x + delta.x;
|
||||
|
||||
if (cansee(new_pos.y, new_pos.x)) see = TRUE;
|
||||
else see = FALSE;
|
||||
|
||||
/* Anything there? */
|
||||
if (new_pos.y < 0 || new_pos.y > LINES-3 ||
|
||||
new_pos.x < 0 || new_pos.x > COLS-1 ||
|
||||
mvwinch(mw, new_pos.y, new_pos.x) == ' ') {
|
||||
msg("Nothing to affect.");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((item = find_mons(new_pos.y, new_pos.x)) == NULL) {
|
||||
debug("Affect what @ %d,%d?", new_pos.y, new_pos.x);
|
||||
return;
|
||||
}
|
||||
tp = THINGPTR(item);
|
||||
mname = monsters[tp->t_index].m_name;
|
||||
|
||||
if (on(player, ISINVIS) && off(*tp, CANSEE)) {
|
||||
sprintf(outstring,"%s%s cannot see you", see ? "The " : "It",
|
||||
see ? mname : "");
|
||||
msg(outstring);
|
||||
return;
|
||||
}
|
||||
|
||||
if (off(*tp, TURNABLE) || on(*tp, WASTURNED))
|
||||
goto annoy;
|
||||
turn_off(*tp, TURNABLE);
|
||||
|
||||
/* Can cleric kill it? */
|
||||
if (pstats.s_lvl >= 3 * tp->t_stats.s_lvl) {
|
||||
unsigned long test; /* For overflow check */
|
||||
|
||||
sprintf(outstring,"You have destroyed %s%s.", see ? "the " : "it", see ? mname : "");
|
||||
msg(outstring);
|
||||
test = pstats.s_exp + tp->t_stats.s_exp;
|
||||
|
||||
/* Be sure there is no overflow before increasing experience */
|
||||
if (test > pstats.s_exp) pstats.s_exp = test;
|
||||
killed(item, FALSE, TRUE);
|
||||
check_level(TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Can cleric turn it? */
|
||||
if (rnd(100) + 1 >
|
||||
(100 * ((2 * tp->t_stats.s_lvl) - pstats.s_lvl)) / pstats.s_lvl) {
|
||||
unsigned long test; /* Overflow test */
|
||||
|
||||
/* Make the monster flee */
|
||||
turn_on(*tp, WASTURNED); /* No more fleeing after this */
|
||||
turn_on(*tp, ISFLEE);
|
||||
runto(tp, &hero);
|
||||
|
||||
/* Let player know */
|
||||
sprintf(outstring,"You have turned %s%s.", see ? "the " : "it", see ? mname : "");
|
||||
msg(outstring);
|
||||
|
||||
/* get points for turning monster -- but check overflow first */
|
||||
test = pstats.s_exp + tp->t_stats.s_exp/2;
|
||||
if (test > pstats.s_exp) pstats.s_exp = test;
|
||||
check_level(TRUE);
|
||||
|
||||
/* If monster was suffocating, stop it */
|
||||
if (on(*tp, DIDSUFFOCATE)) {
|
||||
turn_off(*tp, DIDSUFFOCATE);
|
||||
extinguish(suffocate);
|
||||
}
|
||||
|
||||
/* If monster held us, stop it */
|
||||
if (on(*tp, DIDHOLD) && (--hold_count == 0))
|
||||
turn_off(player, ISHELD);
|
||||
turn_off(*tp, DIDHOLD);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Otherwise -- no go */
|
||||
annoy:
|
||||
sprintf(outstring,"You do not affect %s%s.", see ? "the " : "it", see ? mname : "");
|
||||
msg(outstring);
|
||||
|
||||
/* Annoy monster */
|
||||
if (off(*tp, ISFLEE)) runto(tp, &hero);
|
||||
}
|
||||
|
||||
/*
|
||||
* the magic user is going to try and cast a spell
|
||||
*/
|
||||
cast()
|
||||
{
|
||||
register int i, num_spells, spell_ability;
|
||||
int which_spell;
|
||||
bool nohw = FALSE;
|
||||
|
||||
i = num_spells = spell_ability = which_spell = 0;
|
||||
|
||||
if (player.t_ctype != C_MAGICIAN && pstats.s_intel < 16) {
|
||||
msg("You are not permitted to cast spells.");
|
||||
return;
|
||||
}
|
||||
if (cur_misc[WEAR_CLOAK] != NULL &&
|
||||
cur_misc[WEAR_CLOAK]->o_which == MM_R_POWERLESS) {
|
||||
msg("You can't seem to cast a spell!");
|
||||
return;
|
||||
}
|
||||
num_spells = 0;
|
||||
|
||||
/* Get the number of avilable spells */
|
||||
if (pstats.s_intel >= 16)
|
||||
num_spells = pstats.s_intel - 15;
|
||||
|
||||
if (player.t_ctype == C_MAGICIAN)
|
||||
num_spells += pstats.s_lvl;
|
||||
|
||||
if (num_spells > MAXSPELLS)
|
||||
num_spells = MAXSPELLS;
|
||||
|
||||
spell_ability = pstats.s_lvl * pstats.s_intel;
|
||||
if (player.t_ctype != C_MAGICIAN)
|
||||
spell_ability /= 2;
|
||||
|
||||
/* Prompt for spells */
|
||||
msg("Which spell are you casting? (* for list): ");
|
||||
|
||||
which_spell = (int) (readchar() - 'a');
|
||||
if (which_spell == (int) ESCAPE - (int) 'a') {
|
||||
mpos = 0;
|
||||
msg("");
|
||||
after = FALSE;
|
||||
return;
|
||||
}
|
||||
if (which_spell >= 0 && which_spell < num_spells) nohw = TRUE;
|
||||
|
||||
else if (slow_invent) {
|
||||
register char c;
|
||||
|
||||
for (i=0; i<num_spells; i++) {
|
||||
msg("");
|
||||
mvwaddch(cw, 0, 0, '[');
|
||||
waddch(cw, (char) ((int) 'a' + i));
|
||||
waddstr(cw, "] A spell of ");
|
||||
if (magic_spells[i].s_type == TYP_POTION)
|
||||
waddstr(cw, p_magic[magic_spells[i].s_which].mi_name);
|
||||
else if (magic_spells[i].s_type == TYP_SCROLL)
|
||||
waddstr(cw, s_magic[magic_spells[i].s_which].mi_name);
|
||||
else if (magic_spells[i].s_type == TYP_STICK)
|
||||
waddstr(cw, ws_magic[magic_spells[i].s_which].mi_name);
|
||||
waddstr(cw, morestr);
|
||||
draw(cw);
|
||||
do {
|
||||
c = readchar();
|
||||
} while (c != ' ' && c != ESCAPE);
|
||||
if (c == ESCAPE)
|
||||
break;
|
||||
}
|
||||
msg("");
|
||||
mvwaddstr(cw, 0, 0, "Which spell are you casting? ");
|
||||
draw(cw);
|
||||
}
|
||||
else {
|
||||
/* Set up for redraw */
|
||||
msg("");
|
||||
clearok(cw, TRUE);
|
||||
touchwin(cw);
|
||||
|
||||
/* Now display the possible spells */
|
||||
wclear(hw);
|
||||
touchwin(hw);
|
||||
mvwaddstr(hw, 2, 0, " Cost Spell");
|
||||
mvwaddstr(hw, 3, 0, "-----------------------------------------------");
|
||||
for (i=0; i<num_spells; i++) {
|
||||
mvwaddch(hw, i+4, 0, '[');
|
||||
waddch(hw, (char) ((int) 'a' + i));
|
||||
waddch(hw, ']');
|
||||
sprintf(prbuf, " %3d", magic_spells[i].s_cost);
|
||||
waddstr(hw, prbuf);
|
||||
waddstr(hw, " A spell of ");
|
||||
if (magic_spells[i].s_type == TYP_POTION)
|
||||
waddstr(hw, p_magic[magic_spells[i].s_which].mi_name);
|
||||
else if (magic_spells[i].s_type == TYP_SCROLL)
|
||||
waddstr(hw, s_magic[magic_spells[i].s_which].mi_name);
|
||||
else if (magic_spells[i].s_type == TYP_STICK)
|
||||
waddstr(hw, ws_magic[magic_spells[i].s_which].mi_name);
|
||||
}
|
||||
sprintf(prbuf,"[Current spell power = %d]",spell_ability - spell_power);
|
||||
mvwaddstr(hw, 0, 0, prbuf);
|
||||
waddstr(hw, " Which spell are you casting? ");
|
||||
draw(hw);
|
||||
}
|
||||
|
||||
if (!nohw) {
|
||||
which_spell = (int) (wgetch(hw) - 'a');
|
||||
while (which_spell < 0 || which_spell >= num_spells) {
|
||||
if (which_spell == (int) ESCAPE - (int) 'a') {
|
||||
after = FALSE;
|
||||
return;
|
||||
}
|
||||
wmove(hw, 0, 0);
|
||||
wclrtoeol(hw);
|
||||
waddstr(hw, "Please enter one of the listed spells. ");
|
||||
draw(hw);
|
||||
which_spell = (int) (wgetch(hw) - 'a');
|
||||
}
|
||||
}
|
||||
|
||||
if ((spell_power + magic_spells[which_spell].s_cost) > spell_ability) {
|
||||
msg("Your attempt fails.");
|
||||
return;
|
||||
}
|
||||
if (nohw)
|
||||
msg("Your spell is successful.");
|
||||
else {
|
||||
mvwaddstr(hw, 0, 0, "Your spell is successful.--More--");
|
||||
wclrtoeol(hw);
|
||||
draw(hw);
|
||||
wait_for(hw,' ');
|
||||
}
|
||||
if (magic_spells[which_spell].s_type == TYP_POTION)
|
||||
quaff( magic_spells[which_spell].s_which,
|
||||
magic_spells[which_spell].s_flag,
|
||||
FALSE);
|
||||
else if (magic_spells[which_spell].s_type == TYP_SCROLL)
|
||||
read_scroll( magic_spells[which_spell].s_which,
|
||||
magic_spells[which_spell].s_flag,
|
||||
FALSE);
|
||||
else if (magic_spells[which_spell].s_type == TYP_STICK) {
|
||||
if (!do_zap( TRUE,
|
||||
magic_spells[which_spell].s_which,
|
||||
magic_spells[which_spell].s_flag)) {
|
||||
after = FALSE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
spell_power += magic_spells[which_spell].s_cost;
|
||||
}
|
||||
|
||||
/* Constitution bonus */
|
||||
|
||||
const_bonus() /* Hit point adjustment for changing levels */
|
||||
{
|
||||
if (pstats.s_const > 6 && pstats.s_const <= 14)
|
||||
return(0);
|
||||
if (pstats.s_const > 14)
|
||||
return(pstats.s_const-14);
|
||||
if (pstats.s_const > 3)
|
||||
return(-1);
|
||||
return(-2);
|
||||
}
|
||||
|
||||
|
||||
/* Routines for thieves */
|
||||
|
||||
/*
|
||||
* gsense:
|
||||
* Sense gold
|
||||
*/
|
||||
|
||||
gsense()
|
||||
{
|
||||
/* Only thieves can do this */
|
||||
if (player.t_ctype != C_THIEF) {
|
||||
msg("You seem to have no gold sense.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (lvl_obj != NULL) {
|
||||
struct linked_list *gitem;
|
||||
struct object *cur;
|
||||
int gtotal = 0;
|
||||
|
||||
wclear(hw);
|
||||
for (gitem = lvl_obj; gitem != NULL; gitem = next(gitem)) {
|
||||
cur = OBJPTR(gitem);
|
||||
if (cur->o_type == GOLD) {
|
||||
gtotal += cur->o_count;
|
||||
mvwaddch(hw, cur->o_pos.y, cur->o_pos.x, GOLD);
|
||||
}
|
||||
}
|
||||
if (gtotal) {
|
||||
s_know[S_GFIND] = TRUE;
|
||||
msg("You sense gold!");
|
||||
overlay(hw,cw);
|
||||
return;
|
||||
}
|
||||
}
|
||||
msg("You can sense no gold on this level.");
|
||||
}
|
||||
|
||||
/*
|
||||
* the cleric asks his deity for a spell
|
||||
*/
|
||||
pray()
|
||||
{
|
||||
register int i, num_prayers, prayer_ability;
|
||||
int which_prayer;
|
||||
bool nohw = FALSE;
|
||||
|
||||
which_prayer = num_prayers = prayer_ability = i = 0;
|
||||
|
||||
if (player.t_ctype != C_CLERIC && pstats.s_wisdom < 17 &&
|
||||
cur_relic[HEIL_ANKH] == 0) {
|
||||
msg("You are not permitted to pray.");
|
||||
return;
|
||||
}
|
||||
if (cur_misc[WEAR_CLOAK] != NULL &&
|
||||
cur_misc[WEAR_CLOAK]->o_which == MM_R_POWERLESS) {
|
||||
msg("You can't seem to pray!");
|
||||
return;
|
||||
}
|
||||
num_prayers = 0;
|
||||
|
||||
/* Get the number of avilable prayers */
|
||||
if (pstats.s_wisdom > 16)
|
||||
num_prayers = (pstats.s_wisdom - 15) / 2;
|
||||
|
||||
if (player.t_ctype == C_CLERIC)
|
||||
num_prayers += pstats.s_lvl;
|
||||
|
||||
if (cur_relic[HEIL_ANKH]) num_prayers += 3;
|
||||
|
||||
if (num_prayers > MAXPRAYERS)
|
||||
num_prayers = MAXPRAYERS;
|
||||
|
||||
prayer_ability = pstats.s_lvl * pstats.s_wisdom;
|
||||
if (player.t_ctype != C_CLERIC)
|
||||
prayer_ability /= 2;
|
||||
|
||||
if (cur_relic[HEIL_ANKH]) prayer_ability *= 2;
|
||||
|
||||
/* Prompt for prayer */
|
||||
msg("Which prayer are you offering? (* for list): ");
|
||||
which_prayer = (int) (readchar() - 'a');
|
||||
if (which_prayer == (int) ESCAPE - (int) 'a') {
|
||||
mpos = 0;
|
||||
msg("");
|
||||
after = FALSE;
|
||||
return;
|
||||
}
|
||||
if (which_prayer >= 0 && which_prayer < num_prayers) nohw = TRUE;
|
||||
|
||||
else if (slow_invent) {
|
||||
register char c;
|
||||
|
||||
for (i=0; i<num_prayers; i++) {
|
||||
msg("");
|
||||
mvwaddch(cw, 0, 0, '[');
|
||||
waddch(cw, (char) ((int) 'a' + i));
|
||||
waddstr(cw, "] A prayer for ");
|
||||
if (cleric_spells[i].s_type == TYP_POTION)
|
||||
waddstr(cw, p_magic[cleric_spells[i].s_which].mi_name);
|
||||
else if (cleric_spells[i].s_type == TYP_SCROLL)
|
||||
waddstr(cw, s_magic[cleric_spells[i].s_which].mi_name);
|
||||
else if (cleric_spells[i].s_type == TYP_STICK)
|
||||
waddstr(cw, ws_magic[cleric_spells[i].s_which].mi_name);
|
||||
waddstr(cw, morestr);
|
||||
draw(cw);
|
||||
do {
|
||||
c = readchar();
|
||||
} while (c != ' ' && c != ESCAPE);
|
||||
if (c == ESCAPE)
|
||||
break;
|
||||
}
|
||||
msg("");
|
||||
mvwaddstr(cw, 0, 0, "Which prayer are you offering? ");
|
||||
draw(cw);
|
||||
}
|
||||
else {
|
||||
/* Set up for redraw */
|
||||
msg("");
|
||||
clearok(cw, TRUE);
|
||||
touchwin(cw);
|
||||
|
||||
/* Now display the possible prayers */
|
||||
wclear(hw);
|
||||
touchwin(hw);
|
||||
mvwaddstr(hw, 2, 0, " Cost Prayer");
|
||||
mvwaddstr(hw, 3, 0, "-----------------------------------------------");
|
||||
for (i=0; i<num_prayers; i++) {
|
||||
mvwaddch(hw, i+4, 0, '[');
|
||||
waddch(hw, (char) ((int) 'a' + i));
|
||||
waddch(hw, ']');
|
||||
sprintf(prbuf, " %3d", cleric_spells[i].s_cost);
|
||||
waddstr(hw, prbuf);
|
||||
waddstr(hw, " A prayer for ");
|
||||
if (cleric_spells[i].s_type == TYP_POTION)
|
||||
waddstr(hw, p_magic[cleric_spells[i].s_which].mi_name);
|
||||
else if (cleric_spells[i].s_type == TYP_SCROLL)
|
||||
waddstr(hw, s_magic[cleric_spells[i].s_which].mi_name);
|
||||
else if (cleric_spells[i].s_type == TYP_STICK)
|
||||
waddstr(hw, ws_magic[cleric_spells[i].s_which].mi_name);
|
||||
}
|
||||
sprintf(prbuf,"[Current prayer ability = %d]",prayer_ability-pray_time);
|
||||
mvwaddstr(hw, 0, 0, prbuf);
|
||||
waddstr(hw, " Which prayer are you offering? ");
|
||||
draw(hw);
|
||||
}
|
||||
|
||||
if (!nohw) {
|
||||
which_prayer = (int) (wgetch(hw) - 'a');
|
||||
while (which_prayer < 0 || which_prayer >= num_prayers) {
|
||||
if (which_prayer == (int) ESCAPE - (int) 'a') {
|
||||
after = FALSE;
|
||||
return;
|
||||
}
|
||||
wmove(hw, 0, 0);
|
||||
wclrtoeol(hw);
|
||||
mvwaddstr(hw, 0, 0, "Please enter one of the listed prayers.");
|
||||
draw(hw);
|
||||
which_prayer = (int) (wgetch(hw) - 'a');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (cleric_spells[which_prayer].s_cost + pray_time > prayer_ability) {
|
||||
msg("Your prayer fails.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (nohw)
|
||||
msg("Your prayer has been granted.");
|
||||
else {
|
||||
mvwaddstr(hw, 0, 0, "Your prayer has been granted.--More--");
|
||||
wclrtoeol(hw);
|
||||
draw(hw);
|
||||
wait_for(hw,' ');
|
||||
}
|
||||
if (cleric_spells[which_prayer].s_type == TYP_POTION)
|
||||
quaff( cleric_spells[which_prayer].s_which,
|
||||
cleric_spells[which_prayer].s_flag,
|
||||
FALSE);
|
||||
else if (cleric_spells[which_prayer].s_type == TYP_SCROLL)
|
||||
read_scroll( cleric_spells[which_prayer].s_which,
|
||||
cleric_spells[which_prayer].s_flag,
|
||||
FALSE);
|
||||
else if (cleric_spells[which_prayer].s_type == TYP_STICK) {
|
||||
if (!do_zap( TRUE,
|
||||
cleric_spells[which_prayer].s_which,
|
||||
cleric_spells[which_prayer].s_flag)) {
|
||||
after = FALSE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
pray_time += cleric_spells[which_prayer].s_cost;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* steal:
|
||||
* Steal in direction given in delta
|
||||
*/
|
||||
|
||||
steal()
|
||||
{
|
||||
register struct linked_list *item;
|
||||
register struct thing *tp;
|
||||
register const char *mname;
|
||||
coord new_pos;
|
||||
int thief_bonus = -50;
|
||||
bool isinvisible = FALSE;
|
||||
|
||||
new_pos.y = hero.y + delta.y;
|
||||
new_pos.x = hero.x + delta.x;
|
||||
|
||||
if (on(player, ISBLIND)) {
|
||||
msg("You can't see anything.");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Anything there? */
|
||||
if (new_pos.y < 0 || new_pos.y > LINES-3 ||
|
||||
new_pos.x < 0 || new_pos.x > COLS-1 ||
|
||||
mvwinch(mw, new_pos.y, new_pos.x) == ' ') {
|
||||
msg("Nothing to steal from.");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((item = find_mons(new_pos.y, new_pos.x)) == NULL)
|
||||
debug("Steal from what @ %d,%d?", new_pos.y, new_pos.x);
|
||||
tp = THINGPTR(item);
|
||||
if (isinvisible = invisible(tp)) mname = "creature";
|
||||
else mname = monsters[tp->t_index].m_name;
|
||||
|
||||
/* Can player steal something unnoticed? */
|
||||
if (player.t_ctype == C_THIEF) thief_bonus = 10;
|
||||
if (on(*tp, ISUNIQUE)) thief_bonus -= 15;
|
||||
if (isinvisible) thief_bonus -= 20;
|
||||
if (on(*tp, ISINWALL) && off(player, CANINWALL)) thief_bonus -= 50;
|
||||
|
||||
if (rnd(100) <
|
||||
(thief_bonus + 2*dex_compute() + 5*pstats.s_lvl -
|
||||
5*(tp->t_stats.s_lvl - 3))) {
|
||||
register struct linked_list *s_item, *pack_ptr;
|
||||
int count = 0;
|
||||
unsigned long test; /* Overflow check */
|
||||
|
||||
s_item = NULL; /* Start stolen goods out as nothing */
|
||||
|
||||
/* Find a good item to take */
|
||||
for (pack_ptr=tp->t_pack; pack_ptr != NULL; pack_ptr=next(pack_ptr))
|
||||
if ((OBJPTR(pack_ptr))->o_type != RELIC &&
|
||||
rnd(++count) == 0)
|
||||
s_item = pack_ptr;
|
||||
|
||||
/*
|
||||
* Find anything?
|
||||
*
|
||||
* if we have a merchant, and his pack is empty then the
|
||||
* rogue has already stolen once
|
||||
*/
|
||||
if (s_item == NULL) {
|
||||
if (tp->t_index == NUMMONST)
|
||||
msg("The %s seems to be shielding his pack from you.", mname);
|
||||
else
|
||||
msg("The %s apparently has nothing to steal.", mname);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Take it from monster */
|
||||
if (tp->t_pack) detach(tp->t_pack, s_item);
|
||||
|
||||
/* Give it to player */
|
||||
if (add_pack(s_item, FALSE, NULL) == FALSE) {
|
||||
(OBJPTR(s_item))->o_pos = hero;
|
||||
fall(s_item, TRUE);
|
||||
}
|
||||
|
||||
/* Get points for stealing -- but first check for overflow */
|
||||
test = pstats.s_exp + tp->t_stats.s_exp/2;
|
||||
if (test > pstats.s_exp) pstats.s_exp = test;
|
||||
|
||||
/*
|
||||
* Do adjustments if player went up a level
|
||||
*/
|
||||
check_level(TRUE);
|
||||
}
|
||||
|
||||
else {
|
||||
msg("Your attempt fails.");
|
||||
|
||||
/* Annoy monster (maybe) */
|
||||
if (rnd(35) >= dex_compute() + thief_bonus) {
|
||||
if (tp->t_index == NUMMONST) {
|
||||
if (!isinvisible)
|
||||
msg("The %s looks insulted and leaves", mname);
|
||||
killed(item, FALSE, FALSE);
|
||||
}
|
||||
else
|
||||
runto(tp, &hero);
|
||||
}
|
||||
}
|
||||
}
|
||||
698
arogue5/potions.c
Normal file
698
arogue5/potions.c
Normal file
|
|
@ -0,0 +1,698 @@
|
|||
/*
|
||||
* Function(s) for dealing with potions
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "curses.h"
|
||||
#include "rogue.h"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Increase player's constitution
|
||||
*/
|
||||
|
||||
add_const(cursed)
|
||||
bool cursed;
|
||||
{
|
||||
/* Do the potion */
|
||||
if (cursed) {
|
||||
msg("You feel less healthy now.");
|
||||
pstats.s_const--;
|
||||
if (pstats.s_const <= 0)
|
||||
death(D_CONSTITUTION);
|
||||
}
|
||||
else {
|
||||
msg("You feel healthier now.");
|
||||
pstats.s_const = min(pstats.s_const + 1, 25);
|
||||
}
|
||||
|
||||
/* Adjust the maximum */
|
||||
if (max_stats.s_const < pstats.s_const)
|
||||
max_stats.s_const = pstats.s_const;
|
||||
}
|
||||
|
||||
/*
|
||||
* Increase player's dexterity
|
||||
*/
|
||||
|
||||
add_dexterity(cursed)
|
||||
bool cursed;
|
||||
{
|
||||
int ring_str; /* Value of ring strengths */
|
||||
|
||||
/* Undo any ring changes */
|
||||
ring_str = ring_value(R_ADDHIT);
|
||||
pstats.s_dext -= ring_str;
|
||||
|
||||
/* Now do the potion */
|
||||
if (cursed) {
|
||||
msg("You feel less dextrous now.");
|
||||
pstats.s_dext--;
|
||||
}
|
||||
else {
|
||||
msg("You feel more dextrous now. Watch those hands!");
|
||||
pstats.s_dext = min(pstats.s_dext + 1, 25);
|
||||
}
|
||||
|
||||
/* Adjust the maximum */
|
||||
if (max_stats.s_dext < pstats.s_dext)
|
||||
max_stats.s_dext = pstats.s_dext;
|
||||
|
||||
/* Now put back the ring changes */
|
||||
if (ring_str)
|
||||
pstats.s_dext += ring_str;
|
||||
}
|
||||
|
||||
/*
|
||||
* add_haste:
|
||||
* add a haste to the player
|
||||
*/
|
||||
|
||||
add_haste(blessed)
|
||||
bool blessed;
|
||||
{
|
||||
int hasttime;
|
||||
|
||||
if (blessed) hasttime = HASTETIME*2;
|
||||
else hasttime = HASTETIME;
|
||||
|
||||
if (on(player, ISSLOW)) { /* Is person slow? */
|
||||
extinguish(noslow);
|
||||
noslow();
|
||||
|
||||
if (blessed) hasttime = HASTETIME/2;
|
||||
else return;
|
||||
}
|
||||
|
||||
if (on(player, ISHASTE)) {
|
||||
msg("You faint from exhaustion.");
|
||||
no_command += rnd(hasttime);
|
||||
lengthen(nohaste, roll(hasttime,hasttime));
|
||||
}
|
||||
else {
|
||||
turn_on(player, ISHASTE);
|
||||
fuse(nohaste, 0, roll(hasttime, hasttime), AFTER);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Increase player's intelligence
|
||||
*/
|
||||
add_intelligence(cursed)
|
||||
bool cursed;
|
||||
{
|
||||
int ring_str; /* Value of ring strengths */
|
||||
|
||||
/* Undo any ring changes */
|
||||
ring_str = ring_value(R_ADDINTEL);
|
||||
pstats.s_intel -= ring_str;
|
||||
|
||||
/* Now do the potion */
|
||||
if (cursed) {
|
||||
msg("You feel slightly less intelligent now.");
|
||||
pstats.s_intel--;
|
||||
}
|
||||
else {
|
||||
msg("You feel more intelligent now. What a mind!");
|
||||
pstats.s_intel = min(pstats.s_intel + 1, 25);
|
||||
}
|
||||
|
||||
/* Adjust the maximum */
|
||||
if (max_stats.s_intel < pstats.s_intel)
|
||||
max_stats.s_intel = pstats.s_intel;
|
||||
|
||||
/* Now put back the ring changes */
|
||||
if (ring_str)
|
||||
pstats.s_intel += ring_str;
|
||||
}
|
||||
|
||||
/*
|
||||
* this routine makes the hero move slower
|
||||
*/
|
||||
add_slow()
|
||||
{
|
||||
if (on(player, ISHASTE)) { /* Already sped up */
|
||||
extinguish(nohaste);
|
||||
nohaste();
|
||||
}
|
||||
else {
|
||||
msg("You feel yourself moving %sslower.",
|
||||
on(player, ISSLOW) ? "even " : "");
|
||||
if (on(player, ISSLOW))
|
||||
lengthen(noslow, roll(HASTETIME,HASTETIME));
|
||||
else {
|
||||
turn_on(player, ISSLOW);
|
||||
player.t_turn = TRUE;
|
||||
fuse(noslow, 0, roll(HASTETIME,HASTETIME), AFTER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Increase player's strength
|
||||
*/
|
||||
|
||||
add_strength(cursed)
|
||||
bool cursed;
|
||||
{
|
||||
|
||||
if (cursed) {
|
||||
msg("You feel slightly weaker now.");
|
||||
chg_str(-1);
|
||||
}
|
||||
else {
|
||||
msg("You feel stronger now. What bulging muscles!");
|
||||
chg_str(1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Increase player's wisdom
|
||||
*/
|
||||
|
||||
add_wisdom(cursed)
|
||||
bool cursed;
|
||||
{
|
||||
int ring_str; /* Value of ring strengths */
|
||||
|
||||
/* Undo any ring changes */
|
||||
ring_str = ring_value(R_ADDWISDOM);
|
||||
pstats.s_wisdom -= ring_str;
|
||||
|
||||
/* Now do the potion */
|
||||
if (cursed) {
|
||||
msg("You feel slightly less wise now.");
|
||||
pstats.s_wisdom--;
|
||||
}
|
||||
else {
|
||||
msg("You feel wiser now. What a sage!");
|
||||
pstats.s_wisdom = min(pstats.s_wisdom + 1, 25);
|
||||
}
|
||||
|
||||
/* Adjust the maximum */
|
||||
if (max_stats.s_wisdom < pstats.s_wisdom)
|
||||
max_stats.s_wisdom = pstats.s_wisdom;
|
||||
|
||||
/* Now put back the ring changes */
|
||||
if (ring_str)
|
||||
pstats.s_wisdom += ring_str;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Lower a level of experience
|
||||
*/
|
||||
|
||||
lower_level(who)
|
||||
short who;
|
||||
{
|
||||
int fewer, nsides = 0;
|
||||
|
||||
if (--pstats.s_lvl == 0)
|
||||
death(who); /* All levels gone */
|
||||
msg("You suddenly feel less skillful.");
|
||||
pstats.s_exp /= 2;
|
||||
switch (player.t_ctype) {
|
||||
case C_FIGHTER: nsides = HIT_FIGHTER;
|
||||
when C_MAGICIAN:nsides = HIT_MAGICIAN;
|
||||
when C_CLERIC: nsides = HIT_CLERIC;
|
||||
when C_THIEF: nsides = HIT_THIEF;
|
||||
}
|
||||
fewer = max(1, roll(1,nsides) + const_bonus());
|
||||
pstats.s_hpt -= fewer;
|
||||
max_stats.s_hpt -= fewer;
|
||||
if (pstats.s_hpt < 1)
|
||||
pstats.s_hpt = 1;
|
||||
if (max_stats.s_hpt < 1)
|
||||
death(who);
|
||||
}
|
||||
|
||||
quaff(which, flag, is_potion)
|
||||
int which;
|
||||
int flag;
|
||||
bool is_potion;
|
||||
{
|
||||
register struct object *obj = NULL;
|
||||
register struct linked_list *item, *titem;
|
||||
register struct thing *th;
|
||||
bool cursed, blessed;
|
||||
char buf[LINELEN];
|
||||
|
||||
blessed = FALSE;
|
||||
cursed = FALSE;
|
||||
item = NULL;
|
||||
|
||||
if (which < 0) { /* figure out which ourselves */
|
||||
item = get_item(pack, "quaff", POTION);
|
||||
/*
|
||||
* Make certain that it is somethings that we want to drink
|
||||
*/
|
||||
if (item == NULL)
|
||||
return;
|
||||
|
||||
obj = OBJPTR(item);
|
||||
/* remove it from the pack */
|
||||
inpack--;
|
||||
detach(pack, item);
|
||||
|
||||
/*
|
||||
* Calculate the effect it has on the poor guy.
|
||||
*/
|
||||
cursed = (obj->o_flags & ISCURSED) != 0;
|
||||
blessed = (obj->o_flags & ISBLESSED) != 0;
|
||||
|
||||
which = obj->o_which;
|
||||
}
|
||||
else {
|
||||
cursed = flag & ISCURSED;
|
||||
blessed = flag & ISBLESSED;
|
||||
}
|
||||
|
||||
switch(which)
|
||||
{
|
||||
case P_CLEAR:
|
||||
if (cursed) {
|
||||
if (off(player, ISCLEAR))
|
||||
{
|
||||
msg("Wait, what's going on here. Huh? What? Who?");
|
||||
if (find_slot(unconfuse))
|
||||
lengthen(unconfuse, rnd(8)+HUHDURATION);
|
||||
else
|
||||
fuse(unconfuse, 0, rnd(8)+HUHDURATION, AFTER);
|
||||
turn_on(player, ISHUH);
|
||||
}
|
||||
else msg("You feel dizzy for a moment, but it quickly passes.");
|
||||
}
|
||||
else {
|
||||
if (blessed) { /* Make player immune for the whole game */
|
||||
extinguish(unclrhead); /* If we have a fuse, put it out */
|
||||
msg("A strong blue aura surrounds your head.");
|
||||
}
|
||||
else { /* Just light a fuse for how long player is safe */
|
||||
if (off(player, ISCLEAR)) {
|
||||
fuse(unclrhead, 0, CLRDURATION, AFTER);
|
||||
msg("A faint blue aura surrounds your head.");
|
||||
}
|
||||
else { /* If we have a fuse lengthen it, else we
|
||||
* are permanently clear.
|
||||
*/
|
||||
if (find_slot(unclrhead) == FALSE)
|
||||
msg("Your blue aura continues to glow strongly.");
|
||||
else {
|
||||
lengthen(unclrhead, CLRDURATION);
|
||||
msg("Your blue aura brightens for a moment.");
|
||||
}
|
||||
}
|
||||
}
|
||||
turn_on(player, ISCLEAR);
|
||||
/* If player is confused, unconfuse him */
|
||||
if (on(player, ISHUH)) {
|
||||
extinguish(unconfuse);
|
||||
unconfuse();
|
||||
}
|
||||
}
|
||||
when P_HEALING:
|
||||
if (cursed) {
|
||||
if (!save(VS_POISON, &player, 0)) {
|
||||
msg("You feel very sick now.");
|
||||
pstats.s_hpt /= 2;
|
||||
pstats.s_const--;
|
||||
if (pstats.s_const <= 0 || pstats.s_hpt <= 0)
|
||||
death(D_POISON);
|
||||
}
|
||||
else msg("You feel momentarily sick.");
|
||||
}
|
||||
else {
|
||||
if (blessed) {
|
||||
if ((pstats.s_hpt += roll(pstats.s_lvl, 8)) > max_stats.s_hpt)
|
||||
pstats.s_hpt = ++max_stats.s_hpt;
|
||||
if (on(player, ISHUH)) {
|
||||
extinguish(unconfuse);
|
||||
unconfuse();
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((pstats.s_hpt += roll(pstats.s_lvl, 4)) > max_stats.s_hpt)
|
||||
pstats.s_hpt = ++max_stats.s_hpt;
|
||||
}
|
||||
msg("You begin to feel %sbetter.",
|
||||
blessed ? "much " : "");
|
||||
sight();
|
||||
if (is_potion) p_know[P_HEALING] = TRUE;
|
||||
}
|
||||
when P_ABIL:
|
||||
{
|
||||
int ctype;
|
||||
|
||||
/*
|
||||
* if blessed then fix all attributes
|
||||
*/
|
||||
if (blessed) {
|
||||
add_intelligence(FALSE);
|
||||
add_dexterity(FALSE);
|
||||
add_strength(FALSE);
|
||||
add_wisdom(FALSE);
|
||||
add_const(FALSE);
|
||||
}
|
||||
/* probably will be own ability */
|
||||
else {
|
||||
if (rnd(100) < 70)
|
||||
ctype = player.t_ctype;
|
||||
else do {
|
||||
ctype = rnd(4);
|
||||
} while (ctype == player.t_ctype);
|
||||
|
||||
/* Small chance of doing constitution instead */
|
||||
if (rnd(100) < 10)
|
||||
add_const(cursed);
|
||||
else switch (ctype) {
|
||||
case C_FIGHTER: add_strength(cursed);
|
||||
when C_MAGICIAN: add_intelligence(cursed);
|
||||
when C_CLERIC: add_wisdom(cursed);
|
||||
when C_THIEF: add_dexterity(cursed);
|
||||
otherwise: msg("You're a strange type!");
|
||||
}
|
||||
}
|
||||
if (is_potion) p_know[P_ABIL] = TRUE;
|
||||
}
|
||||
when P_MFIND:
|
||||
/*
|
||||
* Potion of monster detection, if there are monters, detect them
|
||||
*/
|
||||
if (mlist != NULL)
|
||||
{
|
||||
msg("You begin to sense the presence of monsters.");
|
||||
waddstr(cw, morestr);
|
||||
overlay(mw, cw);
|
||||
draw(cw);
|
||||
wait_for(cw,' ');
|
||||
msg("");
|
||||
if (is_potion) p_know[P_MFIND] = TRUE;
|
||||
}
|
||||
else
|
||||
msg("You have a strange feeling for a moment, then it passes.");
|
||||
when P_TFIND:
|
||||
/*
|
||||
* Potion of magic detection. Show the potions and scrolls
|
||||
*/
|
||||
if (lvl_obj != NULL)
|
||||
{
|
||||
register struct linked_list *mobj;
|
||||
register struct object *tp;
|
||||
bool show;
|
||||
|
||||
show = FALSE;
|
||||
wclear(hw);
|
||||
for (mobj = lvl_obj; mobj != NULL; mobj = next(mobj)) {
|
||||
tp = OBJPTR(mobj);
|
||||
if (is_magic(tp)) {
|
||||
char mag_type=MAGIC;
|
||||
|
||||
/* Mark cursed items or bad weapons */
|
||||
if ((tp->o_flags & ISCURSED) ||
|
||||
(tp->o_type == WEAPON &&
|
||||
(tp->o_hplus < 0 || tp->o_dplus < 0)))
|
||||
mag_type = CMAGIC;
|
||||
else if ((tp->o_flags & ISBLESSED) ||
|
||||
(tp->o_type == WEAPON &&
|
||||
(tp->o_hplus > 0 || tp->o_dplus > 0)))
|
||||
mag_type = BMAGIC;
|
||||
show = TRUE;
|
||||
mvwaddch(hw, tp->o_pos.y, tp->o_pos.x, mag_type);
|
||||
}
|
||||
if (is_potion) p_know[P_TFIND] = TRUE;
|
||||
}
|
||||
for (titem = mlist; titem != NULL; titem = next(titem)) {
|
||||
register struct linked_list *pitem;
|
||||
|
||||
th = THINGPTR(titem);
|
||||
for(pitem = th->t_pack; pitem != NULL; pitem = next(pitem)){
|
||||
tp = OBJPTR(pitem);
|
||||
if (is_magic(tp)) {
|
||||
char mag_type=MAGIC;
|
||||
|
||||
/* Mark cursed items or bad weapons */
|
||||
if ((tp->o_flags & ISCURSED) ||
|
||||
(tp->o_type == WEAPON &&
|
||||
(tp->o_hplus < 0 || tp->o_dplus < 0)))
|
||||
mag_type = CMAGIC;
|
||||
else if ((tp->o_flags & ISBLESSED) ||
|
||||
(tp->o_type == WEAPON &&
|
||||
(tp->o_hplus > 0 || tp->o_dplus > 0)))
|
||||
mag_type = BMAGIC;
|
||||
show = TRUE;
|
||||
mvwaddch(hw, th->t_pos.y, th->t_pos.x, mag_type);
|
||||
}
|
||||
if (is_potion) p_know[P_TFIND] = TRUE;
|
||||
}
|
||||
}
|
||||
if (show) {
|
||||
msg("You sense the presence of magic on this level.");
|
||||
waddstr(cw, morestr);
|
||||
overlay(hw,cw);
|
||||
draw(cw);
|
||||
wait_for(cw,' ');
|
||||
msg("");
|
||||
break;
|
||||
}
|
||||
}
|
||||
msg("You have a strange feeling for a moment, then it passes.");
|
||||
when P_SEEINVIS:
|
||||
if (cursed) {
|
||||
if (!find_slot(sight))
|
||||
{
|
||||
msg("A cloak of darkness falls around you.");
|
||||
turn_on(player, ISBLIND);
|
||||
fuse(sight, 0, SEEDURATION, AFTER);
|
||||
light(&hero);
|
||||
}
|
||||
else
|
||||
lengthen(sight, SEEDURATION);
|
||||
}
|
||||
else {
|
||||
if (off(player, CANSEE)) {
|
||||
turn_on(player, CANSEE);
|
||||
msg("Your eyes begin to tingle.");
|
||||
fuse(unsee, 0, blessed ? SEEDURATION*3 :SEEDURATION, AFTER);
|
||||
light(&hero);
|
||||
}
|
||||
else if (find_slot(unsee) != FALSE)
|
||||
lengthen(unsee, blessed ? SEEDURATION*3 : SEEDURATION);
|
||||
sight();
|
||||
}
|
||||
when P_PHASE:
|
||||
if (cursed) {
|
||||
msg("You can't move.");
|
||||
no_command = FREEZETIME;
|
||||
}
|
||||
else {
|
||||
int duration;
|
||||
|
||||
if (blessed) duration = 3;
|
||||
else duration = 1;
|
||||
|
||||
if (on(player, CANINWALL))
|
||||
lengthen(unphase, duration*PHASEDURATION);
|
||||
else {
|
||||
fuse(unphase, 0, duration*PHASEDURATION, AFTER);
|
||||
turn_on(player, CANINWALL);
|
||||
}
|
||||
msg("You feel %slight-headed!",
|
||||
blessed ? "very " : "");
|
||||
}
|
||||
when P_FLY: {
|
||||
int duration;
|
||||
bool say_message;
|
||||
|
||||
say_message = TRUE;
|
||||
|
||||
if (blessed) duration = 3;
|
||||
else duration = 1;
|
||||
|
||||
if (on(player, ISFLY)) {
|
||||
if (find_slot(land))
|
||||
lengthen(land, duration*FLYTIME);
|
||||
else {
|
||||
msg("Nothing happens."); /* Flying by cloak */
|
||||
say_message = FALSE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
fuse(land, 0, duration*FLYTIME, AFTER);
|
||||
turn_on(player, ISFLY);
|
||||
}
|
||||
if (say_message)
|
||||
msg("You feel %slighter than air!", blessed ? "much " : "");
|
||||
}
|
||||
when P_RAISE:
|
||||
if (cursed) lower_level(D_POTION);
|
||||
else {
|
||||
msg("You suddenly feel %smore skillful",
|
||||
blessed ? "much " : "");
|
||||
p_know[P_RAISE] = TRUE;
|
||||
raise_level(TRUE);
|
||||
if (blessed) raise_level(TRUE);
|
||||
}
|
||||
when P_HASTE:
|
||||
if (cursed) { /* Slow player down */
|
||||
add_slow();
|
||||
}
|
||||
else {
|
||||
if (off(player, ISSLOW))
|
||||
msg("You feel yourself moving %sfaster.",
|
||||
blessed ? "much " : "");
|
||||
add_haste(blessed);
|
||||
if (is_potion) p_know[P_HASTE] = TRUE;
|
||||
}
|
||||
when P_RESTORE: {
|
||||
register int i;
|
||||
|
||||
msg("Hey, this tastes great. It make you feel warm all over.");
|
||||
if (lost_str) {
|
||||
extinguish(res_strength);
|
||||
lost_str = 0;
|
||||
}
|
||||
for (i=0; i<lost_dext; i++)
|
||||
extinguish(un_itch);
|
||||
lost_dext = 0;
|
||||
res_strength();
|
||||
res_wisdom();
|
||||
res_dexterity(0);
|
||||
res_intelligence();
|
||||
pstats.s_const = max_stats.s_const;
|
||||
}
|
||||
when P_INVIS:
|
||||
if (off(player, ISINVIS)) {
|
||||
turn_on(player, ISINVIS);
|
||||
msg("You have a tingling feeling all over your body");
|
||||
fuse(appear, 0, blessed ? GONETIME*3 : GONETIME, AFTER);
|
||||
PLAYER = IPLAYER;
|
||||
light(&hero);
|
||||
}
|
||||
else {
|
||||
if (find_slot(appear)) {
|
||||
msg("Your tingling feeling surges.");
|
||||
lengthen(appear, blessed ? GONETIME*3 : GONETIME);
|
||||
}
|
||||
else msg("Nothing happens."); /* Using cloak */
|
||||
}
|
||||
|
||||
otherwise:
|
||||
msg("What an odd tasting potion!");
|
||||
return;
|
||||
}
|
||||
status(FALSE);
|
||||
if (is_potion && p_know[which] && p_guess[which])
|
||||
{
|
||||
free(p_guess[which]);
|
||||
p_guess[which] = NULL;
|
||||
}
|
||||
else if (is_potion &&
|
||||
!p_know[which] &&
|
||||
askme &&
|
||||
(obj->o_flags & ISKNOW) == 0 &&
|
||||
(obj->o_flags & ISPOST) == 0 &&
|
||||
p_guess[which] == NULL)
|
||||
{
|
||||
msg(terse ? "Call it: " : "What do you want to call it? ");
|
||||
if (get_str(buf, cw) == NORM)
|
||||
{
|
||||
p_guess[which] = new((unsigned int) strlen(buf) + 1);
|
||||
strcpy(p_guess[which], buf);
|
||||
}
|
||||
}
|
||||
if (item != NULL) o_discard(item);
|
||||
updpack(TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* res_dexterity:
|
||||
* Restore player's dexterity
|
||||
* if called with zero the restore fully
|
||||
*/
|
||||
|
||||
res_dexterity(howmuch)
|
||||
int howmuch;
|
||||
{
|
||||
short save_max;
|
||||
int ring_str;
|
||||
|
||||
/* Discount the ring value */
|
||||
ring_str = ring_value(R_ADDHIT);
|
||||
pstats.s_dext -= ring_str;
|
||||
|
||||
if (pstats.s_dext < max_stats.s_dext ) {
|
||||
if (howmuch == 0)
|
||||
pstats.s_dext = max_stats.s_dext;
|
||||
else
|
||||
pstats.s_dext = min(pstats.s_dext+howmuch, max_stats.s_dext);
|
||||
}
|
||||
|
||||
/* Redo the rings */
|
||||
if (ring_str) {
|
||||
save_max = max_stats.s_dext;
|
||||
pstats.s_dext += ring_str;
|
||||
max_stats.s_dext = save_max;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* res_intelligence:
|
||||
* Restore player's intelligence
|
||||
*/
|
||||
|
||||
res_intelligence()
|
||||
{
|
||||
short save_max;
|
||||
int ring_str;
|
||||
|
||||
/* Discount the ring value */
|
||||
ring_str = ring_value(R_ADDINTEL);
|
||||
pstats.s_intel -= ring_str;
|
||||
|
||||
if (pstats.s_intel < max_stats.s_intel ) pstats.s_intel = max_stats.s_intel;
|
||||
|
||||
/* Redo the rings */
|
||||
if (ring_str) {
|
||||
save_max = max_stats.s_intel;
|
||||
pstats.s_intel += ring_str;
|
||||
max_stats.s_intel = save_max;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* res_wisdom:
|
||||
* Restore player's wisdom
|
||||
*/
|
||||
|
||||
res_wisdom()
|
||||
{
|
||||
short save_max;
|
||||
int ring_str;
|
||||
|
||||
/* Discount the ring value */
|
||||
ring_str = ring_value(R_ADDWISDOM);
|
||||
pstats.s_wisdom -= ring_str;
|
||||
|
||||
if (pstats.s_wisdom < max_stats.s_wisdom )
|
||||
pstats.s_wisdom = max_stats.s_wisdom;
|
||||
|
||||
/* Redo the rings */
|
||||
if (ring_str) {
|
||||
save_max = max_stats.s_wisdom;
|
||||
pstats.s_wisdom += ring_str;
|
||||
max_stats.s_wisdom = save_max;
|
||||
}
|
||||
}
|
||||
161
arogue5/rings.c
Normal file
161
arogue5/rings.c
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* routines dealing specifically with rings
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "curses.h"
|
||||
#include "rogue.h"
|
||||
|
||||
/*
|
||||
* how much food does this ring use up?
|
||||
*/
|
||||
ring_eat(hand)
|
||||
register int hand;
|
||||
{
|
||||
if (cur_ring[hand] == NULL)
|
||||
return 0;
|
||||
switch (cur_ring[hand]->o_which) {
|
||||
case R_VAMPREGEN:
|
||||
return 3;
|
||||
case R_REGEN:
|
||||
return 2;
|
||||
case R_HEALTH:
|
||||
case R_SUSABILITY:
|
||||
return 1;
|
||||
case R_SEARCH:
|
||||
case R_SEEINVIS:
|
||||
return (rnd(100) < 33);
|
||||
case R_DIGEST:
|
||||
if (cur_ring[hand]->o_ac >= 0)
|
||||
return (-(cur_ring[hand]->o_ac)-1);
|
||||
else
|
||||
return (-(cur_ring[hand]->o_ac));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ring_on(obj)
|
||||
register struct object *obj;
|
||||
{
|
||||
register int save_max;
|
||||
char buf[LINELEN];
|
||||
|
||||
/*
|
||||
* Calculate the effect it has on the poor guy.
|
||||
*/
|
||||
switch (obj->o_which)
|
||||
{
|
||||
case R_ADDSTR:
|
||||
save_max = max_stats.s_str;
|
||||
chg_str(obj->o_ac);
|
||||
max_stats.s_str = save_max;
|
||||
when R_ADDHIT:
|
||||
pstats.s_dext += obj->o_ac;
|
||||
when R_ADDINTEL:
|
||||
pstats.s_intel += obj->o_ac;
|
||||
when R_ADDWISDOM:
|
||||
pstats.s_wisdom += obj->o_ac;
|
||||
when R_SEEINVIS:
|
||||
turn_on(player, CANSEE);
|
||||
msg("Your eyes begin to tingle");
|
||||
light(&hero);
|
||||
mvwaddch(cw, hero.y, hero.x, PLAYER);
|
||||
when R_AGGR:
|
||||
aggravate();
|
||||
when R_WARMTH:
|
||||
turn_on(player, NOCOLD);
|
||||
when R_FIRE:
|
||||
turn_on(player, NOFIRE);
|
||||
when R_LIGHT: {
|
||||
if(roomin(&hero) != NULL) {
|
||||
light(&hero);
|
||||
mvwaddch(cw, hero.y, hero.x, PLAYER);
|
||||
}
|
||||
}
|
||||
when R_SEARCH:
|
||||
daemon(ring_search, 0, AFTER);
|
||||
when R_TELEPORT:
|
||||
daemon(ring_teleport, 0, AFTER);
|
||||
}
|
||||
status(FALSE);
|
||||
if (r_know[obj->o_which] && r_guess[obj->o_which])
|
||||
{
|
||||
free(r_guess[obj->o_which]);
|
||||
r_guess[obj->o_which] = NULL;
|
||||
}
|
||||
else if (!r_know[obj->o_which] &&
|
||||
askme &&
|
||||
(obj->o_flags & ISKNOW) == 0 &&
|
||||
r_guess[obj->o_which] == NULL) {
|
||||
msg(terse ? "Call it: " : "What do you want to call it? ");
|
||||
if (get_str(buf, cw) == NORM)
|
||||
{
|
||||
r_guess[obj->o_which] = new((unsigned int) strlen(buf) + 1);
|
||||
strcpy(r_guess[obj->o_which], buf);
|
||||
}
|
||||
msg("");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* print ring bonuses
|
||||
*/
|
||||
char *
|
||||
ring_num(obj)
|
||||
register struct object *obj;
|
||||
{
|
||||
static char buf[5];
|
||||
|
||||
if (!(obj->o_flags & ISKNOW))
|
||||
return "";
|
||||
switch (obj->o_which)
|
||||
{
|
||||
case R_PROTECT:
|
||||
case R_ADDSTR:
|
||||
case R_ADDDAM:
|
||||
case R_ADDHIT:
|
||||
case R_ADDINTEL:
|
||||
case R_ADDWISDOM:
|
||||
case R_DIGEST:
|
||||
buf[0] = ' ';
|
||||
strcpy(&buf[1], num(obj->o_ac, 0));
|
||||
when R_AGGR:
|
||||
case R_LIGHT:
|
||||
case R_HEAVY:
|
||||
case R_TELEPORT:
|
||||
if (obj->o_flags & ISCURSED)
|
||||
return " cursed";
|
||||
else
|
||||
return "";
|
||||
otherwise:
|
||||
return "";
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the effect of the specified ring
|
||||
*/
|
||||
ring_value(type)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if (ISRING(LEFT_1, type)) result += cur_ring[LEFT_1]->o_ac;
|
||||
if (ISRING(LEFT_2, type)) result += cur_ring[LEFT_2]->o_ac;
|
||||
if (ISRING(LEFT_3, type)) result += cur_ring[LEFT_3]->o_ac;
|
||||
if (ISRING(LEFT_4, type)) result += cur_ring[LEFT_4]->o_ac;
|
||||
if (ISRING(RIGHT_1, type)) result += cur_ring[RIGHT_1]->o_ac;
|
||||
if (ISRING(RIGHT_2, type)) result += cur_ring[RIGHT_2]->o_ac;
|
||||
if (ISRING(RIGHT_3, type)) result += cur_ring[RIGHT_3]->o_ac;
|
||||
if (ISRING(RIGHT_4, type)) result += cur_ring[RIGHT_4]->o_ac;
|
||||
return(result);
|
||||
}
|
||||
768
arogue5/rip.c
Normal file
768
arogue5/rip.c
Normal file
|
|
@ -0,0 +1,768 @@
|
|||
/*
|
||||
* File for the fun ends
|
||||
* Death or a total win
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
/* Print flags for scoring */
|
||||
#define REALLIFE 1 /* Print out machine and logname */
|
||||
#define EDITSCORE 2 /* Edit the current score file */
|
||||
#define ADDSCORE 3 /* Add a new score */
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "curses.h"
|
||||
#include <time.h>
|
||||
#include <signal.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include "network.h"
|
||||
#include "rogue.h"
|
||||
#include "mach_dep.h"
|
||||
|
||||
/*
|
||||
* If you change this structure, change the compatibility routines
|
||||
* scoreout() and scorein() to reflect the change. Also update SCORELEN.
|
||||
*/
|
||||
|
||||
struct sc_ent {
|
||||
unsigned long sc_score;
|
||||
char sc_name[LINELEN];
|
||||
char sc_system[SYSLEN];
|
||||
char sc_login[LOGLEN];
|
||||
short sc_flgs;
|
||||
short sc_level;
|
||||
short sc_ctype;
|
||||
short sc_monster;
|
||||
short sc_quest;
|
||||
};
|
||||
|
||||
#define SCORELEN \
|
||||
(sizeof(unsigned long) + LINELEN + SYSLEN + LOGLEN + 5*sizeof(short))
|
||||
|
||||
static char *rip[] = {
|
||||
" __________",
|
||||
" / \\",
|
||||
" / REST \\",
|
||||
" / IN \\",
|
||||
" / PEACE \\",
|
||||
" / \\",
|
||||
" | |",
|
||||
" | |",
|
||||
" | killed by |",
|
||||
" | |",
|
||||
" | 1984 |",
|
||||
" *| * * * | *",
|
||||
" ________)/\\\\_//(\\/(/\\)/\\//\\/|_)_______",
|
||||
0
|
||||
};
|
||||
|
||||
char *killname();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
byebye(sig)
|
||||
int sig;
|
||||
{
|
||||
NOOP(sig);
|
||||
if (!isendwin()) {
|
||||
clear();
|
||||
endwin();
|
||||
}
|
||||
printf("\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* death:
|
||||
* Do something really fun when he dies
|
||||
*/
|
||||
|
||||
death(monst)
|
||||
register short monst;
|
||||
{
|
||||
register char **dp = rip, *killer;
|
||||
register struct tm *lt;
|
||||
time_t date;
|
||||
char buf[80];
|
||||
struct tm *localtime();
|
||||
|
||||
time(&date);
|
||||
lt = localtime(&date);
|
||||
clear();
|
||||
move(8, 0);
|
||||
while (*dp)
|
||||
printw("%s\n", *dp++);
|
||||
mvaddstr(14, 28-((strlen(whoami)+1)/2), whoami);
|
||||
sprintf(buf, "%lu Points", pstats.s_exp );
|
||||
mvaddstr(15, 28-((strlen(buf)+1)/2), buf);
|
||||
killer = killname(monst);
|
||||
mvaddstr(17, 28-((strlen(killer)+1)/2), killer);
|
||||
mvaddstr(18, 26, (sprintf(prbuf, "%4d", 1900+lt->tm_year), prbuf));
|
||||
move(LINES-1, 0);
|
||||
refresh();
|
||||
score(pstats.s_exp, KILLED, monst);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
char *
|
||||
killname(monst)
|
||||
register short monst;
|
||||
{
|
||||
static char mons_name[LINELEN];
|
||||
int i;
|
||||
|
||||
if (monst > NUMMONST) return("a strange monster");
|
||||
|
||||
if (monst >= 0) {
|
||||
switch (monsters[monst].m_name[0]) {
|
||||
case 'a':
|
||||
case 'e':
|
||||
case 'i':
|
||||
case 'o':
|
||||
case 'u':
|
||||
sprintf(mons_name, "an %s", monsters[monst].m_name);
|
||||
break;
|
||||
default:
|
||||
sprintf(mons_name, "a %s", monsters[monst].m_name);
|
||||
}
|
||||
return(mons_name);
|
||||
}
|
||||
for (i = 0; i< DEATHNUM; i++) {
|
||||
if (deaths[i].reason == monst)
|
||||
break;
|
||||
}
|
||||
if (i >= DEATHNUM)
|
||||
return ("strange death");
|
||||
return (deaths[i].name);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* score -- figure score and post it.
|
||||
*/
|
||||
|
||||
/* VARARGS2 */
|
||||
score(amount, flags, monst)
|
||||
unsigned long amount;
|
||||
short monst;
|
||||
{
|
||||
static struct sc_ent top_ten[NUMSCORE];
|
||||
register struct sc_ent *scp;
|
||||
register int i;
|
||||
register struct sc_ent *sc2;
|
||||
register FILE *outf;
|
||||
register char *killer;
|
||||
register int prflags = 0;
|
||||
register int fd;
|
||||
short upquest = 0, wintype = 0, uplevel = 0, uptype = 0; /* For network updating */
|
||||
char upsystem[SYSLEN], uplogin[LOGLEN];
|
||||
char *thissys; /* Holds the name of this system */
|
||||
char *compatstr=NULL; /* Holds scores for writing compatible score files */
|
||||
#define REASONLEN 3
|
||||
static char *reason[] = {
|
||||
"killed",
|
||||
"quit",
|
||||
"A total winner",
|
||||
"somehow left",
|
||||
};
|
||||
char *packend;
|
||||
memset(top_ten,0,sizeof(top_ten));
|
||||
signal(SIGINT, byebye);
|
||||
if (flags != WINNER && flags != SCOREIT && flags != UPDATE) {
|
||||
if (flags == CHICKEN)
|
||||
packend = "when you quit";
|
||||
else
|
||||
packend = "at your untimely demise";
|
||||
mvaddstr(LINES - 1, 0, retstr);
|
||||
refresh();
|
||||
wgetnstr(cw,prbuf,80);
|
||||
showpack(packend);
|
||||
}
|
||||
purse = 0; /* Steal all the gold */
|
||||
|
||||
/*
|
||||
* Open file and read list
|
||||
*/
|
||||
|
||||
if ((fd = open(score_file, O_RDWR | O_CREAT, 0666)) < 0)
|
||||
{
|
||||
printf("\nCannot open score_file.\n");
|
||||
return;
|
||||
}
|
||||
outf = (FILE *) fdopen(fd, "w");
|
||||
|
||||
/* Get this system's name */
|
||||
thissys = md_gethostname();
|
||||
|
||||
for (scp = top_ten; scp <= &top_ten[NUMSCORE-1]; scp++)
|
||||
{
|
||||
scp->sc_score = 0L;
|
||||
for (i = 0; i < 80; i++)
|
||||
scp->sc_name[i] = rnd(255);
|
||||
scp->sc_quest= RN;
|
||||
scp->sc_flgs = RN;
|
||||
scp->sc_level = RN;
|
||||
scp->sc_monster = RN;
|
||||
scp->sc_ctype = 0;
|
||||
strncpy(scp->sc_system, thissys, SYSLEN);
|
||||
scp->sc_login[0] = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* If this is a SCOREIT optin (rogue -s), don't call byebye. The
|
||||
* endwin() call in byebye() will result in a core dump.
|
||||
*/
|
||||
if (flags == SCOREIT) signal(SIGINT, SIG_DFL);
|
||||
else signal(SIGINT, byebye);
|
||||
|
||||
if (flags != SCOREIT && flags != UPDATE)
|
||||
{
|
||||
mvaddstr(LINES - 1, 0, retstr);
|
||||
refresh();
|
||||
fflush(stdout);
|
||||
wgetnstr(stdscr,prbuf,80);
|
||||
}
|
||||
|
||||
/* Check for special options */
|
||||
if (strcmp(prbuf, "names") == 0)
|
||||
prflags = REALLIFE;
|
||||
#ifdef WIZARD
|
||||
else if (wizard) {
|
||||
if (strcmp(prbuf, "edit") == 0) prflags = EDITSCORE;
|
||||
else if (strcmp(prbuf, "add") == 0) {
|
||||
prflags = ADDSCORE;
|
||||
waswizard = FALSE; /* We want the new score recorded */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Read the score and convert it to a compatible format */
|
||||
scorein(top_ten, fd); /* Convert it */
|
||||
|
||||
/* Get some values if this is an update */
|
||||
if (flags == UPDATE) {
|
||||
int errcheck, errors = 0;
|
||||
|
||||
upquest = (short) netread(&errcheck, sizeof(short), stdin);
|
||||
if (errcheck) errors++;
|
||||
|
||||
if (fread(whoami, 1, LINELEN, stdin) != LINELEN) errors++;
|
||||
|
||||
wintype = (short) netread(&errcheck, sizeof(short), stdin);
|
||||
if (errcheck) errors++;
|
||||
|
||||
uplevel = (short) netread(&errcheck, sizeof(short), stdin);
|
||||
if (errcheck) errors++;
|
||||
|
||||
uptype = (short) netread(&errcheck, sizeof(short), stdin);
|
||||
if (errcheck) errors++;
|
||||
|
||||
if (fread(upsystem, 1, SYSLEN, stdin) != SYSLEN)
|
||||
errors++;
|
||||
if (fread(uplogin, 1, LOGLEN, stdin) != LOGLEN)
|
||||
errors++;
|
||||
|
||||
if (errors) {
|
||||
fclose(outf);
|
||||
free(compatstr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert player in list if need be
|
||||
*/
|
||||
if (!waswizard) {
|
||||
char *login = NULL;
|
||||
|
||||
if (flags != UPDATE) {
|
||||
login = md_getusername();
|
||||
}
|
||||
|
||||
if (flags == UPDATE)
|
||||
(void) update(top_ten, amount, upquest, whoami, wintype,
|
||||
uplevel, monst, uptype, upsystem, uplogin);
|
||||
else {
|
||||
#ifdef WIZARD
|
||||
if (prflags == ADDSCORE) { /* Overlay characteristic by new ones */
|
||||
char buffer[80];
|
||||
int atoi();
|
||||
|
||||
clear();
|
||||
mvaddstr(1, 0, "Score: ");
|
||||
mvaddstr(2, 0, "Quest (number): ");
|
||||
mvaddstr(3, 0, "Name: ");
|
||||
mvaddstr(4, 0, "System: ");
|
||||
mvaddstr(5, 0, "Login: ");
|
||||
mvaddstr(6, 0, "Level: ");
|
||||
mvaddstr(7, 0, "Char type: ");
|
||||
mvaddstr(8, 0, "Result: ");
|
||||
|
||||
/* Get the score */
|
||||
move(1, 7);
|
||||
get_str(buffer, stdscr);
|
||||
amount = atol(buffer);
|
||||
|
||||
/* Get the character's quest -- must be a number */
|
||||
move(2, 16);
|
||||
get_str(buffer, stdscr);
|
||||
quest_item = atoi(buffer);
|
||||
|
||||
/* Get the character's name */
|
||||
move(3, 6);
|
||||
get_str(buffer, stdscr);
|
||||
strncpy(whoami, buffer, LINELEN);
|
||||
|
||||
/* Get the system */
|
||||
move(4, 8);
|
||||
get_str(buffer, stdscr);
|
||||
strncpy(thissys, buffer, SYSLEN);
|
||||
|
||||
/* Get the login */
|
||||
move(5, 7);
|
||||
get_str(buffer, stdscr);
|
||||
strncpy(login, buffer, LOGLEN);
|
||||
|
||||
/* Get the level */
|
||||
move(6, 7);
|
||||
get_str(buffer, stdscr);
|
||||
level = max_level = (short) atoi(buffer);
|
||||
|
||||
/* Get the character type */
|
||||
move(7, 11);
|
||||
get_str(buffer, stdscr);
|
||||
switch (buffer[0]) {
|
||||
case 'F':
|
||||
case 'f':
|
||||
default:
|
||||
player.t_ctype = C_FIGHTER;
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
case 'c':
|
||||
player.t_ctype = C_CLERIC;
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
case 'm':
|
||||
player.t_ctype = C_MAGICIAN;
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
case 't':
|
||||
player.t_ctype = C_THIEF;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get the win type */
|
||||
move(8, 8);
|
||||
get_str(buffer, stdscr);
|
||||
switch (buffer[0]) {
|
||||
case 'W':
|
||||
case 'w':
|
||||
case 'T':
|
||||
case 't':
|
||||
flags = WINNER;
|
||||
break;
|
||||
|
||||
case 'Q':
|
||||
case 'q':
|
||||
flags = CHICKEN;
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
case 'K':
|
||||
default:
|
||||
flags = KILLED;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get the monster if player was killed */
|
||||
if (flags == KILLED) {
|
||||
mvaddstr(9, 0, "Death type: ");
|
||||
get_str(buffer, stdscr);
|
||||
if (buffer[0] == 'M' || buffer[0] == 'm')
|
||||
monst = makemonster(FALSE);
|
||||
else monst = getdeath();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (update(top_ten, amount, (short) quest_item, whoami, flags,
|
||||
(flags == WINNER) ? (short) max_level : (short) level,
|
||||
monst, player.t_ctype, thissys, login)
|
||||
#ifdef NUMNET
|
||||
&& fork() == 0 /* Spin off network process */
|
||||
#endif
|
||||
) {
|
||||
#ifdef NUMNET
|
||||
/* Send this update to the other systems in the network */
|
||||
int i, j;
|
||||
char cmd[256]; /* Command for remote execution */
|
||||
FILE *rmf, *popen(); /* For input to remote command */
|
||||
|
||||
for (i=0; i<NUMNET; i++)
|
||||
if (Network[i].system[0] != '!' &&
|
||||
strcmp(Network[i].system, thissys)) {
|
||||
sprintf(cmd,
|
||||
"usend -s -d%s -uNoLogin -!'%s -u' - 2>/dev/null",
|
||||
Network[i].system, Network[i].rogue);
|
||||
|
||||
/* Execute the command */
|
||||
if ((rmf=popen(cmd, "w")) != NULL) {
|
||||
unsigned long temp; /* Temporary value */
|
||||
|
||||
/* Write out the parameters */
|
||||
(void) netwrite((unsigned long) amount,
|
||||
sizeof(unsigned long), rmf);
|
||||
|
||||
(void) netwrite((unsigned long) monst,
|
||||
sizeof(short), rmf);
|
||||
|
||||
(void) netwrite((unsigned long) quest_item,
|
||||
sizeof(short), rmf);
|
||||
|
||||
(void) fwrite(whoami, 1, strlen(whoami), rmf);
|
||||
for (j=strlen(whoami); j<LINELEN; j++)
|
||||
putc('\0', rmf);
|
||||
|
||||
(void) netwrite((unsigned long) flags,
|
||||
sizeof(short), rmf);
|
||||
|
||||
temp = (unsigned long)
|
||||
(flags==WINNER ? max_level : level);
|
||||
(void) netwrite(temp, sizeof(short), rmf);
|
||||
|
||||
(void) netwrite((unsigned long) player.t_ctype,
|
||||
sizeof(short), rmf);
|
||||
|
||||
(void) fwrite(thissys, 1,
|
||||
strlen(thissys), rmf);
|
||||
for (j=strlen(thissys); j<SYSLEN; j++)
|
||||
putc('\0', rmf);
|
||||
|
||||
(void) fwrite(login, 1, strlen(login), rmf);
|
||||
for (j=strlen(login); j<LOGLEN; j++)
|
||||
putc('\0', rmf);
|
||||
|
||||
/* Close off the command */
|
||||
(void) pclose(rmf);
|
||||
}
|
||||
}
|
||||
_exit(0); /* Exit network process */
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SCOREIT -- rogue -s option. Never started curses if this option.
|
||||
* UPDATE -- network scoring update. Never started curses if this option.
|
||||
* EDITSCORE -- want to delete or change a score.
|
||||
*/
|
||||
/* if (flags != SCOREIT && flags != UPDATE && prflags != EDITSCORE)
|
||||
endwin(); */
|
||||
|
||||
if (flags != UPDATE) {
|
||||
if (flags != SCOREIT) {
|
||||
clear();
|
||||
refresh();
|
||||
endwin();
|
||||
}
|
||||
/*
|
||||
* Print the list
|
||||
*/
|
||||
printf("\nTop %d Adventurers:\nRank Score\tName\n",
|
||||
NUMSCORE);
|
||||
|
||||
for (scp = top_ten; scp <= &top_ten[NUMSCORE-1]; scp++) {
|
||||
char *class;
|
||||
|
||||
if (scp->sc_score != 0) {
|
||||
switch (scp->sc_ctype) {
|
||||
case C_FIGHTER: class = "fighter";
|
||||
when C_MAGICIAN: class = "magician";
|
||||
when C_CLERIC: class = "cleric";
|
||||
when C_THIEF: class = "thief";
|
||||
otherwise: class = "unknown";
|
||||
}
|
||||
|
||||
/* Make sure we have an in-bound reason */
|
||||
if (scp->sc_flgs > REASONLEN) scp->sc_flgs = REASONLEN;
|
||||
|
||||
printf("%3d %10lu\t%s (%s)", scp - top_ten + 1,
|
||||
scp->sc_score, scp->sc_name, class);
|
||||
|
||||
if (prflags == REALLIFE) printf(" [in real life %.*s!%.*s]",
|
||||
SYSLEN, scp->sc_system, LOGLEN, scp->sc_login);
|
||||
printf(":\n\t\t%s on level %d", reason[scp->sc_flgs],
|
||||
scp->sc_level);
|
||||
|
||||
switch (scp->sc_flgs) {
|
||||
case KILLED:
|
||||
printf(" by");
|
||||
killer = killname(scp->sc_monster);
|
||||
printf(" %s", killer);
|
||||
break;
|
||||
|
||||
case WINNER:
|
||||
printf(" with the %s",
|
||||
rel_magic[scp->sc_quest].mi_name);
|
||||
break;
|
||||
}
|
||||
|
||||
if (prflags == EDITSCORE)
|
||||
{
|
||||
fflush(stdout);
|
||||
fgets(prbuf,80,stdin);
|
||||
printf("\n");
|
||||
if (prbuf[0] == 'd') {
|
||||
for (sc2 = scp; sc2 < &top_ten[NUMSCORE-1]; sc2++)
|
||||
*sc2 = *(sc2 + 1);
|
||||
top_ten[NUMSCORE-1].sc_score = 0;
|
||||
for (i = 0; i < 80; i++)
|
||||
top_ten[NUMSCORE-1].sc_name[i] = rnd(255);
|
||||
top_ten[NUMSCORE-1].sc_flgs = RN;
|
||||
top_ten[NUMSCORE-1].sc_level = RN;
|
||||
top_ten[NUMSCORE-1].sc_monster = RN;
|
||||
scp--;
|
||||
}
|
||||
else if (prbuf[0] == 'e') {
|
||||
printf("Death type: ");
|
||||
fgets(prbuf,80,stdin);
|
||||
if (prbuf[0] == 'M' || prbuf[0] == 'm')
|
||||
scp->sc_monster = makemonster(FALSE);
|
||||
else scp->sc_monster = getdeath();
|
||||
clear();
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
else printf("\n");
|
||||
}
|
||||
}
|
||||
if ((flags != SCOREIT) && (flags != UPDATE)) {
|
||||
printf("\n[Press return to exit]");
|
||||
fflush(stdout);
|
||||
fgets(prbuf,80,stdin);
|
||||
}
|
||||
/* if (prflags == EDITSCORE) endwin(); */ /* End editing windowing */
|
||||
}
|
||||
fseek(outf, 0L, 0);
|
||||
/*
|
||||
* Update the list file
|
||||
*/
|
||||
scoreout(top_ten, outf);
|
||||
fclose(outf);
|
||||
}
|
||||
|
||||
/*
|
||||
* scorein:
|
||||
* Convert a character string that has been translated from a
|
||||
* score file by scoreout() back to a score file structure.
|
||||
*/
|
||||
scorein(scores, fd)
|
||||
struct sc_ent scores[];
|
||||
int fd;
|
||||
{
|
||||
int i;
|
||||
char scoreline[100];
|
||||
|
||||
for(i = 0; i < NUMSCORE; i++)
|
||||
{
|
||||
encread((char *) &scores[i].sc_name, LINELEN, fd);
|
||||
encread((char *) &scores[i].sc_system, SYSLEN, fd);
|
||||
encread((char *) &scores[i].sc_login, LINELEN, fd);
|
||||
encread((char *) scoreline, 100, fd);
|
||||
sscanf(scoreline, " %lu %d %d %d %d %d \n",
|
||||
&scores[i].sc_score, &scores[i].sc_flgs,
|
||||
&scores[i].sc_level, &scores[i].sc_ctype,
|
||||
&scores[i].sc_monster, &scores[i].sc_quest);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* scoreout:
|
||||
* Convert a score file structure to a character string. We do
|
||||
* this for compatibility sake since some machines write out fields in
|
||||
* different orders.
|
||||
*/
|
||||
scoreout(scores, outf)
|
||||
struct sc_ent scores[];
|
||||
FILE *outf;
|
||||
{
|
||||
int i;
|
||||
char scoreline[100];
|
||||
|
||||
for(i = 0; i < NUMSCORE; i++) {
|
||||
memset(scoreline,0,100);
|
||||
encwrite((char *) scores[i].sc_name, LINELEN, outf);
|
||||
encwrite((char *) scores[i].sc_system, SYSLEN, outf);
|
||||
encwrite((char *) scores[i].sc_login, LINELEN, outf);
|
||||
sprintf(scoreline, " %lu %d %d %d %d %d \n",
|
||||
scores[i].sc_score, scores[i].sc_flgs,
|
||||
scores[i].sc_level, scores[i].sc_ctype,
|
||||
scores[i].sc_monster,scores[i].sc_quest);
|
||||
encwrite((char *) scoreline, 100, outf);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* showpack:
|
||||
* Display the contents of the hero's pack
|
||||
*/
|
||||
showpack(howso)
|
||||
char *howso;
|
||||
{
|
||||
reg char *iname;
|
||||
reg int cnt, packnum;
|
||||
reg struct linked_list *item;
|
||||
reg struct object *obj;
|
||||
|
||||
idenpack();
|
||||
cnt = 1;
|
||||
clear();
|
||||
mvprintw(0, 0, "Contents of your pack %s:\n",howso);
|
||||
packnum = 'a';
|
||||
for (item = pack; item != NULL; item = next(item)) {
|
||||
obj = OBJPTR(item);
|
||||
iname = inv_name(obj, FALSE);
|
||||
mvprintw(cnt, 0, "%c) %s\n",packnum++,iname);
|
||||
if (++cnt >= LINES - 2 &&
|
||||
next(item) != NULL) {
|
||||
cnt = 1;
|
||||
mvaddstr(LINES - 1, 0, morestr);
|
||||
refresh();
|
||||
wait_for(stdscr,' ');
|
||||
clear();
|
||||
}
|
||||
}
|
||||
mvprintw(cnt + 1,0,"--- %d Gold Pieces ---",purse);
|
||||
refresh();
|
||||
}
|
||||
|
||||
total_winner()
|
||||
{
|
||||
register struct linked_list *item;
|
||||
register struct object *obj;
|
||||
register int worth;
|
||||
register char c;
|
||||
register int oldpurse;
|
||||
|
||||
clear();
|
||||
standout();
|
||||
addstr(" \n");
|
||||
addstr(" @ @ @ @ @ @@@ @ @ \n");
|
||||
addstr(" @ @ @@ @@ @ @ @ @ \n");
|
||||
addstr(" @ @ @@@ @ @ @ @ @ @@@ @@@@ @@@ @ @@@ @ \n");
|
||||
addstr(" @@@@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ \n");
|
||||
addstr(" @ @ @ @ @ @ @ @@@@ @ @ @@@@@ @ @ @ \n");
|
||||
addstr(" @ @ @ @ @ @@ @ @ @ @ @ @ @ @ @ @ \n");
|
||||
addstr(" @@@ @@@ @@ @ @ @ @@@@ @@@@ @@@ @@@ @@ @ \n");
|
||||
addstr(" \n");
|
||||
addstr(" Congratulations, you have made it to the light of day! \n");
|
||||
standend();
|
||||
addstr("\nYou have joined the elite ranks of those who have escaped the\n");
|
||||
addstr("Dungeons of Doom alive. You journey home and sell all your loot at\n");
|
||||
addstr("a great profit and are appointed leader of a ");
|
||||
switch (player.t_ctype) {
|
||||
case C_MAGICIAN:addstr("magic user's guild.\n");
|
||||
when C_FIGHTER: addstr("fighters guild.\n");
|
||||
when C_CLERIC: addstr("monastery.\n");
|
||||
when C_THIEF: addstr("thief's guild.\n");
|
||||
otherwise: addstr("tavern.\n");
|
||||
}
|
||||
mvaddstr(LINES - 1, 0, spacemsg);
|
||||
refresh();
|
||||
wait_for(stdscr,' ');
|
||||
clear();
|
||||
mvaddstr(0, 0, " Worth Item");
|
||||
oldpurse = purse;
|
||||
for (c = 'a', item = pack; item != NULL; c++, item = next(item))
|
||||
{
|
||||
obj = OBJPTR(item);
|
||||
worth = get_worth(obj);
|
||||
if (obj->o_group == 0)
|
||||
worth *= obj->o_count;
|
||||
whatis(item);
|
||||
mvprintw(c - 'a' + 1, 0, "%c) %6d %s", c, worth, inv_name(obj, FALSE));
|
||||
purse += worth;
|
||||
}
|
||||
mvprintw(c - 'a' + 1, 0," %5d Gold Pieces ", oldpurse);
|
||||
refresh();
|
||||
score(pstats.s_exp + (long) purse, WINNER, '\0');
|
||||
exit(0);
|
||||
}
|
||||
|
||||
update(top_ten, amount, quest, whoami, flags, level, monst, ctype, system, login)
|
||||
struct sc_ent top_ten[];
|
||||
unsigned long amount;
|
||||
short quest, flags, level, monst, ctype;
|
||||
char *whoami, *system, *login;
|
||||
{
|
||||
register struct sc_ent *scp, *sc2;
|
||||
int retval=0; /* 1 if a change, 0 otherwise */
|
||||
|
||||
for (scp = top_ten; scp < &top_ten[NUMSCORE]; scp++) {
|
||||
if (amount >= scp->sc_score)
|
||||
break;
|
||||
|
||||
#ifdef LIMITSCORE /* Limits player to one entry per class per uid */
|
||||
/* If this good score is the same class and uid, then forget it */
|
||||
if (strncmp(scp->sc_login, login, LOGLEN) == 0 &&
|
||||
scp->sc_ctype == ctype &&
|
||||
strncmp(scp->sc_system, system, SYSLEN) == 0) return(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (scp < &top_ten[NUMSCORE])
|
||||
{
|
||||
retval = 1;
|
||||
|
||||
#ifdef LIMITSCORE /* Limits player to one entry per class per uid */
|
||||
/* If a lower scores exists for the same login and class, delete it */
|
||||
for (sc2 = scp ;sc2 < &top_ten[NUMSCORE]; sc2++) {
|
||||
if (sc2->sc_score == 0L) break; /* End of useful scores */
|
||||
|
||||
if (strncmp(sc2->sc_login, login, LOGLEN) == 0 &&
|
||||
sc2->sc_ctype == ctype &&
|
||||
strncmp(sc2->sc_system, system, SYSLEN) == 0) {
|
||||
/* We want to delete this entry */
|
||||
while (sc2 < &top_ten[NUMSCORE-1]) {
|
||||
*sc2 = *(sc2+1);
|
||||
sc2++;
|
||||
}
|
||||
sc2->sc_score = 0L;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
for (sc2 = &top_ten[NUMSCORE-1]; sc2 > scp; sc2--)
|
||||
*sc2 = *(sc2-1);
|
||||
scp->sc_score = amount;
|
||||
scp->sc_quest = quest;
|
||||
strncpy(scp->sc_name, whoami, LINELEN);
|
||||
scp->sc_flgs = flags;
|
||||
scp->sc_level = level;
|
||||
scp->sc_monster = monst;
|
||||
scp->sc_ctype = ctype;
|
||||
strncpy(scp->sc_system, system, SYSLEN);
|
||||
strncpy(scp->sc_login, login, LOGLEN);
|
||||
}
|
||||
|
||||
return(retval);
|
||||
}
|
||||
1432
arogue5/rogue.c
Normal file
1432
arogue5/rogue.c
Normal file
File diff suppressed because it is too large
Load diff
1117
arogue5/rogue.h
Normal file
1117
arogue5/rogue.h
Normal file
File diff suppressed because it is too large
Load diff
239
arogue5/rooms.c
Normal file
239
arogue5/rooms.c
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
/*
|
||||
* Draw the nine rooms on the screen
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "curses.h"
|
||||
#include "rogue.h"
|
||||
|
||||
do_rooms()
|
||||
{
|
||||
register int i;
|
||||
register struct room *rp;
|
||||
register struct linked_list *item;
|
||||
register struct thing *tp;
|
||||
register int left_out;
|
||||
coord top;
|
||||
coord bsze;
|
||||
coord mp;
|
||||
|
||||
/*
|
||||
* bsze is the maximum room size
|
||||
*/
|
||||
bsze.x = COLS/3;
|
||||
bsze.y = (LINES-2)/3;
|
||||
/*
|
||||
* Clear things for a new level
|
||||
*/
|
||||
for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) {
|
||||
rp->r_flags = 0;
|
||||
rp->r_fires = NULL;
|
||||
}
|
||||
/*
|
||||
* Put the gone rooms, if any, on the level
|
||||
*/
|
||||
left_out = rnd(4);
|
||||
for (i = 0; i < left_out; i++)
|
||||
rooms[rnd_room()].r_flags |= ISGONE;
|
||||
/*
|
||||
* dig and populate all the rooms on the level
|
||||
*/
|
||||
for (i = 0, rp = rooms; i < MAXROOMS; rp++, i++)
|
||||
{
|
||||
bool has_gold=FALSE;
|
||||
|
||||
/*
|
||||
* Find upper left corner of box that this room goes in
|
||||
*/
|
||||
top.x = (i%3)*bsze.x;
|
||||
top.y = i/3*bsze.y + 1;
|
||||
if (rp->r_flags & ISGONE)
|
||||
{
|
||||
/*
|
||||
* Place a gone room. Make certain that there is a blank line
|
||||
* for passage drawing.
|
||||
*/
|
||||
do
|
||||
{
|
||||
rp->r_pos.x = top.x + rnd(bsze.x-2) + 1;
|
||||
rp->r_pos.y = top.y + rnd(bsze.y-2) + 1;
|
||||
rp->r_max.x = -COLS;
|
||||
rp->r_max.x = -LINES;
|
||||
} until(rp->r_pos.y > 0 && rp->r_pos.y < LINES-2);
|
||||
continue;
|
||||
}
|
||||
if (rnd(10) < level-1)
|
||||
rp->r_flags |= ISDARK;
|
||||
/*
|
||||
* Find a place and size for a random room
|
||||
*/
|
||||
do
|
||||
{
|
||||
rp->r_max.x = rnd(bsze.x - 4) + 4;
|
||||
rp->r_max.y = rnd(bsze.y - 4) + 4;
|
||||
rp->r_pos.x = top.x + rnd(bsze.x - rp->r_max.x);
|
||||
rp->r_pos.y = top.y + rnd(bsze.y - rp->r_max.y);
|
||||
} until (rp->r_pos.y != 0);
|
||||
|
||||
/* Draw the room */
|
||||
draw_room(rp);
|
||||
|
||||
/*
|
||||
* Put the gold in
|
||||
*/
|
||||
if (rnd(100) < 50 && level >= cur_max)
|
||||
{
|
||||
register struct linked_list *item;
|
||||
register struct object *cur;
|
||||
coord tp;
|
||||
|
||||
has_gold = TRUE; /* This room has gold in it */
|
||||
|
||||
item = spec_item(GOLD, NULL, NULL, NULL);
|
||||
cur = OBJPTR(item);
|
||||
|
||||
/* Put the gold into the level list of items */
|
||||
attach(lvl_obj, item);
|
||||
|
||||
/* Put it somewhere */
|
||||
rnd_pos(rp, &tp);
|
||||
mvaddch(tp.y, tp.x, GOLD);
|
||||
cur->o_pos = tp;
|
||||
if (roomin(&tp) != rp) {
|
||||
endwin();
|
||||
printf("\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Put the monster in
|
||||
*/
|
||||
if (rnd(100) < (has_gold ? 80 : 25) + vlevel/2)
|
||||
{
|
||||
item = new_item(sizeof *tp);
|
||||
tp = THINGPTR(item);
|
||||
do
|
||||
{
|
||||
rnd_pos(rp, &mp);
|
||||
} until(mvwinch(stdscr, mp.y, mp.x) == FLOOR);
|
||||
new_monster(item, randmonster(FALSE, FALSE), &mp, FALSE);
|
||||
/*
|
||||
* See if we want to give it a treasure to carry around.
|
||||
*/
|
||||
carry_obj(tp, monsters[tp->t_index].m_carry);
|
||||
|
||||
/*
|
||||
* If it has a fire, mark it
|
||||
*/
|
||||
if (on(*tp, HASFIRE)) {
|
||||
register struct linked_list *fire_item;
|
||||
|
||||
fire_item = creat_item();
|
||||
ldata(fire_item) = (char *) tp;
|
||||
attach(rp->r_fires, fire_item);
|
||||
rp->r_flags |= HASFIRE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Draw a box around a room
|
||||
*/
|
||||
|
||||
draw_room(rp)
|
||||
register struct room *rp;
|
||||
{
|
||||
register int j, k;
|
||||
|
||||
move(rp->r_pos.y, rp->r_pos.x+1);
|
||||
vert(rp->r_max.y-2); /* Draw left side */
|
||||
move(rp->r_pos.y+rp->r_max.y-1, rp->r_pos.x);
|
||||
horiz(rp->r_max.x); /* Draw bottom */
|
||||
move(rp->r_pos.y, rp->r_pos.x);
|
||||
horiz(rp->r_max.x); /* Draw top */
|
||||
vert(rp->r_max.y-2); /* Draw right side */
|
||||
/*
|
||||
* Put the floor down
|
||||
*/
|
||||
for (j = 1; j < rp->r_max.y-1; j++)
|
||||
{
|
||||
move(rp->r_pos.y + j, rp->r_pos.x+1);
|
||||
for (k = 1; k < rp->r_max.x-1; k++)
|
||||
addch(FLOOR);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* horiz:
|
||||
* draw a horizontal line
|
||||
*/
|
||||
|
||||
horiz(cnt)
|
||||
register int cnt;
|
||||
{
|
||||
while (cnt--)
|
||||
addch('-');
|
||||
}
|
||||
|
||||
/*
|
||||
* rnd_pos:
|
||||
* pick a random spot in a room
|
||||
*/
|
||||
|
||||
rnd_pos(rp, cp)
|
||||
register struct room *rp;
|
||||
register coord *cp;
|
||||
{
|
||||
cp->x = rp->r_pos.x + rnd(rp->r_max.x-2) + 1;
|
||||
cp->y = rp->r_pos.y + rnd(rp->r_max.y-2) + 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* roomin:
|
||||
* Find what room some coordinates are in. NULL means they aren't
|
||||
* in any room.
|
||||
*/
|
||||
|
||||
struct room *
|
||||
roomin(cp)
|
||||
register coord *cp;
|
||||
{
|
||||
register struct room *rp;
|
||||
|
||||
for (rp = rooms; rp < &rooms[MAXROOMS]; rp++)
|
||||
if (inroom(rp, cp))
|
||||
return rp;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* vert:
|
||||
* draw a vertical line
|
||||
*/
|
||||
|
||||
vert(cnt)
|
||||
register int cnt;
|
||||
{
|
||||
register int x, y;
|
||||
|
||||
getyx(stdscr, y, x);
|
||||
x--;
|
||||
while (cnt--) {
|
||||
move(++y, x);
|
||||
addch('|');
|
||||
}
|
||||
}
|
||||
289
arogue5/save.c
Normal file
289
arogue5/save.c
Normal file
|
|
@ -0,0 +1,289 @@
|
|||
/*
|
||||
* save and restore routines
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "curses.h"
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <signal.h>
|
||||
#include "rogue.h"
|
||||
|
||||
typedef struct stat STAT;
|
||||
|
||||
extern char version[], encstr[];
|
||||
/* extern bool _endwin; */
|
||||
|
||||
STAT sbuf;
|
||||
|
||||
bool
|
||||
save_game()
|
||||
{
|
||||
register FILE *savef;
|
||||
register int c;
|
||||
char buf[LINELEN];
|
||||
|
||||
/*
|
||||
* get file name
|
||||
*/
|
||||
mpos = 0;
|
||||
if (file_name[0] != '\0')
|
||||
{
|
||||
msg("Save file (%s)? ", file_name);
|
||||
do
|
||||
{
|
||||
c = readchar();
|
||||
if (c == ESCAPE) return(0);
|
||||
} while (c != 'n' && c != 'N' && c != 'y' && c != 'Y');
|
||||
mpos = 0;
|
||||
if (c == 'y' || c == 'Y')
|
||||
{
|
||||
msg("File name: %s", file_name);
|
||||
goto gotfile;
|
||||
}
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
msg("File name: ");
|
||||
mpos = 0;
|
||||
buf[0] = '\0';
|
||||
if (get_str(buf, cw) == QUIT)
|
||||
{
|
||||
msg("");
|
||||
return FALSE;
|
||||
}
|
||||
msg("");
|
||||
strcpy(file_name, buf);
|
||||
gotfile:
|
||||
if ((savef = fopen(file_name, "w")) == NULL)
|
||||
msg(strerror(errno)); /* fake perror() */
|
||||
} while (savef == NULL);
|
||||
|
||||
/*
|
||||
* write out encrpyted file (after a stat)
|
||||
* The fwrite is to force allocation of the buffer before the write
|
||||
*/
|
||||
if (save_file(savef) != 0) {
|
||||
msg("Cannot create save file.");
|
||||
unlink(file_name);
|
||||
return(FALSE);
|
||||
}
|
||||
else return(TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* automatically save a file. This is used if a HUP signal is
|
||||
* recieved
|
||||
*/
|
||||
void
|
||||
auto_save(int sig)
|
||||
{
|
||||
register FILE *savef;
|
||||
register int i;
|
||||
|
||||
NOOP(sig);
|
||||
|
||||
for (i = 0; i < NSIG; i++)
|
||||
signal(i, SIG_IGN);
|
||||
if (file_name[0] != '\0' &&
|
||||
pstats.s_hpt > 0 &&
|
||||
(savef = fopen(file_name, "w")) != NULL)
|
||||
save_file(savef);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* write the saved game on the file
|
||||
*/
|
||||
bool
|
||||
save_file(savef)
|
||||
register FILE *savef;
|
||||
{
|
||||
int ret;
|
||||
int slines = LINES;
|
||||
int scols = COLS;
|
||||
|
||||
wmove(cw, LINES-1, 0);
|
||||
draw(cw);
|
||||
fwrite("junk", 1, 5, savef);
|
||||
fseek(savef, 0L, 0);
|
||||
/* _endwin = TRUE; */
|
||||
fstat(fileno(savef), &sbuf);
|
||||
|
||||
encwrite(version,strlen(version)+1,savef);
|
||||
sprintf(prbuf,"%d x %d\n", LINES, COLS);
|
||||
encwrite(prbuf,80,savef);
|
||||
|
||||
msg("");
|
||||
ret = rs_save_file(savef);
|
||||
|
||||
fclose(savef);
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
restore(file, envp)
|
||||
register char *file;
|
||||
char **envp;
|
||||
{
|
||||
register int inf;
|
||||
#ifndef _AIX
|
||||
extern char **environ;
|
||||
#endif
|
||||
char buf[LINELEN];
|
||||
STAT sbuf2;
|
||||
int oldcol, oldline; /* Old number of columns and lines */
|
||||
|
||||
if (strcmp(file, "-r") == 0)
|
||||
file = file_name;
|
||||
|
||||
if ((inf = open(file, O_RDONLY)) < 0)
|
||||
{
|
||||
perror(file);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
encread(buf, strlen(version) + 1, inf);
|
||||
|
||||
if (strcmp(buf, version) != 0)
|
||||
{
|
||||
printf("Sorry, saved game is out of date.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the lines and columns from the previous game
|
||||
*/
|
||||
|
||||
encread(buf, 80, inf);
|
||||
sscanf(buf, "%d x %d\n", &oldline, &oldcol);
|
||||
fstat(inf, &sbuf2);
|
||||
fflush(stdout);
|
||||
|
||||
/*
|
||||
* Set the new terminal and make sure we aren't going to a smaller screen.
|
||||
*/
|
||||
|
||||
initscr();
|
||||
|
||||
if (COLS < oldcol || LINES < oldline) {
|
||||
endwin();
|
||||
printf("\nCannot restart the game on a smaller screen.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
cw = newwin(LINES, COLS, 0, 0);
|
||||
mw = newwin(LINES, COLS, 0, 0);
|
||||
hw = newwin(LINES, COLS, 0, 0);
|
||||
msgw = newwin(4, COLS, 0, 0);
|
||||
keypad(cw,1);
|
||||
keypad(msgw,1);
|
||||
|
||||
mpos = 0;
|
||||
mvwprintw(cw, 0, 0, "%s: %s", file, ctime(&sbuf2.st_mtime));
|
||||
|
||||
/*
|
||||
* defeat multiple restarting from the same place
|
||||
*/
|
||||
if (!wizard) {
|
||||
if (sbuf2.st_nlink != 1) {
|
||||
endwin();
|
||||
printf("\nCannot restore from a linked file\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (rs_restore_file(inf) != 0)
|
||||
{
|
||||
endwin();
|
||||
printf("\nCannot restore file\n");
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
if (!wizard)
|
||||
{
|
||||
if (unlink(file) < 0) {
|
||||
close(inf); /* only close if system insists */
|
||||
if (unlink(file) < 0) {
|
||||
endwin();
|
||||
printf("\nCannot unlink file\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
environ = envp;
|
||||
strcpy(file_name, file);
|
||||
setup();
|
||||
clearok(curscr, TRUE);
|
||||
touchwin(cw);
|
||||
srand(getpid());
|
||||
playit();
|
||||
/*NOTREACHED*/
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* perform an encrypted write
|
||||
*/
|
||||
encwrite(start, size, outf)
|
||||
register char *start;
|
||||
register unsigned size;
|
||||
register FILE *outf;
|
||||
{
|
||||
register char *ep;
|
||||
register num_written = 0;
|
||||
|
||||
ep = encstr;
|
||||
|
||||
while (size--)
|
||||
{
|
||||
if (putc(*start++ ^ *ep++, outf) == EOF && ferror(outf))
|
||||
return(num_written);
|
||||
num_written++;
|
||||
if (*ep == '\0')
|
||||
ep = encstr;
|
||||
}
|
||||
return(num_written);
|
||||
}
|
||||
|
||||
/*
|
||||
* perform an encrypted read
|
||||
*/
|
||||
encread(start, size, inf)
|
||||
register char *start;
|
||||
register unsigned size;
|
||||
register int inf;
|
||||
{
|
||||
register char *ep;
|
||||
register int read_size;
|
||||
|
||||
if ((read_size = read(inf, start, size)) == -1 || read_size == 0)
|
||||
return read_size;
|
||||
|
||||
ep = encstr;
|
||||
|
||||
size = read_size;
|
||||
while (size--)
|
||||
{
|
||||
*start++ ^= *ep++;
|
||||
if (*ep == '\0')
|
||||
ep = encstr;
|
||||
}
|
||||
return read_size;
|
||||
}
|
||||
709
arogue5/scrolls.c
Normal file
709
arogue5/scrolls.c
Normal file
|
|
@ -0,0 +1,709 @@
|
|||
/*
|
||||
* Read a scroll and let it happen
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "curses.h"
|
||||
#include <ctype.h>
|
||||
#include "rogue.h"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* let the hero get rid of some type of monster (but not a UNIQUE!)
|
||||
*/
|
||||
genocide()
|
||||
{
|
||||
register struct linked_list *ip;
|
||||
register struct thing *mp;
|
||||
register int i;
|
||||
register struct linked_list *nip;
|
||||
register int num_monst = NUMMONST-NUMUNIQUE-1, /* cannot genocide uniques */
|
||||
pres_monst=1,
|
||||
num_lines=2*(LINES-3);
|
||||
register int which_monst;
|
||||
char monst_name[40];
|
||||
|
||||
/* Print out the monsters */
|
||||
while (num_monst > 0) {
|
||||
register left_limit;
|
||||
|
||||
if (num_monst < num_lines) left_limit = (num_monst+1)/2;
|
||||
else left_limit = num_lines/2;
|
||||
|
||||
wclear(hw);
|
||||
touchwin(hw);
|
||||
|
||||
/* Print left column */
|
||||
wmove(hw, 2, 0);
|
||||
for (i=0; i<left_limit; i++) {
|
||||
sprintf(monst_name,
|
||||
"[%d] %c%s\n",
|
||||
pres_monst,
|
||||
monsters[pres_monst].m_normal ? ' ' : '*',
|
||||
monsters[pres_monst].m_name);
|
||||
waddstr(hw, monst_name);
|
||||
pres_monst++;
|
||||
}
|
||||
|
||||
/* Print right column */
|
||||
for (i=0; i<left_limit && pres_monst<=NUMMONST-NUMUNIQUE-1; i++) {
|
||||
sprintf(monst_name,
|
||||
"[%d] %c%s\n",
|
||||
pres_monst,
|
||||
monsters[pres_monst].m_normal ? ' ' : '*',
|
||||
monsters[pres_monst].m_name);
|
||||
wmove(hw, i+2, COLS/2);
|
||||
waddstr(hw, monst_name);
|
||||
pres_monst++;
|
||||
}
|
||||
|
||||
if ((num_monst -= num_lines) > 0) {
|
||||
mvwaddstr(hw, LINES-1, 0, morestr);
|
||||
draw(hw);
|
||||
wait_for(hw,' ');
|
||||
}
|
||||
|
||||
else {
|
||||
mvwaddstr(hw, 0, 0, "Which monster");
|
||||
if (!terse) waddstr(hw, " do you wish to wipe out");
|
||||
waddstr(hw, "? ");
|
||||
draw(hw);
|
||||
}
|
||||
}
|
||||
|
||||
get_monst:
|
||||
get_str(monst_name, hw);
|
||||
which_monst = atoi(monst_name);
|
||||
if ((which_monst < 1 || which_monst > NUMMONST-NUMUNIQUE-1)) {
|
||||
mvwaddstr(hw, 0, 0, "Please enter a number in the displayed range -- ");
|
||||
draw(hw);
|
||||
goto get_monst;
|
||||
}
|
||||
|
||||
/* Set up for redraw */
|
||||
clearok(cw, TRUE);
|
||||
touchwin(cw);
|
||||
|
||||
/* Remove this monster from the present level */
|
||||
for (ip = mlist; ip; ip = nip) {
|
||||
mp = THINGPTR(ip);
|
||||
nip = next(ip);
|
||||
if (mp->t_index == which_monst) {
|
||||
killed(ip, FALSE, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove from available monsters */
|
||||
monsters[which_monst].m_normal = FALSE;
|
||||
monsters[which_monst].m_wander = FALSE;
|
||||
mpos = 0;
|
||||
msg("You have wiped out the %s.", monsters[which_monst].m_name);
|
||||
}
|
||||
|
||||
read_scroll(which, flag, is_scroll)
|
||||
register int which;
|
||||
int flag;
|
||||
bool is_scroll;
|
||||
{
|
||||
register struct object *obj = NULL, *nobj;
|
||||
register struct linked_list *item, *nitem;
|
||||
register int i,j;
|
||||
register char ch, nch;
|
||||
bool cursed, blessed;
|
||||
char buf[LINELEN];
|
||||
|
||||
blessed = FALSE;
|
||||
cursed = FALSE;
|
||||
item = NULL;
|
||||
|
||||
if (which < 0) {
|
||||
if (on(player, ISBLIND)) {
|
||||
msg("You can't see to read anything");
|
||||
return;
|
||||
}
|
||||
item = get_item(pack, "read", SCROLL);
|
||||
if (item == NULL)
|
||||
return;
|
||||
|
||||
obj = OBJPTR(item);
|
||||
/* remove it from the pack */
|
||||
inpack--;
|
||||
detach(pack, item);
|
||||
|
||||
msg("As you read the scroll, it vanishes.");
|
||||
cursed = (obj->o_flags & ISCURSED) != 0;
|
||||
blessed = (obj->o_flags & ISBLESSED) != 0;
|
||||
|
||||
which = obj->o_which;
|
||||
}
|
||||
else {
|
||||
cursed = flag & ISCURSED;
|
||||
blessed = flag & ISBLESSED;
|
||||
}
|
||||
|
||||
|
||||
switch (which) {
|
||||
case S_CONFUSE:
|
||||
/*
|
||||
* Scroll of monster confusion. Give him that power.
|
||||
*/
|
||||
msg("Your hands begin to glow red");
|
||||
turn_on(player, CANHUH);
|
||||
when S_CURING:
|
||||
/*
|
||||
* A cure disease spell
|
||||
*/
|
||||
if (on(player, HASINFEST) ||
|
||||
on(player, HASDISEASE)||
|
||||
on(player, DOROT)) {
|
||||
if (on(player, HASDISEASE)) {
|
||||
extinguish(cure_disease);
|
||||
cure_disease();
|
||||
}
|
||||
if (on(player, HASINFEST)) {
|
||||
msg(terse ? "You feel yourself improving."
|
||||
: "You begin to feel yourself improving again.");
|
||||
turn_off(player, HASINFEST);
|
||||
infest_dam = 0;
|
||||
}
|
||||
if (on(player, DOROT)) {
|
||||
msg("You feel your skin returning to normal.");
|
||||
turn_off(player, DOROT);
|
||||
}
|
||||
}
|
||||
else {
|
||||
msg(nothing);
|
||||
break;
|
||||
}
|
||||
if (is_scroll) s_know[S_CURING] = TRUE;
|
||||
when S_LIGHT:
|
||||
if (blue_light(blessed, cursed) && is_scroll)
|
||||
s_know[S_LIGHT] = TRUE;
|
||||
when S_HOLD:
|
||||
if (cursed) {
|
||||
/*
|
||||
* This scroll aggravates all the monsters on the current
|
||||
* level and sets them running towards the hero
|
||||
*/
|
||||
aggravate();
|
||||
msg("You hear a high pitched humming noise.");
|
||||
}
|
||||
else if (blessed) { /* Hold all monsters on level */
|
||||
if (mlist == NULL) msg(nothing);
|
||||
else {
|
||||
register struct linked_list *mon;
|
||||
register struct thing *th;
|
||||
|
||||
for (mon = mlist; mon != NULL; mon = next(mon)) {
|
||||
th = THINGPTR(mon);
|
||||
turn_off(*th, ISRUN);
|
||||
turn_on(*th, ISHELD);
|
||||
}
|
||||
msg("A sudden peace comes over the dungeon.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Hold monster scroll. Stop all monsters within two spaces
|
||||
* from chasing after the hero.
|
||||
*/
|
||||
register int x,y;
|
||||
register struct linked_list *mon;
|
||||
bool gotone=FALSE;
|
||||
|
||||
for (x = hero.x-2; x <= hero.x+2; x++) {
|
||||
for (y = hero.y-2; y <= hero.y+2; y++) {
|
||||
if (y < 1 || x < 0 || y > LINES - 3 || x > COLS - 1)
|
||||
continue;
|
||||
if (isalpha(mvwinch(mw, y, x))) {
|
||||
if ((mon = find_mons(y, x)) != NULL) {
|
||||
register struct thing *th;
|
||||
|
||||
gotone = TRUE;
|
||||
th = THINGPTR(mon);
|
||||
turn_off(*th, ISRUN);
|
||||
turn_on(*th, ISHELD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (gotone) msg("A sudden peace surrounds you.");
|
||||
else msg(nothing);
|
||||
}
|
||||
when S_SLEEP:
|
||||
/*
|
||||
* if cursed, you fall asleep
|
||||
*/
|
||||
if (is_scroll) s_know[S_SLEEP] = TRUE;
|
||||
if (cursed) {
|
||||
if (ISWEARING(R_ALERT))
|
||||
msg("You feel drowsy for a moment.");
|
||||
else {
|
||||
msg("You fall asleep.");
|
||||
no_command += 4 + rnd(SLEEPTIME);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* sleep monster scroll.
|
||||
* puts all monsters within 2 spaces asleep
|
||||
*/
|
||||
register int x,y;
|
||||
register struct linked_list *mon;
|
||||
bool gotone=FALSE;
|
||||
|
||||
for (x = hero.x-2; x <= hero.x+2; x++) {
|
||||
for (y = hero.y-2; y <= hero.y+2; y++) {
|
||||
if (y < 1 || x < 0 || y > LINES - 3 || x > COLS - 1)
|
||||
continue;
|
||||
if (isalpha(mvwinch(mw, y, x))) {
|
||||
if ((mon = find_mons(y, x)) != NULL) {
|
||||
register struct thing *th;
|
||||
|
||||
th = THINGPTR(mon);
|
||||
if (on(*th, ISUNDEAD))
|
||||
continue;
|
||||
th->t_no_move += SLEEPTIME;
|
||||
gotone = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (gotone)
|
||||
msg("The monster(s) around you seem to have fallen asleep");
|
||||
else
|
||||
msg(nothing);
|
||||
}
|
||||
when S_CREATE:
|
||||
/*
|
||||
* Create a monster
|
||||
* First look in a circle around him, next try his room
|
||||
* otherwise give up
|
||||
*/
|
||||
creat_mons(&player, (short) 0, TRUE);
|
||||
light(&hero);
|
||||
when S_IDENT:
|
||||
/*
|
||||
* if its blessed then identify everything in the pack
|
||||
*/
|
||||
if (blessed) {
|
||||
msg("You feel more Knowledgeable!");
|
||||
idenpack();
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Identify, let the rogue figure something out
|
||||
*/
|
||||
if (is_scroll && s_know[S_IDENT] != TRUE) {
|
||||
msg("This scroll is an identify scroll");
|
||||
}
|
||||
whatis(NULL);
|
||||
}
|
||||
if (is_scroll) s_know[S_IDENT] = TRUE;
|
||||
when S_MAP:
|
||||
/*
|
||||
* Scroll of magic mapping.
|
||||
*/
|
||||
if (is_scroll && s_know[S_MAP] != TRUE) {
|
||||
msg("Oh, now this scroll has a map on it.");
|
||||
s_know[S_MAP] = TRUE;
|
||||
}
|
||||
overwrite(stdscr, hw);
|
||||
/*
|
||||
* Take all the things we want to keep hidden out of the window
|
||||
*/
|
||||
for (i = 1; i < LINES-2; i++)
|
||||
for (j = 0; j < COLS; j++)
|
||||
{
|
||||
switch (nch = ch = CCHAR( mvwinch(hw, i, j) ))
|
||||
{
|
||||
case SECRETDOOR:
|
||||
nch = secretdoor (i, j);
|
||||
break;
|
||||
case '-':
|
||||
case '|':
|
||||
case DOOR:
|
||||
case PASSAGE:
|
||||
case ' ':
|
||||
case STAIRS:
|
||||
if (mvwinch(mw, i, j) != ' ')
|
||||
{
|
||||
register struct thing *it;
|
||||
|
||||
it = THINGPTR(find_mons(i, j));
|
||||
if (it && it->t_oldch == ' ')
|
||||
it->t_oldch = nch;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
nch = ' ';
|
||||
}
|
||||
if (nch != ch)
|
||||
waddch(hw, nch);
|
||||
}
|
||||
/*
|
||||
* Copy in what he has discovered
|
||||
*/
|
||||
overlay(cw, hw);
|
||||
/*
|
||||
* And set up for display
|
||||
*/
|
||||
overwrite(hw, cw);
|
||||
when S_GFIND:
|
||||
/*
|
||||
* Scroll of gold detection
|
||||
*/
|
||||
if (lvl_obj != NULL) {
|
||||
register struct linked_list *gitem;
|
||||
struct object *cur;
|
||||
int gtotal = 0;
|
||||
|
||||
wclear(hw);
|
||||
for (gitem = lvl_obj; gitem != NULL; gitem = next(gitem)) {
|
||||
cur = OBJPTR(gitem);
|
||||
if (cur->o_type == GOLD) {
|
||||
gtotal += cur->o_count;
|
||||
mvwaddch(hw, cur->o_pos.y, cur->o_pos.x, GOLD);
|
||||
}
|
||||
}
|
||||
if (gtotal) {
|
||||
if (is_scroll) s_know[S_GFIND] = TRUE;
|
||||
msg("You begin to feel greedy and you sense gold.");
|
||||
overlay(hw,cw);
|
||||
break;
|
||||
}
|
||||
}
|
||||
msg("You begin to feel a pull downward");
|
||||
when S_TELEP:
|
||||
/*
|
||||
* Scroll of teleportation:
|
||||
* Make him disappear and reappear
|
||||
*/
|
||||
if (cursed) {
|
||||
int old_max = cur_max;
|
||||
|
||||
turns = (vlevel * 3) * LEVEL;
|
||||
level = nfloors;
|
||||
new_level(NORMLEV);
|
||||
status(TRUE);
|
||||
mpos = 0;
|
||||
msg("You are banished to the lower regions.");
|
||||
if (old_max == cur_max) /* if he's been here, make it harder */
|
||||
aggravate();
|
||||
}
|
||||
else if (blessed) {
|
||||
int old_level,
|
||||
much = rnd(4) - 4;
|
||||
|
||||
old_level = level;
|
||||
if (much != 0) {
|
||||
level += much;
|
||||
if (level < 1)
|
||||
level = 1;
|
||||
mpos = 0;
|
||||
cur_max = level;
|
||||
turns += much*LEVEL;
|
||||
if (turns < 0)
|
||||
turns = 0;
|
||||
new_level(NORMLEV); /* change levels */
|
||||
if (level == old_level)
|
||||
status(TRUE);
|
||||
msg("You are whisked away to another region.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
teleport();
|
||||
}
|
||||
if (is_scroll) s_know[S_TELEP] = TRUE;
|
||||
when S_SCARE:
|
||||
/*
|
||||
* A monster will refuse to step on a scare monster scroll
|
||||
* if it is dropped. Thus reading it is a mistake and produces
|
||||
* laughter at the poor rogue's boo boo.
|
||||
*/
|
||||
msg("You hear maniacal laughter in the distance.");
|
||||
when S_REMOVE:
|
||||
if (cursed) { /* curse all player's possessions */
|
||||
for (nitem = pack; nitem != NULL; nitem = next(nitem)) {
|
||||
nobj = OBJPTR(nitem);
|
||||
if (nobj->o_flags & ISBLESSED)
|
||||
nobj->o_flags &= ~ISBLESSED;
|
||||
else
|
||||
nobj->o_flags |= ISCURSED;
|
||||
}
|
||||
msg("The smell of fire and brimstone fills the air.");
|
||||
}
|
||||
else if (blessed) {
|
||||
for (nitem = pack; nitem != NULL; nitem = next(nitem)) {
|
||||
nobj = OBJPTR(nitem);
|
||||
nobj->o_flags &= ~ISCURSED;
|
||||
}
|
||||
msg("Your pack glistens brightly");
|
||||
}
|
||||
else {
|
||||
if ((nitem = get_item(pack, "remove the curse on",ALL))!=NULL){
|
||||
nobj = OBJPTR(nitem);
|
||||
nobj->o_flags &= ~ISCURSED;
|
||||
msg("Removed the curse from %s",inv_name(nobj,TRUE));
|
||||
}
|
||||
}
|
||||
if (is_scroll) s_know[S_REMOVE] = TRUE;
|
||||
when S_PETRIFY:
|
||||
switch (mvinch(hero.y, hero.x)) {
|
||||
case TRAPDOOR:
|
||||
case DARTTRAP:
|
||||
case TELTRAP:
|
||||
case ARROWTRAP:
|
||||
case SLEEPTRAP:
|
||||
case BEARTRAP:
|
||||
{
|
||||
register int i;
|
||||
|
||||
/* Find the right trap */
|
||||
for (i=0; i<ntraps && !ce(traps[i].tr_pos, hero); i++);
|
||||
ntraps--;
|
||||
|
||||
if (!ce(traps[i].tr_pos, hero))
|
||||
msg("What a strange trap!");
|
||||
else {
|
||||
while (i < ntraps) {
|
||||
traps[i] = traps[i + 1];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
goto pet_message;
|
||||
case DOOR:
|
||||
case SECRETDOOR:
|
||||
case FLOOR:
|
||||
case PASSAGE:
|
||||
pet_message: msg("The dungeon begins to rumble and shake!");
|
||||
addch(WALL);
|
||||
|
||||
/* If the player is phased, unphase him */
|
||||
if (on(player, CANINWALL)) {
|
||||
extinguish(unphase);
|
||||
turn_off(player, CANINWALL);
|
||||
msg("Your dizzy feeling leaves you.");
|
||||
}
|
||||
|
||||
/* Mark the player as in a wall */
|
||||
turn_on(player, ISINWALL);
|
||||
break;
|
||||
default:
|
||||
msg(nothing);
|
||||
}
|
||||
when S_GENOCIDE:
|
||||
msg("You have been granted the boon of genocide!--More--");
|
||||
wait_for(cw,' ');
|
||||
msg("");
|
||||
genocide();
|
||||
if (is_scroll) s_know[S_GENOCIDE] = TRUE;
|
||||
when S_PROTECT: {
|
||||
struct linked_list *ll;
|
||||
struct object *lb;
|
||||
bool did_it = FALSE;
|
||||
msg("You are granted the power of protection.");
|
||||
if ((ll = get_item(pack, "protect", PROTECTABLE)) != NULL) {
|
||||
lb = OBJPTR(ll);
|
||||
mpos = 0;
|
||||
if (cursed) {
|
||||
switch(lb->o_type) { /* ruin it completely */
|
||||
case RING: if (lb->o_ac > 0) {
|
||||
if (is_current(lb)) {
|
||||
switch (lb->o_which) {
|
||||
case R_ADDWISDOM:
|
||||
pstats.s_wisdom -= lb->o_ac;
|
||||
when R_ADDINTEL:
|
||||
pstats.s_intel -= lb->o_ac;
|
||||
when R_ADDSTR:
|
||||
pstats.s_str -= lb->o_ac;
|
||||
when R_ADDHIT:
|
||||
pstats.s_dext -= lb->o_ac;
|
||||
}
|
||||
}
|
||||
did_it = TRUE;
|
||||
lb->o_ac = 0;
|
||||
}
|
||||
when ARMOR: if (lb->o_ac > 10) {
|
||||
did_it = TRUE;
|
||||
lb->o_ac = 10;
|
||||
}
|
||||
when STICK: if (lb->o_charges > 0) {
|
||||
did_it = TRUE;
|
||||
lb->o_charges = 0;
|
||||
}
|
||||
when WEAPON:if (lb->o_hplus > 0) {
|
||||
did_it = TRUE;
|
||||
lb->o_hplus = 0;
|
||||
}
|
||||
if (lb->o_dplus > 0) {
|
||||
did_it = TRUE;
|
||||
lb->o_dplus = 0;
|
||||
}
|
||||
}
|
||||
if (lb->o_flags & ISPROT) {
|
||||
did_it = TRUE;
|
||||
lb->o_flags &= ~ISPROT;
|
||||
}
|
||||
if (lb->o_flags & ISBLESSED) {
|
||||
did_it = TRUE;
|
||||
lb->o_flags &= ~ISBLESSED;
|
||||
}
|
||||
if (did_it)
|
||||
msg("Your %s glows red for a moment",inv_name(lb,TRUE));
|
||||
else {
|
||||
msg(nothing);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
lb->o_flags |= ISPROT;
|
||||
msg("Protected %s.",inv_name(lb,TRUE));
|
||||
}
|
||||
}
|
||||
if (is_scroll) s_know[S_PROTECT] = TRUE;
|
||||
}
|
||||
when S_MAKEIT:
|
||||
msg("You have been endowed with the power of creation.");
|
||||
if (is_scroll) s_know[S_MAKEIT] = TRUE;
|
||||
create_obj(TRUE, 0, 0);
|
||||
when S_ALLENCH: {
|
||||
struct linked_list *ll;
|
||||
struct object *lb;
|
||||
int howmuch, flags;
|
||||
if (is_scroll && s_know[S_ALLENCH] == FALSE) {
|
||||
msg("You are granted the power of enchantment.");
|
||||
msg("You may enchant anything(weapon,ring,armor,scroll,potion)");
|
||||
}
|
||||
if ((ll = get_item(pack, "enchant",ALL)) != NULL) {
|
||||
lb = OBJPTR(ll);
|
||||
lb->o_flags &= ~ISCURSED;
|
||||
if (blessed) {
|
||||
howmuch = 2;
|
||||
flags = ISBLESSED;
|
||||
}
|
||||
else if (cursed) {
|
||||
howmuch = -1;
|
||||
flags = ISCURSED;
|
||||
}
|
||||
else {
|
||||
howmuch = 1;
|
||||
flags = ISBLESSED;
|
||||
}
|
||||
switch(lb->o_type) {
|
||||
case RING:
|
||||
if (lb->o_ac + howmuch > MAXENCHANT) {
|
||||
msg("The enchantment doesn't seem to work!");
|
||||
break;
|
||||
}
|
||||
lb->o_ac += howmuch;
|
||||
if (lb==cur_ring[LEFT_1] || lb==cur_ring[LEFT_2] ||
|
||||
lb==cur_ring[LEFT_3] || lb==cur_ring[LEFT_4] ||
|
||||
lb==cur_ring[RIGHT_1] || lb==cur_ring[RIGHT_2] ||
|
||||
lb==cur_ring[RIGHT_3] || lb==cur_ring[RIGHT_4]) {
|
||||
switch (lb->o_which) {
|
||||
case R_ADDWISDOM: pstats.s_wisdom += howmuch;
|
||||
when R_ADDINTEL: pstats.s_intel += howmuch;
|
||||
when R_ADDSTR: pstats.s_str += howmuch;
|
||||
when R_ADDHIT: pstats.s_dext += howmuch;
|
||||
}
|
||||
}
|
||||
msg("Enchanted %s.",inv_name(lb,TRUE));
|
||||
when ARMOR:
|
||||
if ((armors[lb->o_which].a_class - lb->o_ac) +
|
||||
howmuch > MAXENCHANT) {
|
||||
msg("The enchantment doesn't seem to work!");
|
||||
break;
|
||||
}
|
||||
else
|
||||
lb->o_ac -= howmuch;
|
||||
msg("Enchanted %s.",inv_name(lb,TRUE));
|
||||
when STICK:
|
||||
lb->o_charges += (howmuch * 10) + rnd(5);
|
||||
if (lb->o_charges < 0)
|
||||
lb->o_charges = 0;
|
||||
if (EQUAL(ws_type[lb->o_which], "staff")) {
|
||||
if (lb->o_charges > 100)
|
||||
lb->o_charges = 100;
|
||||
}
|
||||
else {
|
||||
if (lb->o_charges > 50)
|
||||
lb->o_charges = 50;
|
||||
}
|
||||
msg("Enchanted %s.",inv_name(lb,TRUE));
|
||||
when WEAPON:
|
||||
if(lb->o_hplus+lb->o_dplus+howmuch > MAXENCHANT * 2){
|
||||
msg("The enchantment doesn't seem to work!");
|
||||
break;
|
||||
}
|
||||
if (rnd(100) < 50)
|
||||
lb->o_hplus += howmuch;
|
||||
else
|
||||
lb->o_dplus += howmuch;
|
||||
msg("Enchanted %s.",inv_name(lb,TRUE));
|
||||
when MM:
|
||||
switch (lb->o_which) {
|
||||
case MM_BRACERS:
|
||||
case MM_PROTECT:
|
||||
if (lb->o_ac + howmuch > MAXENCHANT) {
|
||||
msg("The enchantment doesn't seem to work!");
|
||||
break;
|
||||
}
|
||||
else lb->o_ac += howmuch;
|
||||
msg("Enchanted %s.",inv_name(lb,TRUE));
|
||||
}
|
||||
lb->o_flags |= flags;
|
||||
when POTION:
|
||||
case SCROLL:
|
||||
default:
|
||||
lb->o_flags |= flags;
|
||||
msg("Enchanted %s.",inv_name(lb,TRUE));
|
||||
}
|
||||
}
|
||||
if (is_scroll) s_know[S_ALLENCH] = TRUE;
|
||||
if (!is_scroll) {
|
||||
pstats.s_const--;
|
||||
max_stats.s_const--;
|
||||
if (pstats.s_const <= 0)
|
||||
death(D_CONSTITUTION);
|
||||
msg("You feel less healthy now");
|
||||
}
|
||||
}
|
||||
otherwise:
|
||||
msg("What a puzzling scroll!");
|
||||
return;
|
||||
}
|
||||
look(TRUE, FALSE); /* put the result of the scroll on the screen */
|
||||
status(FALSE);
|
||||
if (is_scroll && s_know[which] && s_guess[which])
|
||||
{
|
||||
free(s_guess[which]);
|
||||
s_guess[which] = NULL;
|
||||
}
|
||||
else if (is_scroll &&
|
||||
!s_know[which] &&
|
||||
askme &&
|
||||
(obj->o_flags & ISKNOW) == 0 &&
|
||||
(obj->o_flags & ISPOST) == 0 &&
|
||||
s_guess[which] == NULL) {
|
||||
msg(terse ? "Call it: " : "What do you want to call it? ");
|
||||
if (get_str(buf, cw) == NORM)
|
||||
{
|
||||
s_guess[which] = new(strlen(buf) + 1);
|
||||
strcpy(s_guess[which], buf);
|
||||
}
|
||||
}
|
||||
if (item != NULL) o_discard(item);
|
||||
updpack(TRUE);
|
||||
}
|
||||
2477
arogue5/state.c
Normal file
2477
arogue5/state.c
Normal file
File diff suppressed because it is too large
Load diff
1076
arogue5/sticks.c
Normal file
1076
arogue5/sticks.c
Normal file
File diff suppressed because it is too large
Load diff
849
arogue5/things.c
Normal file
849
arogue5/things.c
Normal file
|
|
@ -0,0 +1,849 @@
|
|||
/*
|
||||
* Contains functions for dealing with things like
|
||||
* potions and scrolls
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "curses.h"
|
||||
#include <ctype.h>
|
||||
#include "rogue.h"
|
||||
|
||||
/*
|
||||
* print out the number of charges on a stick
|
||||
*/
|
||||
char *
|
||||
charge_str(obj)
|
||||
register struct object *obj;
|
||||
{
|
||||
static char buf[20];
|
||||
|
||||
if (!(obj->o_flags & ISKNOW))
|
||||
buf[0] = '\0';
|
||||
else if (terse)
|
||||
sprintf(buf, " [%d]", obj->o_charges);
|
||||
else
|
||||
sprintf(buf, " [%d charges]", obj->o_charges);
|
||||
return buf;
|
||||
}
|
||||
/*
|
||||
* inv_name:
|
||||
* return the name of something as it would appear in an
|
||||
* inventory.
|
||||
*/
|
||||
char *
|
||||
inv_name(obj, drop)
|
||||
register struct object *obj;
|
||||
bool drop;
|
||||
{
|
||||
register char *pb;
|
||||
|
||||
pb = prbuf;
|
||||
pb[0] = '\0';
|
||||
switch(obj->o_type) {
|
||||
case SCROLL:
|
||||
if (obj->o_count == 1)
|
||||
sprintf(pb, "A %sscroll ", blesscurse(obj->o_flags));
|
||||
else
|
||||
sprintf(pb, "%d %sscrolls ",
|
||||
obj->o_count, blesscurse(obj->o_flags));
|
||||
pb = &pb[strlen(pb)];
|
||||
if (s_know[obj->o_which] || (obj->o_flags & ISPOST))
|
||||
sprintf(pb, "of %s", s_magic[obj->o_which].mi_name);
|
||||
else if (s_guess[obj->o_which])
|
||||
sprintf(pb, "called %s", s_guess[obj->o_which]);
|
||||
else
|
||||
sprintf(pb, "titled '%s'", s_names[obj->o_which]);
|
||||
when POTION:
|
||||
if (obj->o_count == 1)
|
||||
sprintf(pb, "A %spotion ", blesscurse(obj->o_flags));
|
||||
else
|
||||
sprintf(pb, "%d %spotions ",
|
||||
obj->o_count, blesscurse(obj->o_flags));
|
||||
pb = &pb[strlen(pb)];
|
||||
if (obj->o_flags & ISPOST)
|
||||
sprintf(pb, "of %s", p_magic[obj->o_which].mi_name);
|
||||
else if (p_know[obj->o_which])
|
||||
sprintf(pb, "of %s (%s)", p_magic[obj->o_which].mi_name,
|
||||
p_colors[obj->o_which]);
|
||||
else if (p_guess[obj->o_which])
|
||||
sprintf(pb, "called %s (%s)", p_guess[obj->o_which],
|
||||
p_colors[obj->o_which]);
|
||||
else {
|
||||
pb = prbuf;
|
||||
if (obj->o_count == 1)
|
||||
sprintf(pb, "A%s %s potion",
|
||||
vowelstr(p_colors[obj->o_which]),
|
||||
p_colors[obj->o_which]);
|
||||
else
|
||||
sprintf(pb, "%d %s potions",
|
||||
obj->o_count, p_colors[obj->o_which]);
|
||||
}
|
||||
when FOOD:
|
||||
if (obj->o_which == 1)
|
||||
if (obj->o_count == 1)
|
||||
sprintf(pb, "A%s %s", vowelstr(fruit), fruit);
|
||||
else
|
||||
sprintf(pb, "%d %ss", obj->o_count, fruit);
|
||||
else
|
||||
if (obj->o_count == 1)
|
||||
strcpy(pb, "Some food");
|
||||
else
|
||||
sprintf(pb, "%d rations of food", obj->o_count);
|
||||
when WEAPON:
|
||||
if (obj->o_count > 1)
|
||||
sprintf(pb, "%d ", obj->o_count);
|
||||
else
|
||||
strcpy(pb, "A ");
|
||||
pb = &pb[strlen(pb)];
|
||||
if (obj->o_flags & ISKNOW) {
|
||||
strcat(pb, num(obj->o_hplus, obj->o_dplus));
|
||||
strcat (pb, " ");
|
||||
}
|
||||
strcat(pb, weaps[obj->o_which].w_name);
|
||||
if (obj->o_count > 1)
|
||||
strcat(pb, "s");
|
||||
if (obj == cur_weapon)
|
||||
strcat(pb, " (weapon in hand)");
|
||||
when ARMOR:
|
||||
if (obj->o_flags & ISKNOW) {
|
||||
strcat(pb, num(armors[obj->o_which].a_class - obj->o_ac, 0));
|
||||
strcat(pb, " ");
|
||||
}
|
||||
strcat(pb, armors[obj->o_which].a_name);
|
||||
if (obj == cur_armor)
|
||||
strcat(pb, " (being worn)");
|
||||
when STICK:
|
||||
sprintf(pb, "A %s%s ",
|
||||
blesscurse(obj->o_flags), ws_type[obj->o_which]);
|
||||
pb = &pb[strlen(pb)];
|
||||
if (obj->o_flags & ISPOST)
|
||||
sprintf(pb, "of %s", ws_magic[obj->o_which].mi_name);
|
||||
else if (ws_know[obj->o_which])
|
||||
sprintf(pb, "of %s%s (%s)", ws_magic[obj->o_which].mi_name,
|
||||
charge_str(obj), ws_made[obj->o_which]);
|
||||
else if (ws_guess[obj->o_which])
|
||||
sprintf(pb, "called %s (%s)", ws_guess[obj->o_which],
|
||||
ws_made[obj->o_which]);
|
||||
else {
|
||||
pb = prbuf;
|
||||
sprintf(pb, "A %s %s", ws_made[obj->o_which],
|
||||
ws_type[obj->o_which]);
|
||||
}
|
||||
if (obj == cur_weapon)
|
||||
strcat(prbuf, " (weapon in hand)");
|
||||
when RING:
|
||||
if (obj->o_flags & ISPOST)
|
||||
sprintf(pb, "A ring of %s", r_magic[obj->o_which].mi_name);
|
||||
else if (r_know[obj->o_which])
|
||||
sprintf(pb, "A%s ring of %s (%s)", ring_num(obj),
|
||||
r_magic[obj->o_which].mi_name, r_stones[obj->o_which]);
|
||||
else if (r_guess[obj->o_which])
|
||||
sprintf(pb, "A ring called %s (%s)",
|
||||
r_guess[obj->o_which], r_stones[obj->o_which]);
|
||||
else
|
||||
sprintf(pb, "A%s %s ring", vowelstr(r_stones[obj->o_which]),
|
||||
r_stones[obj->o_which]);
|
||||
if (obj == cur_ring[LEFT_1] || obj == cur_ring[LEFT_2] ||
|
||||
obj == cur_ring[LEFT_3] || obj == cur_ring[LEFT_4])
|
||||
strcat(pb, " (on left hand)");
|
||||
if (obj == cur_ring[RIGHT_1] || obj == cur_ring[RIGHT_2] ||
|
||||
obj == cur_ring[RIGHT_3] || obj == cur_ring[RIGHT_4])
|
||||
strcat(pb, " (on right hand)");
|
||||
when RELIC:
|
||||
if (obj->o_flags & ISKNOW)
|
||||
strcpy(pb, rel_magic[obj->o_which].mi_name);
|
||||
else switch(obj->o_which) {
|
||||
case MUSTY_DAGGER:
|
||||
strcpy(pb, "Two very fine daggers marked MDDE");
|
||||
when EMORI_CLOAK:
|
||||
strcpy(pb, "A silk cloak");
|
||||
when HEIL_ANKH:
|
||||
strcpy(pb, "A golden ankh");
|
||||
when MING_STAFF:
|
||||
strcpy(pb, "A finely carved staff");
|
||||
when ORCUS_WAND:
|
||||
strcpy(pb, "A sparkling ivory wand");
|
||||
when ASMO_ROD:
|
||||
strcpy(pb, "A glistening ebony rod");
|
||||
when YENDOR_AMULET:
|
||||
strcpy(pb, "A silver amulet");
|
||||
when BRIAN_MANDOLIN:
|
||||
strcpy(pb, "A gleaming mandolin");
|
||||
when HRUGGEK_MSTAR:
|
||||
strcpy(pb, "A huge morning star");
|
||||
when GERYON_HORN:
|
||||
strcpy(pb, "A jet black horn");
|
||||
when YEENOGHU_FLAIL:
|
||||
strcpy(pb, "A shimmering flail");
|
||||
otherwise:
|
||||
strcpy(pb, "A magical item");
|
||||
}
|
||||
|
||||
/* Take care of wielding and wearing */
|
||||
switch (obj->o_which) {
|
||||
case EMORI_CLOAK:
|
||||
if (cur_armor == NULL && cur_misc[WEAR_CLOAK] == NULL)
|
||||
strcat(pb, " (being worn)");
|
||||
when HEIL_ANKH:
|
||||
if (cur_relic[HEIL_ANKH]) strcat(pb, " (in hand)");
|
||||
when YENDOR_AMULET:
|
||||
if (cur_relic[YENDOR_AMULET] &&
|
||||
cur_misc[WEAR_JEWEL] == NULL)
|
||||
strcat(pb, " (in chest)");
|
||||
when MUSTY_DAGGER:
|
||||
case HRUGGEK_MSTAR:
|
||||
case YEENOGHU_FLAIL:
|
||||
case MING_STAFF:
|
||||
case ASMO_ROD:
|
||||
case ORCUS_WAND:
|
||||
if (cur_weapon == obj) strcat(pb, " (weapon in hand)");
|
||||
}
|
||||
when MM:
|
||||
if (m_know[obj->o_which])
|
||||
strcpy(pb, misc_name(obj));
|
||||
else {
|
||||
switch (obj->o_which) {
|
||||
case MM_JUG:
|
||||
case MM_BEAKER:
|
||||
strcpy(pb, "A bottle");
|
||||
when MM_KEOGHTOM:
|
||||
strcpy(pb, "A jar");
|
||||
when MM_JEWEL:
|
||||
strcpy(pb, "An amulet");
|
||||
when MM_BOOK:
|
||||
case MM_SKILLS:
|
||||
strcpy(pb, "A book");
|
||||
when MM_ELF_BOOTS:
|
||||
case MM_DANCE:
|
||||
strcpy(pb, "A pair of boots");
|
||||
when MM_BRACERS:
|
||||
strcpy(pb, "A pair of bracers");
|
||||
when MM_OPEN:
|
||||
case MM_HUNGER:
|
||||
strcpy(pb, "A chime");
|
||||
when MM_DISP:
|
||||
case MM_R_POWERLESS:
|
||||
case MM_PROTECT:
|
||||
strcpy(pb, "A cloak");
|
||||
when MM_DRUMS:
|
||||
strcpy(pb, "A set of drums");
|
||||
when MM_DISAPPEAR:
|
||||
case MM_CHOKE:
|
||||
strcpy(pb, "A pouch of dust");
|
||||
when MM_G_DEXTERITY:
|
||||
case MM_G_OGRE:
|
||||
case MM_FUMBLE:
|
||||
strcpy(pb, "A pair of gauntlets");
|
||||
when MM_ADAPTION:
|
||||
case MM_STRANGLE:
|
||||
strcpy(pb, "A necklace");
|
||||
otherwise:
|
||||
strcpy(pb, "A magical item");
|
||||
}
|
||||
if (m_guess[obj->o_which]) {
|
||||
strcat(pb, " called: ");
|
||||
strcat(pb, m_guess[obj->o_which]);
|
||||
}
|
||||
}
|
||||
if (obj == cur_misc[WEAR_BOOTS] ||
|
||||
obj == cur_misc[WEAR_BRACERS] ||
|
||||
obj == cur_misc[WEAR_CLOAK] ||
|
||||
obj == cur_misc[WEAR_GAUNTLET] ||
|
||||
obj == cur_misc[WEAR_NECKLACE] ||
|
||||
obj == cur_misc[WEAR_JEWEL])
|
||||
strcat(pb, " (being worn)");
|
||||
when GOLD:
|
||||
sprintf(pb, "%d Pieces of Gold", obj->o_count);
|
||||
otherwise:
|
||||
debug("Picked up something funny");
|
||||
sprintf(pb, "Something bizarre %s", unctrl(obj->o_type));
|
||||
}
|
||||
|
||||
/* Is it marked? */
|
||||
if (obj->o_mark[0]) {
|
||||
pb = &pb[strlen(pb)];
|
||||
sprintf(pb, " <%s>", obj->o_mark);
|
||||
}
|
||||
|
||||
if (obj->o_flags & ISPROT)
|
||||
strcat(pb, " [protected]");
|
||||
if (drop && isupper(prbuf[0]))
|
||||
prbuf[0] = tolower(prbuf[0]);
|
||||
else if (!drop && islower(*prbuf))
|
||||
*prbuf = toupper(*prbuf);
|
||||
if (!drop)
|
||||
strcat(pb, ".");
|
||||
/*
|
||||
* Truncate if long. Use COLS-4 to offset the "pack letter" of a normal
|
||||
* inventory listing.
|
||||
*/
|
||||
prbuf[COLS-4] = '\0';
|
||||
return prbuf;
|
||||
}
|
||||
|
||||
/*
|
||||
* weap_name:
|
||||
* Return the name of a weapon.
|
||||
*/
|
||||
char *
|
||||
weap_name(obj)
|
||||
register struct object *obj;
|
||||
{
|
||||
switch (obj->o_type) {
|
||||
case WEAPON:
|
||||
return(weaps[obj->o_which].w_name);
|
||||
when RELIC:
|
||||
switch (obj->o_which) {
|
||||
case MUSTY_DAGGER:
|
||||
return("daggers");
|
||||
when YEENOGHU_FLAIL:
|
||||
return("flail");
|
||||
when HRUGGEK_MSTAR:
|
||||
return("morning star");
|
||||
when MING_STAFF:
|
||||
return("staff");
|
||||
when ORCUS_WAND:
|
||||
return("wand");
|
||||
when ASMO_ROD:
|
||||
return("rod");
|
||||
}
|
||||
}
|
||||
return("weapon");
|
||||
}
|
||||
|
||||
/*
|
||||
* drop:
|
||||
* put something down
|
||||
*/
|
||||
drop(item)
|
||||
struct linked_list *item;
|
||||
{
|
||||
register char ch = 0;
|
||||
register struct linked_list *obj, *nobj;
|
||||
register struct object *op;
|
||||
|
||||
if (item == NULL) {
|
||||
switch(ch = CCHAR( mvwinch(stdscr, hero.y, hero.x) )) {
|
||||
case PASSAGE:
|
||||
case SCROLL:
|
||||
case POTION:
|
||||
case WEAPON:
|
||||
case FLOOR:
|
||||
case STICK:
|
||||
case ARMOR:
|
||||
case POOL:
|
||||
case RELIC:
|
||||
case GOLD:
|
||||
case FOOD:
|
||||
case RING:
|
||||
case MM:
|
||||
break;
|
||||
default:
|
||||
msg("Can't leave it here");
|
||||
return(FALSE);
|
||||
}
|
||||
if ((obj = get_item(pack, "drop", ALL)) == NULL)
|
||||
return(FALSE);
|
||||
}
|
||||
else {
|
||||
obj = item;
|
||||
}
|
||||
op = OBJPTR(obj);
|
||||
if (!dropcheck(op))
|
||||
return(FALSE);
|
||||
|
||||
/*
|
||||
* If it is a scare monster scroll, curse it
|
||||
*/
|
||||
if (op->o_type == SCROLL && op->o_which == S_SCARE) {
|
||||
if (op->o_flags & ISBLESSED)
|
||||
op->o_flags &= ~ISBLESSED;
|
||||
else op->o_flags |= ISCURSED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Take it out of the pack
|
||||
*/
|
||||
if (op->o_count >= 2 && op->o_group == 0)
|
||||
{
|
||||
nobj = new_item(sizeof *op);
|
||||
op->o_count--;
|
||||
op = OBJPTR(nobj);
|
||||
*op = *(OBJPTR(obj));
|
||||
op->o_count = 1;
|
||||
obj = nobj;
|
||||
}
|
||||
else {
|
||||
detach(pack, obj);
|
||||
inpack--;
|
||||
}
|
||||
if(ch == POOL) {
|
||||
msg("Your %s sinks out of sight.",inv_name(op,TRUE));
|
||||
o_discard(obj);
|
||||
}
|
||||
else if (levtype == POSTLEV) {
|
||||
op->o_pos = hero; /* same place as hero */
|
||||
fall(obj,FALSE);
|
||||
if (item == NULL) /* if item wasn't sold */
|
||||
msg("Thanks for your donation to the fiend's flea market.");
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Link it into the level object list
|
||||
*/
|
||||
attach(lvl_obj, obj);
|
||||
mvaddch(hero.y, hero.x, op->o_type);
|
||||
op->o_pos = hero;
|
||||
msg("Dropped %s", inv_name(op, TRUE));
|
||||
}
|
||||
updpack(FALSE);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* do special checks for dropping or unweilding|unwearing|unringing
|
||||
*/
|
||||
dropcheck(op)
|
||||
register struct object *op;
|
||||
{
|
||||
int save_max;
|
||||
|
||||
if (op == NULL)
|
||||
return TRUE;
|
||||
if (levtype == POSTLEV) {
|
||||
if ((op->o_flags & ISCURSED) && (op->o_flags & ISKNOW)) {
|
||||
msg("The trader does not accept your shoddy merchandise");
|
||||
return(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Player will not drop a relic */
|
||||
if (op->o_type == RELIC) {
|
||||
/*
|
||||
* There is a 1% cumulative chance per relic that trying to get
|
||||
* rid of it will cause the relic to turn on the player.
|
||||
*/
|
||||
if (rnd(100) < cur_relic[op->o_which]++) {
|
||||
msg("The artifact turns on you.");
|
||||
msg("It crushes your mind!!! -- More --");
|
||||
pstats.s_hpt = -1;
|
||||
wait_for (cw,' ');
|
||||
death(D_RELIC);
|
||||
}
|
||||
else {
|
||||
if (terse) msg("Can't release it.");
|
||||
else msg("You cannot bring yourself to release it.");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we aren't wearing it, we can drop it */
|
||||
if (!is_current(op)) return TRUE;
|
||||
|
||||
/* At this point, we know we are wearing the item */
|
||||
if (op->o_flags & ISCURSED) {
|
||||
msg("You can't. It appears to be cursed.");
|
||||
return FALSE;
|
||||
}
|
||||
if (op == cur_armor) {
|
||||
waste_time();
|
||||
}
|
||||
else if (op->o_type == RING) {
|
||||
if (cur_misc[WEAR_GAUNTLET] != NULL) {
|
||||
msg ("You have to remove your gauntlets first!");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
switch (op->o_which) {
|
||||
case R_ADDSTR: save_max = max_stats.s_str;
|
||||
chg_str(-op->o_ac);
|
||||
max_stats.s_str = save_max;
|
||||
when R_ADDHIT: pstats.s_dext -= op->o_ac;
|
||||
when R_ADDINTEL: pstats.s_intel -= op->o_ac;
|
||||
when R_ADDWISDOM: pstats.s_wisdom -= op->o_ac;
|
||||
when R_SEEINVIS: if (find_slot(unsee) == 0) {
|
||||
turn_off(player, CANSEE);
|
||||
msg("The tingling feeling leaves your eyes");
|
||||
}
|
||||
light(&hero);
|
||||
mvwaddch(cw, hero.y, hero.x, PLAYER);
|
||||
when R_WARMTH: turn_off(player, NOCOLD);
|
||||
when R_FIRE: turn_off(player, NOFIRE);
|
||||
when R_LIGHT: {
|
||||
if(roomin(&hero) != NULL) {
|
||||
light(&hero);
|
||||
mvwaddch(cw, hero.y, hero.x, PLAYER);
|
||||
}
|
||||
}
|
||||
when R_SEARCH: kill_daemon(ring_search);
|
||||
when R_TELEPORT: kill_daemon(ring_teleport);
|
||||
}
|
||||
}
|
||||
else if (op->o_type == MM) {
|
||||
switch (op->o_which) {
|
||||
case MM_ADAPTION:
|
||||
turn_off(player, NOGAS);
|
||||
|
||||
when MM_STRANGLE:
|
||||
msg("You can breathe again.....whew!");
|
||||
kill_daemon(strangle);
|
||||
|
||||
when MM_DANCE:
|
||||
turn_off(player, ISDANCE);
|
||||
msg ("Your feet take a break.....whew!");
|
||||
|
||||
when MM_FUMBLE:
|
||||
kill_daemon(fumble);
|
||||
}
|
||||
}
|
||||
cur_null(op); /* set current to NULL */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* return a new thing
|
||||
*/
|
||||
struct linked_list *
|
||||
new_thing(thing_type)
|
||||
int thing_type;
|
||||
{
|
||||
register struct linked_list *item;
|
||||
register struct object *cur;
|
||||
register int j, k;
|
||||
register int blesschance, cursechance;
|
||||
|
||||
item = new_item(sizeof *cur);
|
||||
cur = OBJPTR(item);
|
||||
cur->o_hplus = cur->o_dplus = 0;
|
||||
strcpy(cur->o_damage,"0d0");
|
||||
strcpy(cur->o_hurldmg,"0d0");
|
||||
cur->o_ac = 0;
|
||||
cur->o_count = 1;
|
||||
cur->o_group = 0;
|
||||
cur->contents = NULL;
|
||||
cur->o_flags = 0;
|
||||
cur->o_weight = 0;
|
||||
cur->o_mark[0] = '\0';
|
||||
/*
|
||||
* Decide what kind of object it will be
|
||||
* If we haven't had food for a while, let it be food.
|
||||
*/
|
||||
blesschance = rnd(100);
|
||||
cursechance = rnd(100);
|
||||
|
||||
/* Get the type of item (pick one if 'any' is specified) */
|
||||
if (thing_type == ALL) j = pick_one(things, NUMTHINGS);
|
||||
else j = thing_type;
|
||||
|
||||
/*
|
||||
* make sure he gets his vitamins
|
||||
*/
|
||||
if (thing_type == ALL && no_food > 3)
|
||||
j = 2;
|
||||
/*
|
||||
* limit the number of foods on a level because it sometimes
|
||||
* gets out of hand in the "deep" levels where there is a
|
||||
* treasure room on most every level with lots of food in it
|
||||
*/
|
||||
while (thing_type == ALL && levtype != POSTLEV && foods_this_level > 2 &&
|
||||
j == 2)
|
||||
j = pick_one(things, NUMTHINGS); /* not too many.... */
|
||||
switch (j)
|
||||
{
|
||||
case TYP_POTION:
|
||||
cur->o_type = POTION;
|
||||
cur->o_which = pick_one(p_magic, MAXPOTIONS);
|
||||
cur->o_weight = things[TYP_POTION].mi_wght;
|
||||
if (cursechance < p_magic[cur->o_which].mi_curse)
|
||||
cur->o_flags |= ISCURSED;
|
||||
else if (blesschance < p_magic[cur->o_which].mi_bless)
|
||||
cur->o_flags |= ISBLESSED;
|
||||
when TYP_SCROLL:
|
||||
cur->o_type = SCROLL;
|
||||
cur->o_which = pick_one(s_magic, MAXSCROLLS);
|
||||
cur->o_weight = things[TYP_SCROLL].mi_wght;
|
||||
if (cursechance < s_magic[cur->o_which].mi_curse)
|
||||
cur->o_flags |= ISCURSED;
|
||||
else if (blesschance < s_magic[cur->o_which].mi_bless)
|
||||
cur->o_flags |= ISBLESSED;
|
||||
when TYP_FOOD:
|
||||
no_food = 0;
|
||||
cur->o_type = FOOD;
|
||||
cur->o_weight = things[TYP_FOOD].mi_wght;
|
||||
cur->o_count += extras();
|
||||
foods_this_level += cur->o_count;
|
||||
if (rnd(100) > 10)
|
||||
cur->o_which = 0;
|
||||
else
|
||||
cur->o_which = 1;
|
||||
when TYP_WEAPON:
|
||||
cur->o_type = WEAPON;
|
||||
cur->o_which = rnd(MAXWEAPONS);
|
||||
init_weapon(cur, cur->o_which);
|
||||
if (cursechance < 20)
|
||||
{
|
||||
|
||||
cur->o_flags |= ISCURSED;
|
||||
cur->o_hplus -= rnd(2) + 1;
|
||||
cur->o_dplus -= rnd(2) + 1;
|
||||
}
|
||||
else if (blesschance < 50) {
|
||||
|
||||
cur->o_hplus += rnd(5) + 1;
|
||||
cur->o_dplus += rnd(5) + 1;
|
||||
}
|
||||
when TYP_ARMOR:
|
||||
cur->o_type = ARMOR;
|
||||
for (j = 0; j < MAXARMORS; j++)
|
||||
if (blesschance < armors[j].a_prob)
|
||||
break;
|
||||
if (j == MAXARMORS)
|
||||
{
|
||||
debug("Picked a bad armor %d", blesschance);
|
||||
j = 0;
|
||||
}
|
||||
cur->o_which = j;
|
||||
cur->o_ac = armors[j].a_class;
|
||||
cur->o_weight = armors[j].a_wght;
|
||||
if ((k = rnd(100)) < 20)
|
||||
{
|
||||
cur->o_flags |= ISCURSED;
|
||||
cur->o_ac += rnd(3)+1;
|
||||
}
|
||||
else if (k < 35)
|
||||
cur->o_ac -= rnd(3)+1;
|
||||
when TYP_RING:
|
||||
cur->o_type = RING;
|
||||
cur->o_which = pick_one(r_magic, MAXRINGS);
|
||||
cur->o_weight = things[TYP_RING].mi_wght;
|
||||
if (cursechance < r_magic[cur->o_which].mi_curse)
|
||||
cur->o_flags |= ISCURSED;
|
||||
else if (blesschance < r_magic[cur->o_which].mi_bless)
|
||||
cur->o_flags |= ISBLESSED;
|
||||
switch (cur->o_which)
|
||||
{
|
||||
case R_ADDSTR:
|
||||
case R_ADDWISDOM:
|
||||
case R_ADDINTEL:
|
||||
case R_PROTECT:
|
||||
case R_ADDHIT:
|
||||
case R_ADDDAM:
|
||||
cur->o_ac = rnd(2) + 1; /* From 1 to 3 */
|
||||
if (cur->o_flags & ISCURSED)
|
||||
cur->o_ac = -cur->o_ac;
|
||||
if (cur->o_flags & ISBLESSED) cur->o_ac++;
|
||||
when R_DIGEST:
|
||||
if (cur->o_flags & ISCURSED) cur->o_ac = -1;
|
||||
else if (cur->o_flags & ISBLESSED) cur->o_ac = 2;
|
||||
else cur->o_ac = 1;
|
||||
}
|
||||
when TYP_STICK:
|
||||
cur->o_type = STICK;
|
||||
cur->o_which = pick_one(ws_magic, MAXSTICKS);
|
||||
fix_stick(cur);
|
||||
if (cursechance < ws_magic[cur->o_which].mi_curse)
|
||||
cur->o_flags |= ISCURSED;
|
||||
else if (blesschance < ws_magic[cur->o_which].mi_bless)
|
||||
cur->o_flags |= ISBLESSED;
|
||||
when TYP_MM:
|
||||
cur->o_type = MM;
|
||||
cur->o_which = pick_one(m_magic, MAXMM);
|
||||
cur->o_weight = things[TYP_MM].mi_wght;
|
||||
if (cursechance < m_magic[cur->o_which].mi_curse)
|
||||
cur->o_flags |= ISCURSED;
|
||||
else if (blesschance < m_magic[cur->o_which].mi_bless)
|
||||
cur->o_flags |= ISBLESSED;
|
||||
switch (cur->o_which) {
|
||||
case MM_JUG:
|
||||
switch(rnd(7)) {
|
||||
case 0: cur->o_ac = P_PHASE;
|
||||
when 1: cur->o_ac = P_CLEAR;
|
||||
when 2: cur->o_ac = P_SEEINVIS;
|
||||
when 3: cur->o_ac = P_HEALING;
|
||||
when 4: cur->o_ac = P_MFIND;
|
||||
when 5: cur->o_ac = P_TFIND;
|
||||
when 6: cur->o_ac = P_HASTE;
|
||||
when 7: cur->o_ac = P_RESTORE;
|
||||
}
|
||||
when MM_OPEN:
|
||||
case MM_HUNGER:
|
||||
case MM_DRUMS:
|
||||
case MM_DISAPPEAR:
|
||||
case MM_CHOKE:
|
||||
case MM_KEOGHTOM:
|
||||
cur->o_ac = 3 + (rnd(3)+1) * 3;
|
||||
when MM_BRACERS:
|
||||
if (cur->o_flags & ISCURSED)
|
||||
cur->o_ac = -(rnd(3)+1);
|
||||
else
|
||||
cur->o_ac = rnd(8)+1;
|
||||
when MM_PROTECT:
|
||||
if (cur->o_flags & ISCURSED)
|
||||
cur->o_ac = -(rnd(3)+1);
|
||||
else
|
||||
cur->o_ac = rnd(5)+1;
|
||||
when MM_DISP:
|
||||
cur->o_ac = 2;
|
||||
when MM_SKILLS:
|
||||
cur->o_ac = rnd(4); /* set it to some character class */
|
||||
otherwise:
|
||||
cur->o_ac = 0;
|
||||
}
|
||||
otherwise:
|
||||
debug("Picked a bad kind of object");
|
||||
wait_for(msg,' ');
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
/*
|
||||
* provide a new item tailored to specification
|
||||
*/
|
||||
struct linked_list *
|
||||
spec_item(type, which, hit, damage)
|
||||
int type, which, hit, damage;
|
||||
{
|
||||
register struct linked_list *item;
|
||||
register struct object *obj;
|
||||
|
||||
item = new_item(sizeof *obj);
|
||||
obj = OBJPTR(item);
|
||||
obj->o_count = 1;
|
||||
obj->o_group = 0;
|
||||
obj->contents = NULL;
|
||||
obj->o_type = type;
|
||||
obj->o_which = which;
|
||||
strcpy(obj->o_damage,"0d0");
|
||||
strcpy(obj->o_hurldmg,"0d0");
|
||||
obj->o_hplus = 0;
|
||||
obj->o_dplus = 0;
|
||||
obj->o_flags = 0;
|
||||
obj->o_mark[0] = '\0';
|
||||
obj->o_text = NULL;
|
||||
obj->o_launch = 0;
|
||||
obj->o_weight = 0;
|
||||
|
||||
/* Handle special characteristics */
|
||||
switch (type) {
|
||||
case WEAPON:
|
||||
init_weapon(obj, which);
|
||||
obj->o_hplus = hit;
|
||||
obj->o_dplus = damage;
|
||||
obj->o_ac = 10;
|
||||
|
||||
if (hit > 0 || damage > 0) obj->o_flags |= ISBLESSED;
|
||||
else if (hit < 0 || damage < 0) obj->o_flags |= ISCURSED;
|
||||
|
||||
when ARMOR:
|
||||
obj->o_ac = armors[which].a_class - hit;
|
||||
if (hit > 0) obj->o_flags |= ISBLESSED;
|
||||
else if (hit < 0) obj->o_flags |= ISCURSED;
|
||||
|
||||
when RING:
|
||||
obj->o_ac = hit;
|
||||
switch (obj->o_which) {
|
||||
case R_ADDSTR:
|
||||
case R_ADDWISDOM:
|
||||
case R_ADDINTEL:
|
||||
case R_PROTECT:
|
||||
case R_ADDHIT:
|
||||
case R_ADDDAM:
|
||||
case R_DIGEST:
|
||||
if (hit > 1) obj->o_flags |= ISBLESSED;
|
||||
else if (hit < 0) obj->o_flags |= ISCURSED;
|
||||
}
|
||||
|
||||
when STICK:
|
||||
fix_stick(obj);
|
||||
obj->o_charges = hit;
|
||||
|
||||
when GOLD:
|
||||
obj->o_type = GOLD;
|
||||
obj->o_count = GOLDCALC;
|
||||
obj->o_ac = 11;
|
||||
|
||||
when MM:
|
||||
obj->o_type = MM;
|
||||
obj->o_ac = hit;
|
||||
|
||||
when RELIC:
|
||||
/* Handle weight here since these are all created uniquely */
|
||||
obj->o_weight = things[TYP_RELIC].mi_wght;
|
||||
|
||||
}
|
||||
return(item);
|
||||
}
|
||||
|
||||
/*
|
||||
* pick an item out of a list of nitems possible magic items
|
||||
*/
|
||||
pick_one(magic, nitems)
|
||||
register struct magic_item *magic;
|
||||
int nitems;
|
||||
{
|
||||
register struct magic_item *end;
|
||||
register int i;
|
||||
register struct magic_item *start;
|
||||
|
||||
start = magic;
|
||||
for (end = &magic[nitems], i = rnd(1000); magic < end; magic++)
|
||||
if (i < magic->mi_prob)
|
||||
break;
|
||||
if (magic == end)
|
||||
{
|
||||
if (wizard)
|
||||
{
|
||||
sprintf(outstring,"bad pick_one: %d from %d items", i, nitems);
|
||||
msg(outstring);
|
||||
for (magic = start; magic < end; magic++){
|
||||
sprintf(outstring,"%s: %d%%", magic->mi_name, magic->mi_prob);
|
||||
msg(outstring);
|
||||
}
|
||||
}
|
||||
magic = start;
|
||||
}
|
||||
return (int)(magic - start);
|
||||
}
|
||||
|
||||
|
||||
/* blesscurse returns whether, according to the flag, the object is
|
||||
* blessed, cursed, or neither
|
||||
*/
|
||||
|
||||
char *
|
||||
blesscurse(flags)
|
||||
int flags;
|
||||
{
|
||||
if (flags & ISKNOW) {
|
||||
if (flags & ISCURSED) return("cursed ");
|
||||
if (flags & ISBLESSED) return("blessed ");
|
||||
return("normal ");
|
||||
}
|
||||
return("");
|
||||
}
|
||||
|
||||
/*
|
||||
* extras:
|
||||
* Return the number of extra items to be created
|
||||
*/
|
||||
extras()
|
||||
{
|
||||
reg int i;
|
||||
|
||||
i = rnd(100);
|
||||
if (i < 4) /* 4% for 2 more */
|
||||
return (2);
|
||||
else if (i < 11) /* 7% for 1 more */
|
||||
return (1);
|
||||
else /* otherwise no more */
|
||||
return (0);
|
||||
}
|
||||
336
arogue5/trader.c
Normal file
336
arogue5/trader.c
Normal file
|
|
@ -0,0 +1,336 @@
|
|||
/*
|
||||
* Anything to do with trading posts
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Super-Rogue"
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "curses.h"
|
||||
#include "rogue.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* buy_it:
|
||||
* Buy the item on which the hero stands
|
||||
*/
|
||||
buy_it()
|
||||
{
|
||||
reg int wh;
|
||||
struct linked_list *item;
|
||||
|
||||
if (purse <= 0) {
|
||||
msg("You have no money.");
|
||||
return;
|
||||
}
|
||||
if (curprice < 0) { /* if not yet priced */
|
||||
wh = price_it();
|
||||
if (!wh) /* nothing to price */
|
||||
return;
|
||||
msg("Do you want to buy it? ");
|
||||
do {
|
||||
wh = tolower(readchar());
|
||||
if (wh == ESCAPE || wh == 'n') {
|
||||
msg("");
|
||||
return;
|
||||
}
|
||||
} until(wh == 'y');
|
||||
}
|
||||
mpos = 0;
|
||||
if (curprice > purse) {
|
||||
msg("You can't afford to buy that %s !",curpurch);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* See if the hero has done all his transacting
|
||||
*/
|
||||
if (!open_market())
|
||||
return;
|
||||
/*
|
||||
* The hero bought the item here
|
||||
*/
|
||||
item = find_obj(hero.y, hero.x);
|
||||
mpos = 0;
|
||||
if (add_pack(NULL,TRUE,&item)) { /* try to put it in his pack */
|
||||
purse -= curprice; /* take his money */
|
||||
++trader; /* another transaction */
|
||||
trans_line(); /* show remaining deals */
|
||||
curprice = -1; /* reset stuff */
|
||||
curpurch[0] = 0;
|
||||
whatis (item); /* identify it after purchase */
|
||||
(OBJPTR(item))->o_flags &= ~ISPOST; /* turn off ISPOST */
|
||||
msg("%s", inv_name(OBJPTR(item), TRUE));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* do_post:
|
||||
* Put a trading post room and stuff on the screen
|
||||
*/
|
||||
do_post()
|
||||
{
|
||||
coord tp;
|
||||
reg int i;
|
||||
reg struct room *rp;
|
||||
reg struct object *op;
|
||||
reg struct linked_list *ll;
|
||||
|
||||
o_free_list(lvl_obj); /* throw old items away */
|
||||
|
||||
for (rp = rooms; rp < &rooms[MAXROOMS]; rp++)
|
||||
rp->r_flags = ISGONE; /* kill all rooms */
|
||||
|
||||
rp = &rooms[0]; /* point to only room */
|
||||
rp->r_flags = 0; /* this room NOT gone */
|
||||
rp->r_max.x = 40;
|
||||
rp->r_max.y = 10; /* 10 * 40 room */
|
||||
rp->r_pos.x = (COLS - rp->r_max.x) / 2; /* center horizontal */
|
||||
rp->r_pos.y = 1; /* 2nd line */
|
||||
draw_room(rp); /* draw the only room */
|
||||
i = roll(4,10); /* 10 to 40 items */
|
||||
for (; i > 0 ; i--) { /* place all the items */
|
||||
ll = new_thing(ALL); /* get something */
|
||||
attach(lvl_obj, ll);
|
||||
op = OBJPTR(ll);
|
||||
op->o_flags |= ISPOST; /* object in trading post */
|
||||
do {
|
||||
rnd_pos(rp,&tp);
|
||||
} until (mvinch(tp.y, tp.x) == FLOOR);
|
||||
op->o_pos = tp;
|
||||
mvaddch(tp.y,tp.x,op->o_type);
|
||||
}
|
||||
trader = 0;
|
||||
wmove(cw,12,0);
|
||||
waddstr(cw,"Welcome to Friendly Fiend's Flea Market\n\r");
|
||||
waddstr(cw,"=======================================\n\r");
|
||||
waddstr(cw,"$: Prices object that you stand upon.\n\r");
|
||||
waddstr(cw,"#: Buys the object that you stand upon.\n\r");
|
||||
waddstr(cw,"%: Trades in something in your pack for gold.\n\r");
|
||||
trans_line();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_worth:
|
||||
* Calculate an objects worth in gold
|
||||
*/
|
||||
get_worth(obj)
|
||||
reg struct object *obj;
|
||||
{
|
||||
reg int worth, wh;
|
||||
|
||||
worth = 0;
|
||||
wh = obj->o_which;
|
||||
switch (obj->o_type) {
|
||||
case FOOD:
|
||||
worth = 2;
|
||||
when WEAPON:
|
||||
if (wh < MAXWEAPONS) {
|
||||
worth = weaps[wh].w_worth;
|
||||
worth += s_magic[S_ALLENCH].mi_worth *
|
||||
(obj->o_hplus + obj->o_dplus);
|
||||
}
|
||||
when ARMOR:
|
||||
if (wh < MAXARMORS) {
|
||||
worth = armors[wh].a_worth;
|
||||
worth += s_magic[S_ALLENCH].mi_worth *
|
||||
(armors[wh].a_class - obj->o_ac);
|
||||
}
|
||||
when SCROLL:
|
||||
if (wh < MAXSCROLLS)
|
||||
worth = s_magic[wh].mi_worth;
|
||||
when POTION:
|
||||
if (wh < MAXPOTIONS)
|
||||
worth = p_magic[wh].mi_worth;
|
||||
when RING:
|
||||
if (wh < MAXRINGS) {
|
||||
worth = r_magic[wh].mi_worth;
|
||||
worth += obj->o_ac * 40;
|
||||
}
|
||||
when STICK:
|
||||
if (wh < MAXSTICKS) {
|
||||
worth = ws_magic[wh].mi_worth;
|
||||
worth += 20 * obj->o_charges;
|
||||
}
|
||||
when MM:
|
||||
if (wh < MAXMM) {
|
||||
worth = m_magic[wh].mi_worth;
|
||||
switch (wh) {
|
||||
case MM_BRACERS: worth += 40 * obj->o_ac;
|
||||
when MM_PROTECT: worth += 60 * obj->o_ac;
|
||||
when MM_DISP: /* ac already figured in price*/
|
||||
otherwise: worth += 20 * obj->o_ac;
|
||||
}
|
||||
}
|
||||
when RELIC:
|
||||
if (wh < MAXRELIC) {
|
||||
worth = rel_magic[wh].mi_worth;
|
||||
if (wh == quest_item) worth *= 10;
|
||||
}
|
||||
otherwise:
|
||||
worth = 0;
|
||||
}
|
||||
if (obj->o_flags & ISPROT) /* 300% more for protected */
|
||||
worth *= 3;
|
||||
if (obj->o_flags & ISBLESSED) /* 50% more for blessed */
|
||||
worth = worth * 3 / 2;
|
||||
if (obj->o_flags & ISCURSED) /* half for cursed */
|
||||
worth /= 2;
|
||||
if (worth < 0)
|
||||
worth = 0;
|
||||
return worth;
|
||||
}
|
||||
|
||||
/*
|
||||
* open_market:
|
||||
* Retruns TRUE when ok do to transacting
|
||||
*/
|
||||
open_market()
|
||||
{
|
||||
if (trader >= MAXPURCH && !wizard) {
|
||||
msg("The market is closed. The stairs are that-a-way.");
|
||||
return FALSE;
|
||||
}
|
||||
else {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* price_it:
|
||||
* Price the object that the hero stands on
|
||||
*/
|
||||
price_it()
|
||||
{
|
||||
reg struct linked_list *item;
|
||||
reg struct object *obj;
|
||||
reg int worth;
|
||||
reg char *str;
|
||||
|
||||
if (!open_market()) /* after buying hours */
|
||||
return FALSE;
|
||||
if ((item = find_obj(hero.y,hero.x)) == NULL)
|
||||
return FALSE;
|
||||
obj = OBJPTR(item);
|
||||
worth = get_worth(obj);
|
||||
if (worth < 0) {
|
||||
msg("That's not for sale.");
|
||||
return FALSE;
|
||||
}
|
||||
if (worth < 25)
|
||||
worth = 25;
|
||||
worth *= 3; /* slightly expensive */
|
||||
str = inv_name(obj, TRUE);
|
||||
sprintf(outstring,"%s for only %d pieces of gold", str, worth);
|
||||
msg(outstring);
|
||||
curprice = worth; /* save price */
|
||||
strcpy(curpurch,str); /* save item */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* sell_it:
|
||||
* Sell an item to the trading post
|
||||
*/
|
||||
sell_it()
|
||||
{
|
||||
reg struct linked_list *item;
|
||||
reg struct object *obj;
|
||||
reg int wo, ch;
|
||||
|
||||
if (!open_market()) /* after selling hours */
|
||||
return;
|
||||
|
||||
if ((item = get_item(pack, "sell", ALL)) == NULL)
|
||||
return;
|
||||
obj = OBJPTR(item);
|
||||
wo = get_worth(obj);
|
||||
if (wo <= 0) {
|
||||
mpos = 0;
|
||||
msg("We don't buy those.");
|
||||
return;
|
||||
}
|
||||
if (wo < 25)
|
||||
wo = 25;
|
||||
sprintf(outstring,"Your %s is worth %d pieces of gold.",typ_name(obj),wo);
|
||||
msg(outstring);
|
||||
msg("Do you want to sell it? ");
|
||||
do {
|
||||
ch = tolower(readchar());
|
||||
if (ch == ESCAPE || ch == 'n') {
|
||||
msg("");
|
||||
return;
|
||||
}
|
||||
} until (ch == 'y');
|
||||
mpos = 0;
|
||||
if (drop(item) == TRUE) { /* drop this item */
|
||||
purse += wo; /* give him his money */
|
||||
++trader; /* another transaction */
|
||||
wo = obj->o_count;
|
||||
if (obj->o_group == 0) /* dropped one at a time */
|
||||
obj->o_count = 1;
|
||||
msg("Sold %s",inv_name(obj,TRUE));
|
||||
obj->o_count = wo;
|
||||
trans_line(); /* show remaining deals */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* trans_line:
|
||||
* Show how many transactions the hero has left
|
||||
*/
|
||||
trans_line()
|
||||
{
|
||||
if (!wizard)
|
||||
sprintf(prbuf,"You have %d transactions remaining.",
|
||||
MAXPURCH - trader);
|
||||
else
|
||||
sprintf(prbuf,
|
||||
"You have infinite transactions remaining oh great wizard");
|
||||
mvwaddstr(cw,LINES - 3,0,prbuf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* typ_name:
|
||||
* Return the name for this type of object
|
||||
*/
|
||||
char *
|
||||
typ_name(obj)
|
||||
reg struct object *obj;
|
||||
{
|
||||
static char buff[20];
|
||||
reg int wh;
|
||||
|
||||
switch (obj->o_type) {
|
||||
case POTION: wh = TYP_POTION;
|
||||
when SCROLL: wh = TYP_SCROLL;
|
||||
when STICK: wh = TYP_STICK;
|
||||
when RING: wh = TYP_RING;
|
||||
when ARMOR: wh = TYP_ARMOR;
|
||||
when WEAPON: wh = TYP_WEAPON;
|
||||
when MM: wh = TYP_MM;
|
||||
when FOOD: wh = TYP_FOOD;
|
||||
when RELIC: wh = TYP_RELIC;
|
||||
otherwise: wh = -1;
|
||||
}
|
||||
if (wh < 0)
|
||||
strcpy(buff,"unknown");
|
||||
else
|
||||
strcpy(buff,things[wh].mi_name);
|
||||
return (buff);
|
||||
}
|
||||
|
||||
|
||||
921
arogue5/util.c
Normal file
921
arogue5/util.c
Normal file
|
|
@ -0,0 +1,921 @@
|
|||
/*
|
||||
* all sorts of miscellaneous routines
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "curses.h"
|
||||
#include "rogue.h"
|
||||
#include <ctype.h>
|
||||
|
||||
/*
|
||||
* aggravate:
|
||||
* aggravate all the monsters on this level
|
||||
*/
|
||||
|
||||
aggravate()
|
||||
{
|
||||
register struct linked_list *mi;
|
||||
|
||||
for (mi = mlist; mi != NULL; mi = next(mi))
|
||||
runto(THINGPTR(mi), &hero);
|
||||
}
|
||||
|
||||
/*
|
||||
* cansee:
|
||||
* returns true if the hero can see a certain coordinate.
|
||||
*/
|
||||
|
||||
cansee(y, x)
|
||||
register int y, x;
|
||||
{
|
||||
register struct room *rer;
|
||||
register int radius;
|
||||
coord tp;
|
||||
|
||||
if (on(player, ISBLIND))
|
||||
return FALSE;
|
||||
|
||||
tp.y = y;
|
||||
tp.x = x;
|
||||
rer = roomin(&tp);
|
||||
|
||||
/* How far can we see? */
|
||||
if (levtype == OUTSIDE) {
|
||||
if (daytime) radius = 36;
|
||||
else if (lit_room(rer)) radius = 9;
|
||||
else radius = 3;
|
||||
}
|
||||
else radius = 3;
|
||||
|
||||
/*
|
||||
* We can only see if the hero in the same room as
|
||||
* the coordinate and the room is lit or if it is close.
|
||||
*/
|
||||
return ((rer != NULL &&
|
||||
levtype != OUTSIDE &&
|
||||
(levtype != MAZELEV || /* Maze level needs direct line */
|
||||
maze_view(tp.y, tp.x)) &&
|
||||
rer == roomin(&hero) &&
|
||||
lit_room(rer)) ||
|
||||
DISTANCE(y, x, hero.y, hero.x) < radius);
|
||||
}
|
||||
|
||||
/*
|
||||
* check_level:
|
||||
* Check to see if the guy has gone up a level.
|
||||
*
|
||||
* Return points needed to obtain next level.
|
||||
*
|
||||
* These are the beginning experience levels for all players.
|
||||
* All further experience levels are computed by muliplying by 2
|
||||
* up through MAXDOUBLE.
|
||||
*/
|
||||
#define MAXDOUBLE 14 /* Maximum number of times score is doubled */
|
||||
static struct {
|
||||
long base; /* What it starts out at for doubling */
|
||||
long cap; /* The maximum before doubling stops */
|
||||
} e_levels[4] = {
|
||||
/* You must change MAXDOUBLE if you change the cap figure */
|
||||
{ 90L, 1474560L }, /* Fighter */
|
||||
{ 130L, 2129920L }, /* Magician */
|
||||
{ 110L, 1802240L }, /* cleric */
|
||||
{ 75L, 1228800L } /* Thief */
|
||||
};
|
||||
|
||||
long
|
||||
check_level(get_spells)
|
||||
bool get_spells;
|
||||
{
|
||||
register int i, j, add = 0;
|
||||
register unsigned long exp;
|
||||
long retval; /* Return value */
|
||||
int nsides = 0;
|
||||
|
||||
/* See if we are past the doubling stage */
|
||||
exp = e_levels[player.t_ctype].cap;
|
||||
if (pstats.s_exp >= exp) {
|
||||
i = pstats.s_exp/exp; /* First get amount above doubling area */
|
||||
retval = exp + i * exp; /* Compute next higher boundary */
|
||||
i += MAXDOUBLE; /* Add in the previous doubled levels */
|
||||
}
|
||||
else {
|
||||
i = 0;
|
||||
exp = e_levels[player.t_ctype].base;
|
||||
while (exp <= pstats.s_exp) {
|
||||
i++;
|
||||
exp <<= 1;
|
||||
}
|
||||
retval = exp;
|
||||
}
|
||||
if (++i > pstats.s_lvl) {
|
||||
switch (player.t_ctype) {
|
||||
case C_FIGHTER: nsides = 10;
|
||||
when C_MAGICIAN: nsides = 4;
|
||||
when C_CLERIC: nsides = 8;
|
||||
when C_THIEF: nsides = 6;
|
||||
}
|
||||
|
||||
/* Take care of multi-level jumps */
|
||||
for (j=0; j < (i-pstats.s_lvl); j++)
|
||||
add += max(1, roll(1,nsides) + const_bonus());
|
||||
max_stats.s_hpt += add;
|
||||
if ((pstats.s_hpt += add) > max_stats.s_hpt)
|
||||
pstats.s_hpt = max_stats.s_hpt;
|
||||
sprintf(outstring,"Welcome, %s, to level %d",
|
||||
cnames[player.t_ctype][min(i-1, 10)], i);
|
||||
msg(outstring);
|
||||
if (get_spells) {
|
||||
pray_time = 0; /* A new round of prayers */
|
||||
spell_power = 0; /* A new round of spells */
|
||||
}
|
||||
}
|
||||
pstats.s_lvl = i;
|
||||
return(retval);
|
||||
}
|
||||
|
||||
/*
|
||||
* Used to modify the playes strength
|
||||
* it keeps track of the highest it has been, just in case
|
||||
*/
|
||||
|
||||
chg_str(amt)
|
||||
register int amt;
|
||||
{
|
||||
register int ring_str; /* ring strengths */
|
||||
register struct stats *ptr; /* for speed */
|
||||
|
||||
ptr = &pstats;
|
||||
ring_str = ring_value(R_ADDSTR);
|
||||
ptr->s_str -= ring_str;
|
||||
ptr->s_str += amt;
|
||||
if (ptr->s_str > 25)
|
||||
ptr->s_str = 25;
|
||||
if (ptr->s_str > max_stats.s_str)
|
||||
max_stats.s_str = ptr->s_str;
|
||||
ptr->s_str += ring_str;
|
||||
if (ptr->s_str <= 0)
|
||||
death(D_STRENGTH);
|
||||
updpack(TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* this routine computes the players current AC without dex bonus's
|
||||
*/
|
||||
int
|
||||
ac_compute()
|
||||
{
|
||||
register int ac;
|
||||
|
||||
ac = cur_armor != NULL ? cur_armor->o_ac : pstats.s_arm;
|
||||
ac -= ring_value(R_PROTECT);
|
||||
if (cur_misc[WEAR_BRACERS] != NULL)
|
||||
ac -= cur_misc[WEAR_BRACERS]->o_ac;
|
||||
if (cur_misc[WEAR_CLOAK] != NULL)
|
||||
ac -= cur_misc[WEAR_CLOAK]->o_ac;
|
||||
|
||||
/* If player has the cloak, must be wearing it */
|
||||
if (cur_relic[EMORI_CLOAK]) ac -= 5;
|
||||
|
||||
if (ac > 10)
|
||||
ac = 10;
|
||||
return(ac);
|
||||
}
|
||||
|
||||
/*
|
||||
* this routine computes the players current strength
|
||||
*/
|
||||
str_compute()
|
||||
{
|
||||
if (cur_misc[WEAR_GAUNTLET] != NULL &&
|
||||
cur_misc[WEAR_GAUNTLET]->o_which == MM_G_OGRE) {
|
||||
if (cur_misc[WEAR_GAUNTLET]->o_flags & ISCURSED)
|
||||
return (3);
|
||||
else
|
||||
return (18);
|
||||
}
|
||||
else
|
||||
return (pstats.s_str);
|
||||
}
|
||||
|
||||
/*
|
||||
* this routine computes the players current dexterity
|
||||
*/
|
||||
dex_compute()
|
||||
{
|
||||
if (cur_misc[WEAR_GAUNTLET] != NULL &&
|
||||
cur_misc[WEAR_GAUNTLET]->o_which == MM_G_DEXTERITY) {
|
||||
if (cur_misc[WEAR_GAUNTLET]->o_flags & ISCURSED)
|
||||
return (3);
|
||||
else
|
||||
return (18);
|
||||
}
|
||||
else
|
||||
return (pstats.s_dext);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* diag_ok:
|
||||
* Check to see if the move is legal if it is diagonal
|
||||
*/
|
||||
|
||||
diag_ok(sp, ep, flgptr)
|
||||
register coord *sp, *ep;
|
||||
struct thing *flgptr;
|
||||
{
|
||||
register int numpaths = 0;
|
||||
|
||||
/* Horizontal and vertical moves are always ok */
|
||||
if (ep->x == sp->x || ep->y == sp->y)
|
||||
return TRUE;
|
||||
|
||||
/* Diagonal moves are not allowed if there is a horizontal or
|
||||
* vertical path to the destination
|
||||
*/
|
||||
if (step_ok(ep->y, sp->x, MONSTOK, flgptr)) numpaths++;
|
||||
if (step_ok(sp->y, ep->x, MONSTOK, flgptr)) numpaths++;
|
||||
return(numpaths != 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* eat:
|
||||
* He wants to eat something, so let him try
|
||||
*/
|
||||
|
||||
eat()
|
||||
{
|
||||
register struct linked_list *item;
|
||||
|
||||
if ((item = get_item(pack, "eat", FOOD)) == NULL)
|
||||
return;
|
||||
if ((OBJPTR(item))->o_which == 1)
|
||||
msg("My, that was a yummy %s", fruit);
|
||||
else {
|
||||
if (rnd(100) > 70) {
|
||||
msg("Yuk, this food tastes awful");
|
||||
|
||||
/* Do a check for overflow before increasing experience */
|
||||
if (pstats.s_exp + 1L > pstats.s_exp) pstats.s_exp++;
|
||||
check_level(TRUE);
|
||||
}
|
||||
else
|
||||
msg("Yum, that tasted good");
|
||||
}
|
||||
if ((food_left += HUNGERTIME + rnd(400) - 200) > STOMACHSIZE)
|
||||
food_left = STOMACHSIZE;
|
||||
del_pack(item);
|
||||
hungry_state = F_OKAY;
|
||||
updpack(TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* pick a random position around the give (y, x) coordinates
|
||||
*/
|
||||
coord *
|
||||
fallpos(pos, be_clear, range)
|
||||
register coord *pos;
|
||||
bool be_clear;
|
||||
int range;
|
||||
{
|
||||
register int tried, i, j;
|
||||
register char ch;
|
||||
static coord ret;
|
||||
static short masks[] = {
|
||||
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x100 };
|
||||
|
||||
/*
|
||||
* Pick a spot at random centered on the position given by 'pos' and
|
||||
* up to 'range' squares away from 'pos'
|
||||
*
|
||||
* If 'be_clear' is TRUE, the spot must be either FLOOR or PASSAGE
|
||||
* inorder to be considered valid
|
||||
*
|
||||
*
|
||||
* Generate a number from 0 to 8, representing the position to pick.
|
||||
* Note that this DOES include the positon 'pos' itself
|
||||
*
|
||||
* If this position is not valid, mark it as 'tried', and pick another.
|
||||
* Whenever a position is picked that has been tried before,
|
||||
* sequentially find the next untried position. This eliminates costly
|
||||
* random number generation
|
||||
*/
|
||||
|
||||
tried = 0;
|
||||
while( tried != 0x1ff ) {
|
||||
i = rnd(9);
|
||||
while( tried & masks[i] )
|
||||
i = (i + 1) % 9;
|
||||
|
||||
tried |= masks[i];
|
||||
|
||||
for( j = 1; j <= range; j++ ) {
|
||||
ret.x = pos->x + j*grid[i].x;
|
||||
ret.y = pos->y + j*grid[i].y;
|
||||
|
||||
if (ret.x == hero.x && ret.y == hero.y)
|
||||
continue; /* skip the hero */
|
||||
|
||||
if (ret.x < 0 || ret.x > COLS - 1 ||
|
||||
ret.y < 1 || ret.y > LINES - 3)
|
||||
continue; /* off the screen? */
|
||||
|
||||
ch = CCHAR( winat(ret.y, ret.x) );
|
||||
|
||||
/*
|
||||
* Check to make certain the spot is valid
|
||||
*/
|
||||
switch( ch ) {
|
||||
case FLOOR:
|
||||
case PASSAGE:
|
||||
return( &ret );
|
||||
case GOLD:
|
||||
case SCROLL:
|
||||
case POTION:
|
||||
case STICK:
|
||||
case RING:
|
||||
case WEAPON:
|
||||
case ARMOR:
|
||||
case MM:
|
||||
case FOOD:
|
||||
if(!be_clear && levtype != POSTLEV)
|
||||
return( &ret );
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* find_mons:
|
||||
* Find the monster from his corrdinates
|
||||
*/
|
||||
|
||||
struct linked_list *
|
||||
find_mons(y, x)
|
||||
register int y;
|
||||
register int x;
|
||||
{
|
||||
register struct linked_list *item;
|
||||
register struct thing *th;
|
||||
|
||||
for (item = mlist; item != NULL; item = next(item))
|
||||
{
|
||||
th = THINGPTR(item);
|
||||
if (th->t_pos.y == y && th->t_pos.x == x)
|
||||
return item;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* find_obj:
|
||||
* find the unclaimed object at y, x
|
||||
*/
|
||||
|
||||
struct linked_list *
|
||||
find_obj(y, x)
|
||||
register int y;
|
||||
register int x;
|
||||
{
|
||||
register struct linked_list *obj;
|
||||
register struct object *op;
|
||||
|
||||
for (obj = lvl_obj; obj != NULL; obj = next(obj))
|
||||
{
|
||||
op = OBJPTR(obj);
|
||||
if (op->o_pos.y == y && op->o_pos.x == x)
|
||||
return obj;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* set up the direction co_ordinate for use in varios "prefix" commands
|
||||
*/
|
||||
get_dir()
|
||||
{
|
||||
register char *prompt;
|
||||
register bool gotit;
|
||||
|
||||
prompt = terse ? "Direction?" : "Which direction? ";
|
||||
msg(prompt);
|
||||
do
|
||||
{
|
||||
gotit = TRUE;
|
||||
switch (readchar())
|
||||
{
|
||||
case 'h': case'H': delta.y = 0; delta.x = -1;
|
||||
when 'j': case'J': delta.y = 1; delta.x = 0;
|
||||
when 'k': case'K': delta.y = -1; delta.x = 0;
|
||||
when 'l': case'L': delta.y = 0; delta.x = 1;
|
||||
when 'y': case'Y': delta.y = -1; delta.x = -1;
|
||||
when 'u': case'U': delta.y = -1; delta.x = 1;
|
||||
when 'b': case'B': delta.y = 1; delta.x = -1;
|
||||
when 'n': case'N': delta.y = 1; delta.x = 1;
|
||||
when ESCAPE: return FALSE;
|
||||
otherwise:
|
||||
mpos = 0;
|
||||
msg(prompt);
|
||||
gotit = FALSE;
|
||||
}
|
||||
} until (gotit);
|
||||
if ((on(player, ISHUH) || on(player, ISDANCE)) && rnd(100) > 20) {
|
||||
do
|
||||
{
|
||||
delta = grid[rnd(9)];
|
||||
} while (delta.y == 0 && delta.x == 0);
|
||||
}
|
||||
mpos = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* see if the object is one of the currently used items
|
||||
*/
|
||||
is_current(obj)
|
||||
register struct object *obj;
|
||||
{
|
||||
if (obj == NULL)
|
||||
return FALSE;
|
||||
if (obj == cur_armor || obj == cur_weapon ||
|
||||
obj == cur_ring[LEFT_1] || obj == cur_ring[LEFT_2] ||
|
||||
obj == cur_ring[LEFT_3] || obj == cur_ring[LEFT_4] ||
|
||||
obj == cur_ring[RIGHT_1] || obj == cur_ring[RIGHT_2] ||
|
||||
obj == cur_ring[RIGHT_3] || obj == cur_ring[RIGHT_4] ||
|
||||
obj == cur_misc[WEAR_BOOTS] || obj == cur_misc[WEAR_JEWEL] ||
|
||||
obj == cur_misc[WEAR_BRACERS] || obj == cur_misc[WEAR_CLOAK] ||
|
||||
obj == cur_misc[WEAR_GAUNTLET] || obj == cur_misc[WEAR_NECKLACE]) {
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Is it a "current" relic? */
|
||||
if (obj->o_type == RELIC) {
|
||||
switch (obj->o_which) {
|
||||
case MUSTY_DAGGER:
|
||||
case EMORI_CLOAK:
|
||||
case HEIL_ANKH:
|
||||
case YENDOR_AMULET:
|
||||
case HRUGGEK_MSTAR:
|
||||
case YEENOGHU_FLAIL:
|
||||
if (cur_relic[obj->o_which]) return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Look:
|
||||
* A quick glance all around the player
|
||||
*/
|
||||
|
||||
look(wakeup, runend)
|
||||
bool wakeup; /* Should we wake up monsters */
|
||||
bool runend; /* At end of a run -- for mazes */
|
||||
{
|
||||
register int x, y, radius;
|
||||
register char ch, och;
|
||||
register int oldx, oldy;
|
||||
register bool inpass, horiz, vert, do_light = FALSE, do_blank = FALSE;
|
||||
register int passcount = 0, curfloorcount = 0, nextfloorcount = 0;
|
||||
register struct room *rp;
|
||||
register int ey, ex;
|
||||
|
||||
inpass = ((rp = roomin(&hero)) == NULL); /* Are we in a passage? */
|
||||
|
||||
/* Are we moving vertically or horizontally? */
|
||||
if (runch == 'h' || runch == 'l') horiz = TRUE;
|
||||
else horiz = FALSE;
|
||||
if (runch == 'j' || runch == 'k') vert = TRUE;
|
||||
else vert = FALSE;
|
||||
|
||||
/* How far around himself can the player see? */
|
||||
if (levtype == OUTSIDE) {
|
||||
if (daytime) radius = 6;
|
||||
else if (lit_room(rp)) radius = 3;
|
||||
else radius = 1;
|
||||
}
|
||||
else radius = 1;
|
||||
|
||||
getyx(cw, oldy, oldx); /* Save current position */
|
||||
|
||||
/* Blank out the floor around our last position and check for
|
||||
* moving out of a corridor in a maze.
|
||||
*/
|
||||
if (levtype == OUTSIDE) do_blank = !daytime;
|
||||
else if (oldrp != NULL && !lit_room(oldrp) && off(player, ISBLIND))
|
||||
do_blank = TRUE;
|
||||
|
||||
/* Now move around the old position and blank things out */
|
||||
ey = player.t_oldpos.y + radius;
|
||||
ex = player.t_oldpos.x + radius;
|
||||
for (x = player.t_oldpos.x - radius; x <= ex; x++)
|
||||
if (x >= 0 && x < COLS)
|
||||
for (y = player.t_oldpos.y - radius; y <= ey; y++) {
|
||||
char savech; /* Saves character in monster window */
|
||||
|
||||
if (y < 1 || y > LINES - 3) continue;
|
||||
|
||||
/* See what's there -- ignore monsters, just see what they're on */
|
||||
savech = CCHAR( mvwinch(mw, y, x) );
|
||||
waddch(mw, ' ');
|
||||
ch = show(y, x);
|
||||
mvwaddch(mw, y, x, savech); /* Restore monster */
|
||||
|
||||
if (do_blank && (y != hero.y || x != hero.x))
|
||||
switch (ch) {
|
||||
case DOOR:
|
||||
case SECRETDOOR:
|
||||
case PASSAGE:
|
||||
case STAIRS:
|
||||
case TRAPDOOR:
|
||||
case TELTRAP:
|
||||
case BEARTRAP:
|
||||
case SLEEPTRAP:
|
||||
case ARROWTRAP:
|
||||
case DARTTRAP:
|
||||
case MAZETRAP:
|
||||
case POOL:
|
||||
case POST:
|
||||
case '|':
|
||||
case '-':
|
||||
case WALL:
|
||||
/* If there was a monster showing, make it disappear */
|
||||
if (isalpha(savech)) mvwaddch(cw, y, x, ch);
|
||||
break;
|
||||
when FLOOR:
|
||||
case FOREST:
|
||||
default:
|
||||
mvwaddch(cw, y, x, ' ');
|
||||
}
|
||||
|
||||
/* Moving out of a corridor? */
|
||||
if (levtype == MAZELEV && !ce(hero, player.t_oldpos) &&
|
||||
!running && !isrock(ch) && /* Not running and not a wall */
|
||||
((vert && x != player.t_oldpos.x && y==player.t_oldpos.y) ||
|
||||
(horiz && y != player.t_oldpos.y && x==player.t_oldpos.x)))
|
||||
do_light = off(player, ISBLIND);
|
||||
}
|
||||
|
||||
/* Take care of unlighting a corridor */
|
||||
if (do_light && lit_room(rp)) light(&player.t_oldpos);
|
||||
|
||||
/* Are we coming or going between a wall and a corridor in a maze? */
|
||||
och = show(player.t_oldpos.y, player.t_oldpos.x);
|
||||
ch = show(hero.y, hero.x);
|
||||
if (levtype == MAZELEV &&
|
||||
((isrock(och) && !isrock(ch)) || (isrock(ch) && !isrock(och)))) {
|
||||
do_light = off(player, ISBLIND); /* Light it up if not blind */
|
||||
|
||||
/* Unlight what we just saw */
|
||||
if (do_light && lit_room(&rooms[0])) light(&player.t_oldpos);
|
||||
}
|
||||
|
||||
/* Look around the player */
|
||||
ey = hero.y + radius;
|
||||
ex = hero.x + radius;
|
||||
for (x = hero.x - radius; x <= ex; x++)
|
||||
if (x >= 0 && x < COLS) for (y = hero.y - radius; y <= ey; y++) {
|
||||
if (y < 1 || y >= LINES - 2)
|
||||
continue;
|
||||
if (isalpha(mvwinch(mw, y, x)))
|
||||
{
|
||||
register struct linked_list *it;
|
||||
register struct thing *tp;
|
||||
|
||||
if (wakeup)
|
||||
it = wake_monster(y, x);
|
||||
else
|
||||
it = find_mons(y, x);
|
||||
tp = THINGPTR(it);
|
||||
tp->t_oldch = CCHAR( mvinch(y, x) );
|
||||
if (isatrap(tp->t_oldch)) {
|
||||
register struct trap *trp = trap_at(y, x);
|
||||
|
||||
tp->t_oldch = (trp->tr_flags & ISFOUND) ? tp->t_oldch
|
||||
: trp->tr_show;
|
||||
}
|
||||
if (tp->t_oldch == FLOOR && !lit_room(rp) &&
|
||||
off(player, ISBLIND))
|
||||
tp->t_oldch = ' ';
|
||||
}
|
||||
|
||||
/*
|
||||
* Secret doors show as walls
|
||||
*/
|
||||
if ((ch = show(y, x)) == SECRETDOOR)
|
||||
ch = secretdoor(y, x);
|
||||
/*
|
||||
* Don't show room walls if he is in a passage and
|
||||
* check for maze turns
|
||||
*/
|
||||
if (off(player, ISBLIND))
|
||||
{
|
||||
if (y == hero.y && x == hero.x
|
||||
|| (inpass && (ch == '-' || ch == '|')))
|
||||
continue;
|
||||
|
||||
/* Did we come to a crossroads in a maze? */
|
||||
if (levtype == MAZELEV &&
|
||||
(runend || !ce(hero, player.t_oldpos)) &&
|
||||
!isrock(ch) && /* Not a wall */
|
||||
((vert && x != hero.x && y == hero.y) ||
|
||||
(horiz && y != hero.y && x == hero.x)))
|
||||
/* Just came to a turn */
|
||||
do_light = off(player, ISBLIND);
|
||||
}
|
||||
else if (y != hero.y || x != hero.x)
|
||||
continue;
|
||||
|
||||
wmove(cw, y, x);
|
||||
waddch(cw, ch);
|
||||
if (door_stop && !firstmove && running)
|
||||
{
|
||||
switch (runch)
|
||||
{
|
||||
case 'h':
|
||||
if (x == hero.x + 1)
|
||||
continue;
|
||||
when 'j':
|
||||
if (y == hero.y - 1)
|
||||
continue;
|
||||
when 'k':
|
||||
if (y == hero.y + 1)
|
||||
continue;
|
||||
when 'l':
|
||||
if (x == hero.x - 1)
|
||||
continue;
|
||||
when 'y':
|
||||
if ((x + y) - (hero.x + hero.y) >= 1)
|
||||
continue;
|
||||
when 'u':
|
||||
if ((y - x) - (hero.y - hero.x) >= 1)
|
||||
continue;
|
||||
when 'n':
|
||||
if ((x + y) - (hero.x + hero.y) <= -1)
|
||||
continue;
|
||||
when 'b':
|
||||
if ((y - x) - (hero.y - hero.x) <= -1)
|
||||
continue;
|
||||
}
|
||||
switch (ch)
|
||||
{
|
||||
case DOOR:
|
||||
if (x == hero.x || y == hero.y)
|
||||
running = FALSE;
|
||||
break;
|
||||
case PASSAGE:
|
||||
if (x == hero.x || y == hero.y)
|
||||
passcount++;
|
||||
break;
|
||||
case FLOOR:
|
||||
/* Stop by new passages in a maze (floor next to us) */
|
||||
if ((levtype == MAZELEV) &&
|
||||
!(hero.y == y && hero.x == x)) {
|
||||
if (vert) { /* Moving vertically */
|
||||
/* We have a passage on our row */
|
||||
if (y == hero.y) curfloorcount++;
|
||||
|
||||
/* Some passage on the next row */
|
||||
else if (y != player.t_oldpos.y)
|
||||
nextfloorcount++;
|
||||
}
|
||||
else { /* Moving horizontally */
|
||||
/* We have a passage on our column */
|
||||
if (x == hero.x) curfloorcount++;
|
||||
|
||||
/* Some passage in the next column */
|
||||
else if (x != player.t_oldpos.x)
|
||||
nextfloorcount++;
|
||||
}
|
||||
}
|
||||
case '|':
|
||||
case '-':
|
||||
case ' ':
|
||||
break;
|
||||
default:
|
||||
running = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Have we passed a side passage, with multiple choices? */
|
||||
if (curfloorcount > 0 && nextfloorcount > 0) running = FALSE;
|
||||
|
||||
else if (door_stop && !firstmove && passcount > 1)
|
||||
running = FALSE;
|
||||
|
||||
/* Do we have to light up the area (just stepped into a new corridor)? */
|
||||
if (do_light && !running && lit_room(rp)) light(&hero);
|
||||
|
||||
mvwaddch(cw, hero.y, hero.x, PLAYER);
|
||||
wmove(cw, oldy, oldx);
|
||||
if (!ce(player.t_oldpos, hero)) {
|
||||
player.t_oldpos = hero; /* Don't change if we didn't move */
|
||||
oldrp = rp;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* raise_level:
|
||||
* The guy just magically went up a level.
|
||||
*/
|
||||
|
||||
raise_level(get_spells)
|
||||
bool get_spells;
|
||||
{
|
||||
unsigned long test; /* Next level -- be sure it is not an overflow */
|
||||
|
||||
test = check_level(FALSE); /* Get next boundary */
|
||||
|
||||
/* Be sure it is higher than what we have no -- else overflow */
|
||||
if (test > pstats.s_exp) pstats.s_exp = test;
|
||||
check_level(get_spells);
|
||||
}
|
||||
|
||||
/*
|
||||
* saving throw matrix for character saving throws
|
||||
* this table is indexed by char type and saving throw type
|
||||
*/
|
||||
static int st_matrix[5][5] = {
|
||||
/* Poison, Petrify, wand, Breath, Magic */
|
||||
{ 14, 15, 16, 16, 17 },
|
||||
{ 14, 13, 11, 15, 12 },
|
||||
{ 10, 13, 14, 16, 15 },
|
||||
{ 13, 12, 14, 16, 15 },
|
||||
{ 14, 15, 16, 16, 17 }
|
||||
};
|
||||
|
||||
/*
|
||||
* save:
|
||||
* See if a creature saves against something
|
||||
*/
|
||||
save(which, who, adj)
|
||||
int which; /* which type of save */
|
||||
struct thing *who; /* who is saving */
|
||||
int adj; /* saving throw adjustment */
|
||||
{
|
||||
register int need, level;
|
||||
|
||||
level = who->t_stats.s_lvl;
|
||||
need = st_matrix[who->t_ctype][which];
|
||||
switch (who->t_ctype) {
|
||||
case C_FIGHTER:
|
||||
need -= (level-1) / 2;
|
||||
when C_MAGICIAN:
|
||||
need -= 2 * (level-1) / 5;
|
||||
when C_CLERIC:
|
||||
need -= (level-1) / 3;
|
||||
when C_THIEF:
|
||||
need -= 2 * (level-1) / 4;
|
||||
when C_MONSTER:
|
||||
need -= level / 2;
|
||||
}
|
||||
/*
|
||||
* add in pluses against poison for execeptional constitution
|
||||
*/
|
||||
if (which == VS_POISON && who->t_stats.s_const > 18)
|
||||
need -= (who->t_stats.s_const - 17) / 2;
|
||||
/*
|
||||
* does the player have a ring of protection on?
|
||||
*/
|
||||
if (who == &player)
|
||||
need -= (min(ring_value(R_PROTECT),3)); /* no more than +3 bonus */
|
||||
/*
|
||||
* does the player have a cloak of protection on?
|
||||
*/
|
||||
if (who == &player && cur_misc[WEAR_CLOAK])
|
||||
need -= (min(cur_misc[WEAR_CLOAK]->o_ac,3)); /* no more than +3 bonus */
|
||||
need -= adj;
|
||||
debug("need a %d to save", need);
|
||||
return (roll(1, 20) >= need);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* secret_door:
|
||||
* Figure out what a secret door looks like.
|
||||
*/
|
||||
|
||||
secretdoor(y, x)
|
||||
register int y, x;
|
||||
{
|
||||
register int i;
|
||||
register struct room *rp;
|
||||
register coord *cpp;
|
||||
static coord cp;
|
||||
|
||||
cp.y = y;
|
||||
cp.x = x;
|
||||
cpp = &cp;
|
||||
for (rp = rooms, i = 0; i < MAXROOMS; rp++, i++)
|
||||
if (inroom(rp, cpp))
|
||||
if (y == rp->r_pos.y || y == rp->r_pos.y + rp->r_max.y - 1)
|
||||
return('-');
|
||||
else
|
||||
return('|');
|
||||
|
||||
return('p');
|
||||
}
|
||||
|
||||
/*
|
||||
* copy string using unctrl for things
|
||||
*/
|
||||
strucpy(s1, s2, len)
|
||||
register char *s1, *s2;
|
||||
register int len;
|
||||
{
|
||||
register char *sp;
|
||||
|
||||
while (len--)
|
||||
{
|
||||
strcpy(s1, (sp = unctrl(*s2)));
|
||||
s1 += strlen(sp);
|
||||
s2++;
|
||||
}
|
||||
*s1 = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* tr_name:
|
||||
* print the name of a trap
|
||||
*/
|
||||
|
||||
char *
|
||||
tr_name(ch)
|
||||
char ch;
|
||||
{
|
||||
register char *s = NULL;
|
||||
|
||||
switch (ch)
|
||||
{
|
||||
case TRAPDOOR:
|
||||
s = terse ? "A trapdoor." : "You found a trapdoor.";
|
||||
when BEARTRAP:
|
||||
s = terse ? "A beartrap." : "You found a beartrap.";
|
||||
when SLEEPTRAP:
|
||||
s = terse ? "A sleeping gas trap.":"You found a sleeping gas trap.";
|
||||
when ARROWTRAP:
|
||||
s = terse ? "An arrow trap." : "You found an arrow trap.";
|
||||
when TELTRAP:
|
||||
s = terse ? "A teleport trap." : "You found a teleport trap.";
|
||||
when DARTTRAP:
|
||||
s = terse ? "A dart trap." : "You found a poison dart trap.";
|
||||
when POOL:
|
||||
s = terse ? "A shimmering pool." : "You found a shimmering pool";
|
||||
when MAZETRAP:
|
||||
s = terse ? "A maze entrance." : "You found a maze entrance";
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* for printfs: if string starts with a vowel, return "n" for an "an"
|
||||
*/
|
||||
char *
|
||||
vowelstr(str)
|
||||
register char *str;
|
||||
{
|
||||
switch (*str)
|
||||
{
|
||||
case 'a':
|
||||
case 'e':
|
||||
case 'i':
|
||||
case 'o':
|
||||
case 'u':
|
||||
return "n";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* waste_time:
|
||||
* Do nothing but let other things happen
|
||||
*/
|
||||
|
||||
waste_time()
|
||||
{
|
||||
if (inwhgt) /* if from wghtchk then done */
|
||||
return;
|
||||
do_daemons(BEFORE);
|
||||
do_fuses(BEFORE);
|
||||
do_daemons(AFTER);
|
||||
do_fuses(AFTER);
|
||||
}
|
||||
20
arogue5/vers.c
Normal file
20
arogue5/vers.c
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* version number. Whenever a new version number is desired, use
|
||||
* sccs to get vers.c. Environ and encstr are declared here to
|
||||
* force them to be loaded before the version number, and therefore
|
||||
* not to be written in saved games.
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
char encstr[] = "\354\251\243\332A\201|\301\321p\210\251\327\"\257\365t\341%3\271^`~\203z{\341};\f\341\231\222e\234\351]\321\234";
|
||||
char version[] = "@(#)vers.c 5.8 (Bell Labs) 1/03/85";
|
||||
char *release = "5.8.2";
|
||||
310
arogue5/weapons.c
Normal file
310
arogue5/weapons.c
Normal file
|
|
@ -0,0 +1,310 @@
|
|||
/*
|
||||
* Functions for dealing with problems brought about by weapons
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "curses.h"
|
||||
#include <ctype.h>
|
||||
#include "rogue.h"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* do the actual motion on the screen done by an object traveling
|
||||
* across the room
|
||||
*/
|
||||
do_motion(obj, ydelta, xdelta, tp)
|
||||
register struct object *obj;
|
||||
register int ydelta, xdelta;
|
||||
register struct thing *tp;
|
||||
{
|
||||
|
||||
/*
|
||||
* Come fly with us ...
|
||||
*/
|
||||
obj->o_pos = tp->t_pos;
|
||||
for (; ;) {
|
||||
register int ch;
|
||||
/*
|
||||
* Erase the old one
|
||||
*/
|
||||
if (!ce(obj->o_pos, tp->t_pos) &&
|
||||
cansee(unc(obj->o_pos)) &&
|
||||
mvwinch(cw, obj->o_pos.y, obj->o_pos.x) != ' ') {
|
||||
mvwaddch(cw, obj->o_pos.y, obj->o_pos.x, show(obj->o_pos.y, obj->o_pos.x));
|
||||
}
|
||||
/*
|
||||
* Get the new position
|
||||
*/
|
||||
obj->o_pos.y += ydelta;
|
||||
obj->o_pos.x += xdelta;
|
||||
if (shoot_ok(ch = winat(obj->o_pos.y, obj->o_pos.x)) && ch != DOOR && !ce(obj->o_pos, hero)) {
|
||||
/*
|
||||
* It hasn't hit anything yet, so display it
|
||||
* If it alright.
|
||||
*/
|
||||
if (cansee(unc(obj->o_pos)) &&
|
||||
mvwinch(cw, obj->o_pos.y, obj->o_pos.x) != ' ') {
|
||||
mvwaddch(cw, obj->o_pos.y, obj->o_pos.x, obj->o_type);
|
||||
draw(cw);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* fall:
|
||||
* Drop an item someplace around here.
|
||||
*/
|
||||
|
||||
fall(item, pr)
|
||||
register struct linked_list *item;
|
||||
bool pr;
|
||||
{
|
||||
register struct object *obj;
|
||||
register struct room *rp;
|
||||
register int i;
|
||||
coord *fpos = NULL;
|
||||
|
||||
obj = OBJPTR(item);
|
||||
/*
|
||||
* try to drop the item, look up to 3 squares away for now
|
||||
*/
|
||||
for (i=1; i<4; i++) {
|
||||
if ((fpos = fallpos(&obj->o_pos, FALSE, i)) != NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
if (fpos != NULL) {
|
||||
mvaddch(fpos->y, fpos->x, obj->o_type);
|
||||
obj->o_pos = *fpos;
|
||||
if ((rp = roomin(&hero)) != NULL &&
|
||||
lit_room(rp)) {
|
||||
light(&hero);
|
||||
mvwaddch(cw, hero.y, hero.x, PLAYER);
|
||||
}
|
||||
attach(lvl_obj, item);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (pr) {
|
||||
if (obj->o_type == WEAPON) /* BUGFIX: Identification trick */
|
||||
msg("The %s vanishes as it hits the ground.",
|
||||
weaps[obj->o_which].w_name);
|
||||
else
|
||||
msg("%s vanishes as it hits the ground.", inv_name(obj,TRUE));
|
||||
}
|
||||
o_discard(item);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Does the missile hit the monster
|
||||
*/
|
||||
|
||||
hit_monster(y, x, obj, tp)
|
||||
register int y, x;
|
||||
struct object *obj;
|
||||
register struct thing *tp;
|
||||
{
|
||||
static coord mp;
|
||||
|
||||
mp.y = y;
|
||||
mp.x = x;
|
||||
if (tp == &player) {
|
||||
/* Make sure there is a monster where it landed */
|
||||
if (!isalpha(mvwinch(mw, y, x))) {
|
||||
return(FALSE);
|
||||
}
|
||||
return(fight(&mp, obj, TRUE));
|
||||
} else {
|
||||
if (!ce(mp, hero)) {
|
||||
return(FALSE);
|
||||
}
|
||||
return(attack(tp, obj, TRUE));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* init_weapon:
|
||||
* Set up the initial goodies for a weapon
|
||||
*/
|
||||
|
||||
init_weapon(weap, type)
|
||||
register struct object *weap;
|
||||
char type;
|
||||
{
|
||||
register struct init_weps *iwp;
|
||||
|
||||
iwp = &weaps[type];
|
||||
strcpy(weap->o_damage,iwp->w_dam);
|
||||
strcpy(weap->o_hurldmg,iwp->w_hrl);
|
||||
weap->o_launch = iwp->w_launch;
|
||||
weap->o_flags = iwp->w_flags;
|
||||
weap->o_weight = iwp->w_wght;
|
||||
if (weap->o_flags & ISMANY) {
|
||||
weap->o_count = rnd(8) + 8;
|
||||
weap->o_group = newgrp();
|
||||
} else {
|
||||
weap->o_count = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* missile:
|
||||
* Fire a missile in a given direction
|
||||
*/
|
||||
|
||||
missile(ydelta, xdelta, item, tp)
|
||||
int ydelta, xdelta;
|
||||
register struct linked_list *item;
|
||||
register struct thing *tp;
|
||||
{
|
||||
register struct object *obj;
|
||||
register struct linked_list *nitem;
|
||||
char ch;
|
||||
|
||||
/*
|
||||
* Get which thing we are hurling
|
||||
*/
|
||||
if (item == NULL) {
|
||||
return;
|
||||
}
|
||||
obj = OBJPTR(item);
|
||||
|
||||
#if 0 /* Do we really want to make this check */
|
||||
if (is_current(obj)) { /* Are we holding it? */
|
||||
msg(terse ? "Holding it." : "You are already holding it.");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!dropcheck(obj)) return; /* Can we get rid of it? */
|
||||
|
||||
if(!(obj->o_flags & ISMISL)) {
|
||||
for(;;) {
|
||||
msg(terse ? "Really throw? (y or n): "
|
||||
: "Do you really want to throw %s? (y or n): ",
|
||||
inv_name(obj, TRUE));
|
||||
mpos = 0;
|
||||
ch = readchar();
|
||||
if (ch == 'n' || ch == ESCAPE) {
|
||||
after = FALSE;
|
||||
return;
|
||||
}
|
||||
if (ch == 'y')
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Get rid of the thing. If it is a non-multiple item object, or
|
||||
* if it is the last thing, just drop it. Otherwise, create a new
|
||||
* item with a count of one.
|
||||
*/
|
||||
if (obj->o_count < 2) {
|
||||
detach(tp->t_pack, item);
|
||||
if (tp->t_pack == pack) {
|
||||
inpack--;
|
||||
}
|
||||
}
|
||||
else {
|
||||
obj->o_count--;
|
||||
nitem = (struct linked_list *) new_item(sizeof *obj);
|
||||
obj = OBJPTR(nitem);
|
||||
*obj = *(OBJPTR(item));
|
||||
obj->o_count = 1;
|
||||
item = nitem;
|
||||
}
|
||||
updpack (FALSE);
|
||||
do_motion(obj, ydelta, xdelta, tp);
|
||||
/*
|
||||
* AHA! Here it has hit something. If it is a wall or a door,
|
||||
* or if it misses (combat) the monster, put it on the floor
|
||||
*/
|
||||
if (!hit_monster(unc(obj->o_pos), obj, tp)) {
|
||||
fall(item, TRUE);
|
||||
}
|
||||
mvwaddch(cw, hero.y, hero.x, PLAYER);
|
||||
}
|
||||
|
||||
/*
|
||||
* num:
|
||||
* Figure out the plus number for armor/weapons
|
||||
*/
|
||||
|
||||
char *
|
||||
num(n1, n2)
|
||||
register int n1, n2;
|
||||
{
|
||||
static char numbuf[LINELEN];
|
||||
|
||||
if (n1 == 0 && n2 == 0) {
|
||||
return "+0";
|
||||
}
|
||||
if (n2 == 0) {
|
||||
sprintf(numbuf, "%s%d", n1 < 0 ? "" : "+", n1);
|
||||
} else {
|
||||
sprintf(numbuf, "%s%d, %s%d", n1 < 0 ? "" : "+", n1, n2 < 0 ? "" : "+", n2);
|
||||
}
|
||||
return(numbuf);
|
||||
}
|
||||
|
||||
/*
|
||||
* wield:
|
||||
* Pull out a certain weapon
|
||||
*/
|
||||
|
||||
wield()
|
||||
{
|
||||
register struct linked_list *item;
|
||||
register struct object *obj, *oweapon;
|
||||
|
||||
if ((oweapon = cur_weapon) != NULL) {
|
||||
if (!dropcheck(cur_weapon)) {
|
||||
cur_weapon = oweapon;
|
||||
return;
|
||||
}
|
||||
if (terse)
|
||||
addmsg("Was ");
|
||||
else
|
||||
addmsg("You were ");
|
||||
msg("wielding %s", inv_name(oweapon, TRUE));
|
||||
}
|
||||
if ((item = get_item(pack, "wield", WIELDABLE)) == NULL) {
|
||||
after = FALSE;
|
||||
return;
|
||||
}
|
||||
obj = OBJPTR(item);
|
||||
if (is_current(obj)) {
|
||||
msg("Item in use.");
|
||||
after = FALSE;
|
||||
return;
|
||||
}
|
||||
if (player.t_ctype != C_FIGHTER &&
|
||||
obj->o_type == WEAPON &&
|
||||
(obj->o_which == TWOSWORD || obj->o_which == BASWORD)) {
|
||||
msg("Only fighters can wield a %s", weaps[obj->o_which].w_name);
|
||||
return;
|
||||
}
|
||||
if (terse) {
|
||||
addmsg("W");
|
||||
} else {
|
||||
addmsg("You are now w");
|
||||
}
|
||||
msg("ielding %s", inv_name(obj, TRUE));
|
||||
cur_weapon = obj;
|
||||
}
|
||||
|
||||
259
arogue5/wear.c
Normal file
259
arogue5/wear.c
Normal file
|
|
@ -0,0 +1,259 @@
|
|||
/*
|
||||
* This file contains misc functions for dealing with armor
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "curses.h"
|
||||
#include "rogue.h"
|
||||
|
||||
|
||||
/*
|
||||
* take_off:
|
||||
* Get the armor off of the players back
|
||||
*/
|
||||
|
||||
take_off()
|
||||
{
|
||||
register struct object *obj;
|
||||
register struct linked_list *item;
|
||||
|
||||
/* What does player want to take off? */
|
||||
if ((item = get_item(pack, "take off", REMOVABLE)) == NULL)
|
||||
return;
|
||||
|
||||
obj = OBJPTR(item);
|
||||
if (!is_current(obj)) {
|
||||
sprintf(outstring,"Not wearing %c) %s", pack_char(pack, obj),inv_name(obj, TRUE));
|
||||
msg(outstring);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Can the player remove the item? */
|
||||
if (!dropcheck(obj)) return;
|
||||
updpack(TRUE);
|
||||
|
||||
sprintf(outstring,"Was wearing %c) %s", pack_char(pack, obj),inv_name(obj,TRUE));
|
||||
msg(outstring);
|
||||
}
|
||||
|
||||
/*
|
||||
* wear:
|
||||
* The player wants to wear something, so let him/her put it on.
|
||||
*/
|
||||
|
||||
wear()
|
||||
{
|
||||
register struct linked_list *item;
|
||||
register struct object *obj;
|
||||
register int i;
|
||||
char buf[LINELEN];
|
||||
|
||||
|
||||
/* What does player want to wear? */
|
||||
if ((item = get_item(pack, "wear", WEARABLE)) == NULL)
|
||||
return;
|
||||
|
||||
obj = OBJPTR(item);
|
||||
|
||||
switch (obj->o_type) {
|
||||
case ARMOR:
|
||||
if (cur_armor != NULL) {
|
||||
addmsg("You are already wearing armor");
|
||||
if (!terse) addmsg(". You'll have to take it off first.");
|
||||
endmsg();
|
||||
after = FALSE;
|
||||
return;
|
||||
}
|
||||
if (cur_misc[WEAR_BRACERS] != NULL) {
|
||||
msg("You can't wear armor with bracers of defense.");
|
||||
return;
|
||||
}
|
||||
if (cur_misc[WEAR_CLOAK] != NULL || cur_relic[EMORI_CLOAK]) {
|
||||
msg("You can't wear armor with a cloak.");
|
||||
return;
|
||||
}
|
||||
if (player.t_ctype == C_THIEF &&
|
||||
(obj->o_which != LEATHER && obj->o_which != STUDDED_LEATHER)) {
|
||||
if (terse) msg("Thieves can't wear that type of armor");
|
||||
else
|
||||
msg("Thieves can only wear leather or studded leather armor");
|
||||
return;
|
||||
}
|
||||
waste_time();
|
||||
obj->o_flags |= ISKNOW;
|
||||
cur_armor = obj;
|
||||
addmsg(terse ? "W" : "You are now w");
|
||||
msg("earing %s.", armors[obj->o_which].a_name);
|
||||
|
||||
when MM:
|
||||
switch (obj->o_which) {
|
||||
/*
|
||||
* when wearing the boots of elvenkind the player will not
|
||||
* set off any traps
|
||||
*/
|
||||
case MM_ELF_BOOTS:
|
||||
if (cur_misc[WEAR_BOOTS] != NULL)
|
||||
msg("already wearing a pair of boots");
|
||||
else {
|
||||
msg("wearing %s",inv_name(obj,TRUE));
|
||||
cur_misc[WEAR_BOOTS] = obj;
|
||||
}
|
||||
/*
|
||||
* when wearing the boots of dancing the player will dance
|
||||
* uncontrollably
|
||||
*/
|
||||
when MM_DANCE:
|
||||
if (cur_misc[WEAR_BOOTS] != NULL)
|
||||
msg("already wearing a pair of boots");
|
||||
else {
|
||||
msg("wearing %s",inv_name(obj,TRUE));
|
||||
cur_misc[WEAR_BOOTS] = obj;
|
||||
msg("You begin to dance uncontrollably!");
|
||||
turn_on(player, ISDANCE);
|
||||
}
|
||||
/*
|
||||
* bracers give the hero protection in he same way armor does.
|
||||
* they cannot be used with armor but can be used with cloaks
|
||||
*/
|
||||
when MM_BRACERS:
|
||||
if (cur_misc[WEAR_BRACERS] != NULL)
|
||||
msg("already wearing bracers");
|
||||
else {
|
||||
if (cur_armor != NULL) {
|
||||
msg("You can't wear bracers of defense with armor.");
|
||||
}
|
||||
else {
|
||||
msg("wearing %s",inv_name(obj,TRUE));
|
||||
cur_misc[WEAR_BRACERS] = obj;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The robe (cloak) of powerlessness disallows any spell casting
|
||||
*/
|
||||
when MM_R_POWERLESS:
|
||||
/*
|
||||
* the cloak of displacement gives the hero an extra +2 on AC
|
||||
* and saving throws. Cloaks cannot be used with armor.
|
||||
*/
|
||||
case MM_DISP:
|
||||
/*
|
||||
* the cloak of protection gives the hero +n on AC and saving
|
||||
* throws with a max of +3 on saves
|
||||
*/
|
||||
case MM_PROTECT:
|
||||
if (cur_misc[WEAR_CLOAK] != NULL || cur_relic[EMORI_CLOAK])
|
||||
msg("%slready wearing a cloak.", terse ? "A"
|
||||
: "You are a");
|
||||
else {
|
||||
if (cur_armor != NULL) {
|
||||
msg("You can't wear a cloak with armor.");
|
||||
}
|
||||
else {
|
||||
msg("wearing %s",inv_name(obj,TRUE));
|
||||
cur_misc[WEAR_CLOAK] = obj;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* the gauntlets of dexterity give the hero a dexterity of 18
|
||||
* the gauntlets of ogre power give the hero a strength of 18
|
||||
* the gauntlets of fumbling cause the hero to drop his weapon
|
||||
*/
|
||||
when MM_G_DEXTERITY:
|
||||
case MM_G_OGRE:
|
||||
case MM_FUMBLE:
|
||||
if (cur_misc[WEAR_GAUNTLET] != NULL)
|
||||
msg("Already wearing a pair of gauntlets.");
|
||||
else {
|
||||
msg("wearing %s",inv_name(obj,TRUE));
|
||||
cur_misc[WEAR_GAUNTLET] = obj;
|
||||
if (obj->o_which == MM_FUMBLE)
|
||||
daemon(fumble, 0, AFTER);
|
||||
}
|
||||
/*
|
||||
* the jewel of attacks does an aggavate monster
|
||||
*/
|
||||
when MM_JEWEL:
|
||||
if (cur_misc[WEAR_JEWEL] != NULL || cur_relic[YENDOR_AMULET])
|
||||
msg("Already wearing an amulet.");
|
||||
else {
|
||||
msg("wearing %s",inv_name(obj,TRUE));
|
||||
cur_misc[WEAR_JEWEL] = obj;
|
||||
aggravate();
|
||||
}
|
||||
/*
|
||||
* the necklace of adaption makes the hero immune to
|
||||
* chlorine gas
|
||||
*/
|
||||
when MM_ADAPTION:
|
||||
if (cur_misc[WEAR_NECKLACE] != NULL)
|
||||
msg("already wearing a necklace");
|
||||
else {
|
||||
msg("wearing %s",inv_name(obj,TRUE));
|
||||
cur_misc[WEAR_NECKLACE] = obj;
|
||||
turn_on(player, NOGAS);
|
||||
}
|
||||
/*
|
||||
* the necklace of stragulation will try to strangle the
|
||||
* hero to death
|
||||
*/
|
||||
when MM_STRANGLE:
|
||||
if (cur_misc[WEAR_NECKLACE] != NULL)
|
||||
msg("already wearing a necklace");
|
||||
else {
|
||||
msg("wearing %s",inv_name(obj,TRUE));
|
||||
cur_misc[WEAR_NECKLACE] = obj;
|
||||
msg("The necklace is beginning to strangle you!");
|
||||
daemon(strangle, 0, AFTER);
|
||||
}
|
||||
otherwise:
|
||||
msg("what a strange item you have!");
|
||||
}
|
||||
status(FALSE);
|
||||
if (m_know[obj->o_which] && m_guess[obj->o_which]) {
|
||||
free(m_guess[obj->o_which]);
|
||||
m_guess[obj->o_which] = NULL;
|
||||
}
|
||||
else if (!m_know[obj->o_which] &&
|
||||
askme &&
|
||||
(obj->o_flags & ISKNOW) == 0 &&
|
||||
m_guess[obj->o_which] == NULL) {
|
||||
msg(terse ? "Call it: " : "What do you want to call it? ");
|
||||
if (get_str(buf, cw) == NORM) {
|
||||
m_guess[obj->o_which] = new((unsigned int) strlen(buf) + 1);
|
||||
strcpy(m_guess[obj->o_which], buf);
|
||||
}
|
||||
}
|
||||
|
||||
when RING:
|
||||
if (cur_misc[WEAR_GAUNTLET] != NULL) {
|
||||
msg ("You have to remove your gauntlets first!");
|
||||
return;
|
||||
}
|
||||
|
||||
/* If there is room, put on the ring */
|
||||
for (i=0; i<NUM_FINGERS; i++)
|
||||
if (cur_ring[i] == NULL) {
|
||||
cur_ring[i] = obj;
|
||||
break;
|
||||
}
|
||||
if (i == NUM_FINGERS) { /* No room */
|
||||
if (terse) msg("Wearing enough rings");
|
||||
else msg("You already have on eight rings");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Calculate the effect of the ring */
|
||||
ring_on(obj);
|
||||
}
|
||||
updpack(TRUE);
|
||||
}
|
||||
585
arogue5/wizard.c
Normal file
585
arogue5/wizard.c
Normal file
|
|
@ -0,0 +1,585 @@
|
|||
/*
|
||||
* Special wizard commands (some of which are also non-wizard commands
|
||||
* under strange circumstances)
|
||||
*
|
||||
* Advanced Rogue
|
||||
* Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "curses.h"
|
||||
#include <ctype.h>
|
||||
#include "rogue.h"
|
||||
|
||||
|
||||
/*
|
||||
* create_obj:
|
||||
* Create any object for wizard, scroll, magician, or cleric
|
||||
*/
|
||||
create_obj(prompt, which_item, which_type)
|
||||
bool prompt;
|
||||
int which_item, which_type;
|
||||
{
|
||||
reg struct linked_list *item;
|
||||
reg struct object *obj;
|
||||
reg int wh;
|
||||
reg char ch, newitem, newtype = 0, whc, msz, *pt;
|
||||
WINDOW *thiswin;
|
||||
|
||||
thiswin = cw;
|
||||
if (prompt) {
|
||||
bool nogood = TRUE;
|
||||
|
||||
thiswin = hw;
|
||||
wclear(hw);
|
||||
wprintw(hw,"Item\t\t\tKey\n\n");
|
||||
wprintw(hw,"%s\t\t\t%c\n%s\t\t\t%c\n",things[TYP_RING].mi_name,RING,
|
||||
things[TYP_STICK].mi_name,STICK);
|
||||
wprintw(hw,"%s\t\t\t%c\n%s\t\t\t%c\n",things[TYP_POTION].mi_name,POTION,
|
||||
things[TYP_SCROLL].mi_name,SCROLL);
|
||||
wprintw(hw,"%s\t\t\t%c\n%s\t\t\t%c\n",things[TYP_ARMOR].mi_name,ARMOR,
|
||||
things[TYP_WEAPON].mi_name,WEAPON);
|
||||
wprintw(hw,"%s\t%c\n",things[TYP_MM].mi_name,MM);
|
||||
wprintw(hw,"%s\t\t\t%c\n",things[TYP_FOOD].mi_name,FOOD);
|
||||
if (wizard) {
|
||||
wprintw(hw,"%s\t\t%c\n",things[TYP_RELIC].mi_name,RELIC);
|
||||
waddstr(hw,"monster\t\t\tm");
|
||||
}
|
||||
wprintw(hw,"\n\nWhat do you want to create? ");
|
||||
draw(hw);
|
||||
do {
|
||||
ch = wgetch(hw);
|
||||
if (ch == ESCAPE) {
|
||||
restscr(cw);
|
||||
return;
|
||||
}
|
||||
switch (ch) {
|
||||
case RING:
|
||||
case STICK:
|
||||
case POTION:
|
||||
case SCROLL:
|
||||
case ARMOR:
|
||||
case WEAPON:
|
||||
case FOOD:
|
||||
case MM:
|
||||
nogood = FALSE;
|
||||
break;
|
||||
case RELIC:
|
||||
case 'm':
|
||||
if (wizard)
|
||||
nogood = FALSE;
|
||||
break;
|
||||
default:
|
||||
nogood = TRUE;
|
||||
}
|
||||
} while (nogood);
|
||||
newitem = ch;
|
||||
}
|
||||
else
|
||||
newitem = which_item;
|
||||
|
||||
pt = "those";
|
||||
msz = 0;
|
||||
if(newitem == 'm') {
|
||||
makemonster(TRUE); /* make monster and be done with it */
|
||||
return;
|
||||
}
|
||||
if(newitem == GOLD)
|
||||
pt = "gold";
|
||||
/* else if(isatrap(newitem))
|
||||
pt = "traps";
|
||||
*/
|
||||
switch(newitem) {
|
||||
case POTION: whc = TYP_POTION; msz = MAXPOTIONS;
|
||||
when SCROLL: whc = TYP_SCROLL; msz = MAXSCROLLS;
|
||||
when WEAPON: whc = TYP_WEAPON; msz = MAXWEAPONS;
|
||||
when ARMOR: whc = TYP_ARMOR; msz = MAXARMORS;
|
||||
when RING: whc = TYP_RING; msz = MAXRINGS;
|
||||
when STICK: whc = TYP_STICK; msz = MAXSTICKS;
|
||||
when MM: whc = TYP_MM; msz = MAXMM;
|
||||
when RELIC: whc = TYP_RELIC; msz = MAXRELIC;
|
||||
when FOOD:
|
||||
whc = TYP_FOOD;
|
||||
msz = MAXFOODS;
|
||||
if (thiswin == hw)
|
||||
restscr(cw);
|
||||
mpos = 0;
|
||||
otherwise:
|
||||
if (thiswin == hw)
|
||||
restscr(cw);
|
||||
mpos = 0;
|
||||
msg("Even wizards can't create %s !!",pt);
|
||||
return;
|
||||
}
|
||||
if(msz == 1) { /* if only one type of item */
|
||||
ch = 'a';
|
||||
}
|
||||
else if (prompt) {
|
||||
register struct magic_item *wmi;
|
||||
char wmn;
|
||||
register int ii;
|
||||
int old_prob;
|
||||
|
||||
mpos = 0;
|
||||
wmi = NULL;
|
||||
wmn = 0;
|
||||
switch(newitem) {
|
||||
case POTION: wmi = &p_magic[0];
|
||||
when SCROLL: wmi = &s_magic[0];
|
||||
when RING: wmi = &r_magic[0];
|
||||
when STICK: wmi = &ws_magic[0];
|
||||
when MM: wmi = &m_magic[0];
|
||||
when RELIC: wmi = &rel_magic[0];
|
||||
when WEAPON: wmn = 1;
|
||||
when ARMOR: wmn = 2;
|
||||
}
|
||||
wclear(hw);
|
||||
thiswin = hw;
|
||||
if (wmi != NULL) {
|
||||
ii = old_prob = 0;
|
||||
while (ii < msz) {
|
||||
if(wmi->mi_prob == old_prob && wizard == FALSE) {
|
||||
msz--; /* can't make a unique item */
|
||||
}
|
||||
else {
|
||||
mvwaddch(hw,ii % 13,ii > 12 ? COLS/2 : 0, ii + 'a');
|
||||
waddstr(hw,") ");
|
||||
waddstr(hw,wmi->mi_name);
|
||||
ii++;
|
||||
}
|
||||
old_prob = wmi->mi_prob;
|
||||
wmi++;
|
||||
}
|
||||
}
|
||||
else if (wmn != 0) {
|
||||
for(ii = 0 ; ii < msz ; ii++) {
|
||||
mvwaddch(hw,ii % 13,ii > 12 ? COLS/2 : 0, ii + 'a');
|
||||
waddstr(hw,") ");
|
||||
if(wmn == 1)
|
||||
waddstr(hw,weaps[ii].w_name);
|
||||
else
|
||||
waddstr(hw,armors[ii].a_name);
|
||||
}
|
||||
}
|
||||
sprintf(prbuf,"Which %s? ",things[whc].mi_name);
|
||||
mvwaddstr(hw,LINES - 1, 0, prbuf);
|
||||
draw(hw);
|
||||
do {
|
||||
ch = wgetch(hw);
|
||||
if (ch == ESCAPE) {
|
||||
restscr(cw);
|
||||
msg("");
|
||||
return;
|
||||
}
|
||||
} until (isalpha(ch));
|
||||
if (thiswin == hw) /* restore screen if need be */
|
||||
restscr(cw);
|
||||
newtype = tolower(ch) - 'a';
|
||||
if(newtype < 0 || newtype >= msz) { /* if an illegal value */
|
||||
mpos = 0;
|
||||
msg("There is no such %s",things[whc].mi_name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
newtype = which_type;
|
||||
item = new_item(sizeof *obj); /* get some memory */
|
||||
obj = OBJPTR(item);
|
||||
obj->o_type = newitem; /* store the new items */
|
||||
obj->o_mark[0] = '\0';
|
||||
obj->o_which = newtype;
|
||||
obj->o_group = 0;
|
||||
obj->contents = NULL;
|
||||
obj->o_count = 1;
|
||||
obj->o_flags = 0;
|
||||
obj->o_dplus = obj->o_hplus = 0;
|
||||
obj->o_weight = 0;
|
||||
wh = obj->o_which;
|
||||
mpos = 0;
|
||||
if (!wizard) /* users get 0 to +3 */
|
||||
whc = rnd(4);
|
||||
else /* wizard gets to choose */
|
||||
whc = getbless();
|
||||
if (whc < 0)
|
||||
obj->o_flags |= ISCURSED;
|
||||
switch (obj->o_type) {
|
||||
case WEAPON:
|
||||
case ARMOR:
|
||||
if (obj->o_type == WEAPON) {
|
||||
init_weapon(obj, wh);
|
||||
obj->o_hplus += whc;
|
||||
obj->o_dplus += whc;
|
||||
}
|
||||
else { /* armor here */
|
||||
obj->o_weight = armors[wh].a_wght;
|
||||
obj->o_ac = armors[wh].a_class - whc;
|
||||
}
|
||||
when RING:
|
||||
if (whc > 1 && r_magic[wh].mi_bless != 0)
|
||||
obj->o_flags |= ISBLESSED;
|
||||
r_know[wh] = TRUE;
|
||||
switch(wh) {
|
||||
case R_ADDSTR:
|
||||
case R_ADDWISDOM:
|
||||
case R_ADDINTEL:
|
||||
case R_PROTECT:
|
||||
case R_ADDHIT:
|
||||
case R_ADDDAM:
|
||||
case R_DIGEST:
|
||||
obj->o_ac = whc + 1;
|
||||
break;
|
||||
default:
|
||||
obj->o_ac = 0;
|
||||
}
|
||||
obj->o_weight = things[TYP_RING].mi_wght;
|
||||
when MM:
|
||||
if (whc > 1 && m_magic[wh].mi_bless != 0)
|
||||
obj->o_flags |= ISBLESSED;
|
||||
m_know[wh] = TRUE;
|
||||
switch(wh) {
|
||||
case MM_JUG:
|
||||
switch(rnd(9)) {
|
||||
case 0: obj->o_ac = P_PHASE;
|
||||
when 1: obj->o_ac = P_CLEAR;
|
||||
when 2: obj->o_ac = P_SEEINVIS;
|
||||
when 3: obj->o_ac = P_HEALING;
|
||||
when 4: obj->o_ac = P_MFIND;
|
||||
when 5: obj->o_ac = P_TFIND;
|
||||
when 6: obj->o_ac = P_HASTE;
|
||||
when 7: obj->o_ac = P_RESTORE;
|
||||
when 8: obj->o_ac = P_FLY;
|
||||
}
|
||||
when MM_OPEN:
|
||||
case MM_HUNGER:
|
||||
case MM_DRUMS:
|
||||
case MM_DISAPPEAR:
|
||||
case MM_CHOKE:
|
||||
case MM_KEOGHTOM:
|
||||
if (whc < 0)
|
||||
whc = -whc; /* these cannot be negative */
|
||||
obj->o_ac = (whc + 1) * 5;
|
||||
break;
|
||||
when MM_BRACERS:
|
||||
obj->o_ac = whc * 2 + 1;
|
||||
when MM_DISP:
|
||||
obj->o_ac = 2;
|
||||
when MM_PROTECT:
|
||||
obj->o_ac = whc;
|
||||
when MM_SKILLS:
|
||||
if (wizard && whc != 0)
|
||||
obj->o_ac = rnd(4);
|
||||
else
|
||||
obj->o_ac = player.t_ctype;
|
||||
otherwise:
|
||||
obj->o_ac = 0;
|
||||
}
|
||||
obj->o_weight = things[TYP_MM].mi_wght;
|
||||
when STICK:
|
||||
if (whc > 1 && ws_magic[wh].mi_bless != 0)
|
||||
obj->o_flags |= ISBLESSED;
|
||||
ws_know[wh] = TRUE;
|
||||
fix_stick(obj);
|
||||
when SCROLL:
|
||||
if (whc > 1 && s_magic[wh].mi_bless != 0)
|
||||
obj->o_flags |= ISBLESSED;
|
||||
obj->o_weight = things[TYP_SCROLL].mi_wght;
|
||||
s_know[wh] = TRUE;
|
||||
when POTION:
|
||||
if (whc > 1 && p_magic[wh].mi_bless != 0)
|
||||
obj->o_flags |= ISBLESSED;
|
||||
obj->o_weight = things[TYP_POTION].mi_wght;
|
||||
p_know[wh] = TRUE;
|
||||
when RELIC:
|
||||
obj->o_weight = things[TYP_RELIC].mi_wght;
|
||||
}
|
||||
mpos = 0;
|
||||
obj->o_flags |= ISKNOW;
|
||||
if (add_pack(item, FALSE, NULL) == FALSE) {
|
||||
obj->o_pos = hero;
|
||||
fall(item, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* getbless:
|
||||
* Get a blessing for a wizards object
|
||||
*/
|
||||
getbless()
|
||||
{
|
||||
reg char bless;
|
||||
|
||||
msg("Blessing? (+,-,n)");
|
||||
bless = readchar();
|
||||
if (bless == '+')
|
||||
return (rnd(3) + 2);
|
||||
else if (bless == '-')
|
||||
return (-rnd(3) - 1);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* get a non-monster death type
|
||||
*/
|
||||
getdeath()
|
||||
{
|
||||
register int i;
|
||||
int which_death;
|
||||
char label[80];
|
||||
|
||||
clear();
|
||||
for (i=0; i<DEATHNUM; i++) {
|
||||
sprintf(label, "[%d] %s", i+1, deaths[i].name);
|
||||
mvaddstr(i+2, 0, label);
|
||||
}
|
||||
mvaddstr(0, 0, "Which death? ");
|
||||
refresh();
|
||||
|
||||
/* Get the death */
|
||||
for (;;) {
|
||||
get_str(label, stdscr);
|
||||
which_death = atoi(label);
|
||||
if ((which_death < 1 || which_death > DEATHNUM)) {
|
||||
mvaddstr(0, 0, "Please enter a number in the displayed range -- ");
|
||||
refresh();
|
||||
}
|
||||
else break;
|
||||
}
|
||||
return(deaths[which_death-1].reason);
|
||||
}
|
||||
|
||||
/*
|
||||
* make a monster for the wizard
|
||||
*/
|
||||
makemonster(create)
|
||||
bool create;
|
||||
{
|
||||
register int i;
|
||||
register short which_monst;
|
||||
register int num_monst = NUMMONST, pres_monst=1, num_lines=2*(LINES-3);
|
||||
char monst_name[40];
|
||||
|
||||
/* Print out the monsters */
|
||||
while (num_monst > 0) {
|
||||
register left_limit;
|
||||
|
||||
if (num_monst < num_lines) left_limit = (num_monst+1)/2;
|
||||
else left_limit = num_lines/2;
|
||||
|
||||
wclear(hw);
|
||||
touchwin(hw);
|
||||
|
||||
/* Print left column */
|
||||
wmove(hw, 2, 0);
|
||||
for (i=0; i<left_limit; i++) {
|
||||
sprintf(monst_name, "[%d] %s\n",
|
||||
pres_monst, monsters[pres_monst].m_name);
|
||||
waddstr(hw, monst_name);
|
||||
pres_monst++;
|
||||
}
|
||||
|
||||
/* Print right column */
|
||||
for (i=0; i<left_limit && pres_monst<=NUMMONST; i++) {
|
||||
sprintf(monst_name, "[%d] %s",
|
||||
pres_monst, monsters[pres_monst].m_name);
|
||||
wmove(hw, i+2, COLS/2);
|
||||
waddstr(hw, monst_name);
|
||||
pres_monst++;
|
||||
}
|
||||
|
||||
if ((num_monst -= num_lines) > 0) {
|
||||
mvwaddstr(hw, LINES-1, 0, morestr);
|
||||
draw(hw);
|
||||
wait_for(hw,' ');
|
||||
}
|
||||
|
||||
else {
|
||||
mvwaddstr(hw, 0, 0, "Which monster");
|
||||
if (!terse && create) waddstr(hw, " do you wish to create");
|
||||
waddstr(hw, "? ");
|
||||
draw(hw);
|
||||
}
|
||||
}
|
||||
|
||||
get_monst:
|
||||
get_str(monst_name, hw);
|
||||
which_monst = atoi(monst_name);
|
||||
if ((which_monst < 1 || which_monst > NUMMONST)) {
|
||||
mvwaddstr(hw, 0, 0, "Please enter a number in the displayed range -- ");
|
||||
draw(hw);
|
||||
goto get_monst;
|
||||
}
|
||||
restscr(cw);
|
||||
if (create) {
|
||||
creat_mons (&player, which_monst, TRUE);
|
||||
light(&hero);
|
||||
}
|
||||
touchwin(cw);
|
||||
return(which_monst);
|
||||
}
|
||||
|
||||
/*
|
||||
* passwd:
|
||||
* see if user knows password
|
||||
*/
|
||||
|
||||
passwd()
|
||||
{
|
||||
register char *sp, c;
|
||||
char buf[LINELEN];
|
||||
|
||||
msg("Wizard's Password:");
|
||||
mpos = 0;
|
||||
sp = buf;
|
||||
while ((c = readchar()) != '\n' && c != '\r' && c != '\033')
|
||||
if (c == md_killchar())
|
||||
sp = buf;
|
||||
else if (c == md_erasechar() && sp > buf)
|
||||
sp--;
|
||||
else
|
||||
*sp++ = c;
|
||||
if (sp == buf)
|
||||
return FALSE;
|
||||
*sp = '\0';
|
||||
return (strcmp(PASSWD, md_crypt(buf, "Si")) == 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* teleport:
|
||||
* Bamf the hero someplace else
|
||||
*/
|
||||
|
||||
teleport()
|
||||
{
|
||||
register struct room *new_rp, *old_rp = roomin(&hero);
|
||||
register int rm;
|
||||
coord c;
|
||||
|
||||
c = hero;
|
||||
mvwaddch(cw, hero.y, hero.x, mvwinch(stdscr, hero.y, hero.x));
|
||||
do
|
||||
{
|
||||
rm = rnd_room();
|
||||
rnd_pos(&rooms[rm], &hero);
|
||||
} until(winat(hero.y, hero.x) == FLOOR);
|
||||
player.t_oldpos = c; /* Save last position */
|
||||
|
||||
/* If hero gets moved, darken old room */
|
||||
new_rp = &rooms[rm];
|
||||
if (old_rp && old_rp != new_rp) {
|
||||
old_rp->r_flags |= FORCEDARK; /* Fake darkness */
|
||||
light(&c);
|
||||
old_rp->r_flags &= ~FORCEDARK; /* Restore light state */
|
||||
}
|
||||
|
||||
/* Darken where we just came from */
|
||||
else if (levtype == MAZELEV) light(&c);
|
||||
|
||||
light(&hero);
|
||||
mvwaddch(cw, hero.y, hero.x, PLAYER);
|
||||
|
||||
/* Reset current room and position */
|
||||
oldrp = new_rp; /* Used in look() */
|
||||
player.t_oldpos = hero;
|
||||
|
||||
/*
|
||||
* turn off ISHELD in case teleportation was done while fighting
|
||||
* something that holds you
|
||||
*/
|
||||
if (on(player, ISHELD)) {
|
||||
register struct linked_list *ip, *nip;
|
||||
register struct thing *mp;
|
||||
|
||||
turn_off(player, ISHELD);
|
||||
hold_count = 0;
|
||||
for (ip = mlist; ip; ip = nip) {
|
||||
mp = THINGPTR(ip);
|
||||
nip = next(ip);
|
||||
if (on(*mp, DIDHOLD)) {
|
||||
turn_off(*mp, DIDHOLD);
|
||||
turn_on(*mp, CANHOLD);
|
||||
}
|
||||
turn_off(*mp, DIDSUFFOCATE); /* Suffocation -- see below */
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure player does not suffocate */
|
||||
extinguish(suffocate);
|
||||
|
||||
count = 0;
|
||||
running = FALSE;
|
||||
md_flushinp();
|
||||
return rm;
|
||||
}
|
||||
|
||||
/*
|
||||
* whatis:
|
||||
* What a certin object is
|
||||
*/
|
||||
|
||||
whatis(what)
|
||||
struct linked_list *what;
|
||||
{
|
||||
register struct object *obj;
|
||||
register struct linked_list *item;
|
||||
|
||||
if (what == NULL) { /* do we need to ask which one? */
|
||||
if ((item = get_item(pack, "identify", IDENTABLE)) == NULL)
|
||||
return;
|
||||
}
|
||||
else
|
||||
item = what;
|
||||
obj = OBJPTR(item);
|
||||
switch (obj->o_type) {
|
||||
case SCROLL:
|
||||
s_know[obj->o_which] = TRUE;
|
||||
if (s_guess[obj->o_which]) {
|
||||
free(s_guess[obj->o_which]);
|
||||
s_guess[obj->o_which] = NULL;
|
||||
}
|
||||
when POTION:
|
||||
p_know[obj->o_which] = TRUE;
|
||||
if (p_guess[obj->o_which]) {
|
||||
free(p_guess[obj->o_which]);
|
||||
p_guess[obj->o_which] = NULL;
|
||||
}
|
||||
when STICK:
|
||||
ws_know[obj->o_which] = TRUE;
|
||||
if (ws_guess[obj->o_which]) {
|
||||
free(ws_guess[obj->o_which]);
|
||||
ws_guess[obj->o_which] = NULL;
|
||||
}
|
||||
when RING:
|
||||
r_know[obj->o_which] = TRUE;
|
||||
if (r_guess[obj->o_which]) {
|
||||
free(r_guess[obj->o_which]);
|
||||
r_guess[obj->o_which] = NULL;
|
||||
}
|
||||
when MM:
|
||||
/* If it's an identified jug, identify its potion */
|
||||
if (obj->o_which == MM_JUG && (obj->o_flags & ISKNOW)) {
|
||||
if (obj->o_ac != JUG_EMPTY)
|
||||
p_know[obj->o_ac] = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
m_know[obj->o_which] = TRUE;
|
||||
if (m_guess[obj->o_which]) {
|
||||
free(m_guess[obj->o_which]);
|
||||
m_guess[obj->o_which] = NULL;
|
||||
}
|
||||
otherwise:
|
||||
break;
|
||||
}
|
||||
obj->o_flags |= ISKNOW;
|
||||
if (what == NULL)
|
||||
msg(inv_name(obj, FALSE));
|
||||
}
|
||||
|
||||
694
arogue5/xcrypt.c
Normal file
694
arogue5/xcrypt.c
Normal file
|
|
@ -0,0 +1,694 @@
|
|||
/*
|
||||
* FreeSec: libcrypt
|
||||
*
|
||||
* Copyright (C) 1994 David Burren
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name(s) of the author(s) nor the names of other contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* This is an original implementation of the DES and the crypt(3) interfaces
|
||||
* by David Burren <davidb@werj.com.au>.
|
||||
*
|
||||
* An excellent reference on the underlying algorithm (and related
|
||||
* algorithms) is:
|
||||
*
|
||||
* B. Schneier, Applied Cryptography: protocols, algorithms,
|
||||
* and source code in C, John Wiley & Sons, 1994.
|
||||
*
|
||||
* Note that in that book's description of DES the lookups for the initial,
|
||||
* pbox, and final permutations are inverted (this has been brought to the
|
||||
* attention of the author). A list of errata for this book has been
|
||||
* posted to the sci.crypt newsgroup by the author and is available for FTP.
|
||||
*
|
||||
* NOTE:
|
||||
* This file has a static version of des_setkey() so that crypt.o exports
|
||||
* only the crypt() interface. This is required to make binaries linked
|
||||
* against crypt.o exportable or re-exportable from the USA.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
# include <stdio.h>
|
||||
#endif
|
||||
#define _PASSWORD_EFMT1 '_'
|
||||
|
||||
static unsigned char IP[64] = {
|
||||
58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
|
||||
62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
|
||||
57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
|
||||
61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
|
||||
};
|
||||
|
||||
static unsigned char inv_key_perm[64];
|
||||
static unsigned char key_perm[56] = {
|
||||
57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
|
||||
10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
|
||||
63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
|
||||
14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4
|
||||
};
|
||||
|
||||
static unsigned char key_shifts[16] = {
|
||||
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
|
||||
};
|
||||
|
||||
static unsigned char inv_comp_perm[56];
|
||||
static unsigned char comp_perm[48] = {
|
||||
14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
|
||||
23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
|
||||
41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
|
||||
44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
|
||||
};
|
||||
|
||||
/*
|
||||
* No E box is used, as it's replaced by some ANDs, shifts, and ORs.
|
||||
*/
|
||||
|
||||
static unsigned char u_sbox[8][64];
|
||||
static unsigned char sbox[8][64] = {
|
||||
{
|
||||
14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
|
||||
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
|
||||
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
|
||||
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13
|
||||
},
|
||||
{
|
||||
15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
|
||||
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
|
||||
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
|
||||
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9
|
||||
},
|
||||
{
|
||||
10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
|
||||
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
|
||||
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
|
||||
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12
|
||||
},
|
||||
{
|
||||
7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
|
||||
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
|
||||
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
|
||||
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14
|
||||
},
|
||||
{
|
||||
2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
|
||||
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
|
||||
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
|
||||
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3
|
||||
},
|
||||
{
|
||||
12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
|
||||
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
|
||||
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
|
||||
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13
|
||||
},
|
||||
{
|
||||
4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
|
||||
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
|
||||
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
|
||||
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12
|
||||
},
|
||||
{
|
||||
13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
|
||||
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
|
||||
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
|
||||
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
|
||||
}
|
||||
};
|
||||
|
||||
static unsigned char un_pbox[32];
|
||||
static unsigned char pbox[32] = {
|
||||
16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
|
||||
2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25
|
||||
};
|
||||
|
||||
static unsigned int bits32[32] =
|
||||
{
|
||||
0x80000000, 0x40000000, 0x20000000, 0x10000000,
|
||||
0x08000000, 0x04000000, 0x02000000, 0x01000000,
|
||||
0x00800000, 0x00400000, 0x00200000, 0x00100000,
|
||||
0x00080000, 0x00040000, 0x00020000, 0x00010000,
|
||||
0x00008000, 0x00004000, 0x00002000, 0x00001000,
|
||||
0x00000800, 0x00000400, 0x00000200, 0x00000100,
|
||||
0x00000080, 0x00000040, 0x00000020, 0x00000010,
|
||||
0x00000008, 0x00000004, 0x00000002, 0x00000001
|
||||
};
|
||||
|
||||
static unsigned char bits8[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
|
||||
|
||||
static unsigned int saltbits;
|
||||
static int old_salt;
|
||||
static unsigned int *bits28, *bits24;
|
||||
static unsigned char init_perm[64], final_perm[64];
|
||||
static unsigned int en_keysl[16], en_keysr[16];
|
||||
static unsigned int de_keysl[16], de_keysr[16];
|
||||
static int des_initialised = 0;
|
||||
static unsigned char m_sbox[4][4096];
|
||||
static unsigned int psbox[4][256];
|
||||
static unsigned int ip_maskl[8][256], ip_maskr[8][256];
|
||||
static unsigned int fp_maskl[8][256], fp_maskr[8][256];
|
||||
static unsigned int key_perm_maskl[8][128], key_perm_maskr[8][128];
|
||||
static unsigned int comp_maskl[8][128], comp_maskr[8][128];
|
||||
static unsigned int old_rawkey0, old_rawkey1;
|
||||
|
||||
static unsigned char ascii64[] =
|
||||
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
/* 0000000000111111111122222222223333333333444444444455555555556666 */
|
||||
/* 0123456789012345678901234567890123456789012345678901234567890123 */
|
||||
|
||||
static __inline int
|
||||
ascii_to_bin(ch)
|
||||
char ch;
|
||||
{
|
||||
if (ch > 'z')
|
||||
return(0);
|
||||
if (ch >= 'a')
|
||||
return(ch - 'a' + 38);
|
||||
if (ch > 'Z')
|
||||
return(0);
|
||||
if (ch >= 'A')
|
||||
return(ch - 'A' + 12);
|
||||
if (ch > '9')
|
||||
return(0);
|
||||
if (ch >= '.')
|
||||
return(ch - '.');
|
||||
return(0);
|
||||
}
|
||||
|
||||
static void
|
||||
des_init()
|
||||
{
|
||||
int i, j, b, k, inbit, obit;
|
||||
unsigned int *p, *il, *ir, *fl, *fr;
|
||||
|
||||
old_rawkey0 = old_rawkey1 = 0;
|
||||
saltbits = 0;
|
||||
old_salt = 0;
|
||||
bits24 = (bits28 = bits32 + 4) + 4;
|
||||
|
||||
/*
|
||||
* Invert the S-boxes, reordering the input bits.
|
||||
*/
|
||||
for (i = 0; i < 8; i++)
|
||||
for (j = 0; j < 64; j++) {
|
||||
b = (j & 0x20) | ((j & 1) << 4) | ((j >> 1) & 0xf);
|
||||
u_sbox[i][j] = sbox[i][b];
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the inverted S-boxes into 4 arrays of 8 bits.
|
||||
* Each will handle 12 bits of the S-box input.
|
||||
*/
|
||||
for (b = 0; b < 4; b++)
|
||||
for (i = 0; i < 64; i++)
|
||||
for (j = 0; j < 64; j++)
|
||||
m_sbox[b][(i << 6) | j] =
|
||||
(u_sbox[(b << 1)][i] << 4) |
|
||||
u_sbox[(b << 1) + 1][j];
|
||||
|
||||
/*
|
||||
* Set up the initial & final permutations into a useful form, and
|
||||
* initialise the inverted key permutation.
|
||||
*/
|
||||
for (i = 0; i < 64; i++) {
|
||||
init_perm[final_perm[i] = IP[i] - 1] = i;
|
||||
inv_key_perm[i] = 255;
|
||||
}
|
||||
|
||||
/*
|
||||
* Invert the key permutation and initialise the inverted key
|
||||
* compression permutation.
|
||||
*/
|
||||
for (i = 0; i < 56; i++) {
|
||||
inv_key_perm[key_perm[i] - 1] = i;
|
||||
inv_comp_perm[i] = 255;
|
||||
}
|
||||
|
||||
/*
|
||||
* Invert the key compression permutation.
|
||||
*/
|
||||
for (i = 0; i < 48; i++) {
|
||||
inv_comp_perm[comp_perm[i] - 1] = i;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the OR-mask arrays for the initial and final permutations,
|
||||
* and for the key initial and compression permutations.
|
||||
*/
|
||||
for (k = 0; k < 8; k++) {
|
||||
for (i = 0; i < 256; i++) {
|
||||
*(il = &ip_maskl[k][i]) = 0;
|
||||
*(ir = &ip_maskr[k][i]) = 0;
|
||||
*(fl = &fp_maskl[k][i]) = 0;
|
||||
*(fr = &fp_maskr[k][i]) = 0;
|
||||
for (j = 0; j < 8; j++) {
|
||||
inbit = 8 * k + j;
|
||||
if (i & bits8[j]) {
|
||||
if ((obit = init_perm[inbit]) < 32)
|
||||
*il |= bits32[obit];
|
||||
else
|
||||
*ir |= bits32[obit-32];
|
||||
if ((obit = final_perm[inbit]) < 32)
|
||||
*fl |= bits32[obit];
|
||||
else
|
||||
*fr |= bits32[obit - 32];
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < 128; i++) {
|
||||
*(il = &key_perm_maskl[k][i]) = 0;
|
||||
*(ir = &key_perm_maskr[k][i]) = 0;
|
||||
for (j = 0; j < 7; j++) {
|
||||
inbit = 8 * k + j;
|
||||
if (i & bits8[j + 1]) {
|
||||
if ((obit = inv_key_perm[inbit]) == 255)
|
||||
continue;
|
||||
if (obit < 28)
|
||||
*il |= bits28[obit];
|
||||
else
|
||||
*ir |= bits28[obit - 28];
|
||||
}
|
||||
}
|
||||
*(il = &comp_maskl[k][i]) = 0;
|
||||
*(ir = &comp_maskr[k][i]) = 0;
|
||||
for (j = 0; j < 7; j++) {
|
||||
inbit = 7 * k + j;
|
||||
if (i & bits8[j + 1]) {
|
||||
if ((obit=inv_comp_perm[inbit]) == 255)
|
||||
continue;
|
||||
if (obit < 24)
|
||||
*il |= bits24[obit];
|
||||
else
|
||||
*ir |= bits24[obit - 24];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Invert the P-box permutation, and convert into OR-masks for
|
||||
* handling the output of the S-box arrays setup above.
|
||||
*/
|
||||
for (i = 0; i < 32; i++)
|
||||
un_pbox[pbox[i] - 1] = i;
|
||||
|
||||
for (b = 0; b < 4; b++)
|
||||
for (i = 0; i < 256; i++) {
|
||||
*(p = &psbox[b][i]) = 0;
|
||||
for (j = 0; j < 8; j++) {
|
||||
if (i & bits8[j])
|
||||
*p |= bits32[un_pbox[8 * b + j]];
|
||||
}
|
||||
}
|
||||
|
||||
des_initialised = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
setup_salt(salt)
|
||||
int salt;
|
||||
{
|
||||
unsigned int obit, saltbit;
|
||||
int i;
|
||||
|
||||
if (salt == old_salt)
|
||||
return;
|
||||
old_salt = salt;
|
||||
|
||||
saltbits = 0;
|
||||
saltbit = 1;
|
||||
obit = 0x800000;
|
||||
for (i = 0; i < 24; i++) {
|
||||
if (salt & saltbit)
|
||||
saltbits |= obit;
|
||||
saltbit <<= 1;
|
||||
obit >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
des_setkey(key)
|
||||
const char *key;
|
||||
{
|
||||
unsigned int k0, k1, rawkey0, rawkey1;
|
||||
int shifts, round;
|
||||
|
||||
if (!des_initialised)
|
||||
des_init();
|
||||
|
||||
rawkey0 = md_ntohl(*(unsigned int *) key);
|
||||
rawkey1 = md_ntohl(*(unsigned int *) (key + 4));
|
||||
|
||||
if ((rawkey0 | rawkey1)
|
||||
&& rawkey0 == old_rawkey0
|
||||
&& rawkey1 == old_rawkey1) {
|
||||
/*
|
||||
* Already setup for this key.
|
||||
* This optimisation fails on a zero key (which is weak and
|
||||
* has bad parity anyway) in order to simplify the starting
|
||||
* conditions.
|
||||
*/
|
||||
return(0);
|
||||
}
|
||||
old_rawkey0 = rawkey0;
|
||||
old_rawkey1 = rawkey1;
|
||||
|
||||
/*
|
||||
* Do key permutation and split into two 28-bit subkeys.
|
||||
*/
|
||||
k0 = key_perm_maskl[0][rawkey0 >> 25]
|
||||
| key_perm_maskl[1][(rawkey0 >> 17) & 0x7f]
|
||||
| key_perm_maskl[2][(rawkey0 >> 9) & 0x7f]
|
||||
| key_perm_maskl[3][(rawkey0 >> 1) & 0x7f]
|
||||
| key_perm_maskl[4][rawkey1 >> 25]
|
||||
| key_perm_maskl[5][(rawkey1 >> 17) & 0x7f]
|
||||
| key_perm_maskl[6][(rawkey1 >> 9) & 0x7f]
|
||||
| key_perm_maskl[7][(rawkey1 >> 1) & 0x7f];
|
||||
k1 = key_perm_maskr[0][rawkey0 >> 25]
|
||||
| key_perm_maskr[1][(rawkey0 >> 17) & 0x7f]
|
||||
| key_perm_maskr[2][(rawkey0 >> 9) & 0x7f]
|
||||
| key_perm_maskr[3][(rawkey0 >> 1) & 0x7f]
|
||||
| key_perm_maskr[4][rawkey1 >> 25]
|
||||
| key_perm_maskr[5][(rawkey1 >> 17) & 0x7f]
|
||||
| key_perm_maskr[6][(rawkey1 >> 9) & 0x7f]
|
||||
| key_perm_maskr[7][(rawkey1 >> 1) & 0x7f];
|
||||
/*
|
||||
* Rotate subkeys and do compression permutation.
|
||||
*/
|
||||
shifts = 0;
|
||||
for (round = 0; round < 16; round++) {
|
||||
unsigned int t0, t1;
|
||||
|
||||
shifts += key_shifts[round];
|
||||
|
||||
t0 = (k0 << shifts) | (k0 >> (28 - shifts));
|
||||
t1 = (k1 << shifts) | (k1 >> (28 - shifts));
|
||||
|
||||
de_keysl[15 - round] =
|
||||
en_keysl[round] = comp_maskl[0][(t0 >> 21) & 0x7f]
|
||||
| comp_maskl[1][(t0 >> 14) & 0x7f]
|
||||
| comp_maskl[2][(t0 >> 7) & 0x7f]
|
||||
| comp_maskl[3][t0 & 0x7f]
|
||||
| comp_maskl[4][(t1 >> 21) & 0x7f]
|
||||
| comp_maskl[5][(t1 >> 14) & 0x7f]
|
||||
| comp_maskl[6][(t1 >> 7) & 0x7f]
|
||||
| comp_maskl[7][t1 & 0x7f];
|
||||
|
||||
de_keysr[15 - round] =
|
||||
en_keysr[round] = comp_maskr[0][(t0 >> 21) & 0x7f]
|
||||
| comp_maskr[1][(t0 >> 14) & 0x7f]
|
||||
| comp_maskr[2][(t0 >> 7) & 0x7f]
|
||||
| comp_maskr[3][t0 & 0x7f]
|
||||
| comp_maskr[4][(t1 >> 21) & 0x7f]
|
||||
| comp_maskr[5][(t1 >> 14) & 0x7f]
|
||||
| comp_maskr[6][(t1 >> 7) & 0x7f]
|
||||
| comp_maskr[7][t1 & 0x7f];
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
do_des(l_in, r_in, l_out, r_out, count)
|
||||
unsigned int l_in, r_in, *l_out, *r_out;
|
||||
int count;
|
||||
{
|
||||
/*
|
||||
* l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format.
|
||||
*/
|
||||
unsigned int l, r, *kl, *kr, *kl1, *kr1;
|
||||
unsigned int f = 0, r48l, r48r;
|
||||
int round;
|
||||
|
||||
if (count == 0) {
|
||||
return(1);
|
||||
} else if (count > 0) {
|
||||
/*
|
||||
* Encrypting
|
||||
*/
|
||||
kl1 = en_keysl;
|
||||
kr1 = en_keysr;
|
||||
} else {
|
||||
/*
|
||||
* Decrypting
|
||||
*/
|
||||
count = -count;
|
||||
kl1 = de_keysl;
|
||||
kr1 = de_keysr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do initial permutation (IP).
|
||||
*/
|
||||
l = ip_maskl[0][l_in >> 24]
|
||||
| ip_maskl[1][(l_in >> 16) & 0xff]
|
||||
| ip_maskl[2][(l_in >> 8) & 0xff]
|
||||
| ip_maskl[3][l_in & 0xff]
|
||||
| ip_maskl[4][r_in >> 24]
|
||||
| ip_maskl[5][(r_in >> 16) & 0xff]
|
||||
| ip_maskl[6][(r_in >> 8) & 0xff]
|
||||
| ip_maskl[7][r_in & 0xff];
|
||||
r = ip_maskr[0][l_in >> 24]
|
||||
| ip_maskr[1][(l_in >> 16) & 0xff]
|
||||
| ip_maskr[2][(l_in >> 8) & 0xff]
|
||||
| ip_maskr[3][l_in & 0xff]
|
||||
| ip_maskr[4][r_in >> 24]
|
||||
| ip_maskr[5][(r_in >> 16) & 0xff]
|
||||
| ip_maskr[6][(r_in >> 8) & 0xff]
|
||||
| ip_maskr[7][r_in & 0xff];
|
||||
|
||||
while (count--) {
|
||||
/*
|
||||
* Do each round.
|
||||
*/
|
||||
kl = kl1;
|
||||
kr = kr1;
|
||||
round = 16;
|
||||
while (round--) {
|
||||
/*
|
||||
* Expand R to 48 bits (simulate the E-box).
|
||||
*/
|
||||
r48l = ((r & 0x00000001) << 23)
|
||||
| ((r & 0xf8000000) >> 9)
|
||||
| ((r & 0x1f800000) >> 11)
|
||||
| ((r & 0x01f80000) >> 13)
|
||||
| ((r & 0x001f8000) >> 15);
|
||||
|
||||
r48r = ((r & 0x0001f800) << 7)
|
||||
| ((r & 0x00001f80) << 5)
|
||||
| ((r & 0x000001f8) << 3)
|
||||
| ((r & 0x0000001f) << 1)
|
||||
| ((r & 0x80000000) >> 31);
|
||||
/*
|
||||
* Do salting for crypt() and friends, and
|
||||
* XOR with the permuted key.
|
||||
*/
|
||||
f = (r48l ^ r48r) & saltbits;
|
||||
r48l ^= f ^ *kl++;
|
||||
r48r ^= f ^ *kr++;
|
||||
/*
|
||||
* Do sbox lookups (which shrink it back to 32 bits)
|
||||
* and do the pbox permutation at the same time.
|
||||
*/
|
||||
f = psbox[0][m_sbox[0][r48l >> 12]]
|
||||
| psbox[1][m_sbox[1][r48l & 0xfff]]
|
||||
| psbox[2][m_sbox[2][r48r >> 12]]
|
||||
| psbox[3][m_sbox[3][r48r & 0xfff]];
|
||||
/*
|
||||
* Now that we've permuted things, complete f().
|
||||
*/
|
||||
f ^= l;
|
||||
l = r;
|
||||
r = f;
|
||||
}
|
||||
r = l;
|
||||
l = f;
|
||||
}
|
||||
/*
|
||||
* Do final permutation (inverse of IP).
|
||||
*/
|
||||
*l_out = fp_maskl[0][l >> 24]
|
||||
| fp_maskl[1][(l >> 16) & 0xff]
|
||||
| fp_maskl[2][(l >> 8) & 0xff]
|
||||
| fp_maskl[3][l & 0xff]
|
||||
| fp_maskl[4][r >> 24]
|
||||
| fp_maskl[5][(r >> 16) & 0xff]
|
||||
| fp_maskl[6][(r >> 8) & 0xff]
|
||||
| fp_maskl[7][r & 0xff];
|
||||
*r_out = fp_maskr[0][l >> 24]
|
||||
| fp_maskr[1][(l >> 16) & 0xff]
|
||||
| fp_maskr[2][(l >> 8) & 0xff]
|
||||
| fp_maskr[3][l & 0xff]
|
||||
| fp_maskr[4][r >> 24]
|
||||
| fp_maskr[5][(r >> 16) & 0xff]
|
||||
| fp_maskr[6][(r >> 8) & 0xff]
|
||||
| fp_maskr[7][r & 0xff];
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
des_cipher(in, out, salt, count)
|
||||
const char *in;
|
||||
char *out;
|
||||
int salt;
|
||||
int count;
|
||||
{
|
||||
unsigned int l_out, r_out, rawl, rawr;
|
||||
unsigned int x[2];
|
||||
int retval;
|
||||
|
||||
if (!des_initialised)
|
||||
des_init();
|
||||
|
||||
setup_salt(salt);
|
||||
|
||||
memcpy(x, in, sizeof x);
|
||||
rawl = md_ntohl(x[0]);
|
||||
rawr = md_ntohl(x[1]);
|
||||
retval = do_des(rawl, rawr, &l_out, &r_out, count);
|
||||
|
||||
x[0] = md_htonl(l_out);
|
||||
x[1] = md_htonl(r_out);
|
||||
memcpy(out, x, sizeof x);
|
||||
return(retval);
|
||||
}
|
||||
|
||||
char *
|
||||
xcrypt(key, setting)
|
||||
const char *key;
|
||||
const char *setting;
|
||||
{
|
||||
int i;
|
||||
unsigned int count, salt, l, r0, r1, keybuf[2];
|
||||
unsigned char *p, *q;
|
||||
static unsigned char output[21];
|
||||
|
||||
if (!des_initialised)
|
||||
des_init();
|
||||
|
||||
/*
|
||||
* Copy the key, shifting each character up by one bit
|
||||
* and padding with zeros.
|
||||
*/
|
||||
q = (unsigned char *) keybuf;
|
||||
while ((q - (unsigned char *) keybuf) < sizeof(keybuf)) {
|
||||
if ((*q++ = *key << 1))
|
||||
key++;
|
||||
}
|
||||
if (des_setkey((unsigned char *) keybuf))
|
||||
return(NULL);
|
||||
|
||||
if (*setting == _PASSWORD_EFMT1) {
|
||||
/*
|
||||
* "new"-style:
|
||||
* setting - underscore, 4 bytes of count, 4 bytes of salt
|
||||
* key - unlimited characters
|
||||
*/
|
||||
for (i = 1, count = 0; i < 5; i++)
|
||||
count |= ascii_to_bin(setting[i]) << (i - 1) * 6;
|
||||
|
||||
for (i = 5, salt = 0; i < 9; i++)
|
||||
salt |= ascii_to_bin(setting[i]) << (i - 5) * 6;
|
||||
|
||||
while (*key) {
|
||||
/*
|
||||
* Encrypt the key with itself.
|
||||
*/
|
||||
if (des_cipher((unsigned char*)keybuf, (unsigned char*)keybuf, 0, 1))
|
||||
return(NULL);
|
||||
/*
|
||||
* And XOR with the next 8 characters of the key.
|
||||
*/
|
||||
q = (unsigned char *) keybuf;
|
||||
while (((q - (unsigned char *) keybuf) < sizeof(keybuf)) &&
|
||||
*key)
|
||||
*q++ ^= *key++ << 1;
|
||||
|
||||
if (des_setkey((unsigned char *) keybuf))
|
||||
return(NULL);
|
||||
}
|
||||
strncpy((char *)output, setting, 9);
|
||||
|
||||
/*
|
||||
* Double check that we weren't given a short setting.
|
||||
* If we were, the above code will probably have created
|
||||
* wierd values for count and salt, but we don't really care.
|
||||
* Just make sure the output string doesn't have an extra
|
||||
* NUL in it.
|
||||
*/
|
||||
output[9] = '\0';
|
||||
p = output + strlen((const char *)output);
|
||||
} else {
|
||||
/*
|
||||
* "old"-style:
|
||||
* setting - 2 bytes of salt
|
||||
* key - up to 8 characters
|
||||
*/
|
||||
count = 25;
|
||||
|
||||
salt = (ascii_to_bin(setting[1]) << 6)
|
||||
| ascii_to_bin(setting[0]);
|
||||
|
||||
output[0] = setting[0];
|
||||
/*
|
||||
* If the encrypted password that the salt was extracted from
|
||||
* is only 1 character long, the salt will be corrupted. We
|
||||
* need to ensure that the output string doesn't have an extra
|
||||
* NUL in it!
|
||||
*/
|
||||
output[1] = setting[1] ? setting[1] : output[0];
|
||||
|
||||
p = output + 2;
|
||||
}
|
||||
setup_salt(salt);
|
||||
/*
|
||||
* Do it.
|
||||
*/
|
||||
if (do_des(0, 0, &r0, &r1, count))
|
||||
return(NULL);
|
||||
/*
|
||||
* Now encode the result...
|
||||
*/
|
||||
l = (r0 >> 8);
|
||||
*p++ = ascii64[(l >> 18) & 0x3f];
|
||||
*p++ = ascii64[(l >> 12) & 0x3f];
|
||||
*p++ = ascii64[(l >> 6) & 0x3f];
|
||||
*p++ = ascii64[l & 0x3f];
|
||||
|
||||
l = (r0 << 16) | ((r1 >> 16) & 0xffff);
|
||||
*p++ = ascii64[(l >> 18) & 0x3f];
|
||||
*p++ = ascii64[(l >> 12) & 0x3f];
|
||||
*p++ = ascii64[(l >> 6) & 0x3f];
|
||||
*p++ = ascii64[l & 0x3f];
|
||||
|
||||
l = r1 << 2;
|
||||
*p++ = ascii64[(l >> 12) & 0x3f];
|
||||
*p++ = ascii64[(l >> 6) & 0x3f];
|
||||
*p++ = ascii64[l & 0x3f];
|
||||
*p = 0;
|
||||
|
||||
return((char *)output);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue