Import Super-Rogue 9.0 from the Roguelike Restoration Project (r1490)
This commit is contained in:
parent
00669593bd
commit
ce4b930551
48 changed files with 17601 additions and 0 deletions
139
srogue/LICENSE.TXT
Normal file
139
srogue/LICENSE.TXT
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
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.
|
||||
|
||||
===========================================================================
|
||||
|
||||
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.
|
||||
130
srogue/Makefile
Normal file
130
srogue/Makefile
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
# Makefile for rogue
|
||||
# %W% (Berkeley) %G%
|
||||
#
|
||||
# Super-Rogue
|
||||
# Copyright (C) 1984 Robert D. Kindelberger
|
||||
# All rights reserved.
|
||||
#
|
||||
# Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
# Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
# All rights reserved.
|
||||
#
|
||||
# See the file LICENSE.TXT for full copyright and licensing information.
|
||||
|
||||
DISTNAME=srogue9.0-1
|
||||
PROGRAM=srogue
|
||||
|
||||
HDRS= bob.h cx.h ncx.h rdk.h rogue.h
|
||||
OBJS= vers.o armor.o chase.o command.o daemon.o daemons.o disply.o encumb.o \
|
||||
fight.o global.o init.o io.o list.o main.o misc.o monsters.o move.o \
|
||||
new_leve.o options.o pack.o passages.o potions.o pstats.o rings.o rip.o \
|
||||
rooms.o save.o scrolls.o state.o sticks.o things.o trader.o weapons.o \
|
||||
wizard.o xcrypt.o
|
||||
CFILES= vers.c armor.c chase.c command.c daemon.c daemons.c disply.c encumb.c \
|
||||
fight.c global.c init.c io.c list.c main.c misc.c monsters.c move.c \
|
||||
new_leve.c options.c pack.c passages.c potions.c pstats.c rings.c rip.c \
|
||||
rooms.c save.c scrolls.c state.c sticks.c things.c trader.c weapons.c \
|
||||
wizard.c xcrypt.c
|
||||
|
||||
MISC= Makefile LICENSE.TXT rogue.nr
|
||||
|
||||
CC = gcc
|
||||
CFLAGS= -g
|
||||
CRLIB = -lcurses
|
||||
RM = rm -f
|
||||
TAR = tar
|
||||
|
||||
$(PROGRAM): $(HDRS) $(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 -f $(OBJS) core
|
||||
rm -f $(PROGRAM) $(PROGRAM).exe $(PROGRAM) $(PROGRAM).exe $(PROGRAM).tar $(PROGRAM).tar.gz $(PROGRAM).doc
|
||||
|
||||
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)
|
||||
gzip -f $(DISTNAME)-src.tar
|
||||
|
||||
dist.irix:
|
||||
make clean
|
||||
make CC=cc CFLAGS="-woff 1116 -O3" $(PROGRAM)
|
||||
tbl rogue.nr | nroff -mm | colcrt - > $(PROGRAM).doc
|
||||
tar cf $(DISTNAME)-irix.tar $(PROGRAM) LICENSE.TXT $(PROGRAM).doc
|
||||
gzip -f $(DISTNAME)-irix.tar
|
||||
|
||||
debug.aix:
|
||||
make clean
|
||||
make CC=xlc CFLAGS="-qmaxmem=16768 -g -DWIZARD -qstrict" $(PROGRAM)
|
||||
|
||||
dist.aix:
|
||||
make clean
|
||||
make CC=xlc CFLAGS="-qmaxmem=16768 -O3 -qstrict" $(PROGRAM)
|
||||
tbl rogue.nr | nroff -mm | colcrt - > $(PROGRAM).doc
|
||||
tar cf $(DISTNAME)-aix.tar $(PROGRAM) LICENSE.TXT $(PROGRAM).doc
|
||||
gzip -f $(DISTNAME)-aix.tar
|
||||
|
||||
debug.linux:
|
||||
make clean
|
||||
make CFLAGS="-g -DWIZARD" $(PROGRAM)
|
||||
|
||||
dist.linux:
|
||||
make clean
|
||||
make $(PROGRAM)
|
||||
groff -P-c -t -mm -Tascii rogue.nr | sed -e 's/.\x08//g' >$(PROGRAM).doc
|
||||
tar cf $(DISTNAME)-linux.tar $(PROGRAM) LICENSE.TXT $(PROGRAM).doc
|
||||
gzip -f $(DISTNAME)-linux.tar
|
||||
|
||||
debug.interix:
|
||||
make clean
|
||||
make CFLAGS="-g3 -DWIZARD" $(PROGRAM)
|
||||
|
||||
dist.interix:
|
||||
make clean
|
||||
make $(PROGRAM)
|
||||
groff -P-b -P-u -t -mm -Tascii rogue.nr > $(PROGRAM).doc
|
||||
tar cf $(DISTNAME)-interix.tar $(PROGRAM) LICENSE.TXT $(PROGRAM).doc
|
||||
gzip -f $(DISTNAME)-interix.tar
|
||||
|
||||
debug.cygwin:
|
||||
make clean
|
||||
make CFLAGS="-g3 -DWIZARD" $(PROGRAM)
|
||||
|
||||
dist.cygwin:
|
||||
make clean
|
||||
make $(PROGRAM)
|
||||
groff -P-c -t -mm -Tascii rogue.nr | sed -e 's/.\x08//g' >$(PROGRAM).doc
|
||||
tar cf $(DISTNAME)-cygwin.tar $(PROGRAM).exe LICENSE.TXT $(PROGRAM).doc
|
||||
gzip -f $(DISTNAME)-cygwin.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)
|
||||
groff -t -mm -Tascii rogue.nr | sed -e 's/.\x08//g' > $(PROGRAM).doc
|
||||
rm -f $(DISTNAME)-djgpp.zip
|
||||
zip $(DISTNAME)-djgpp.zip $(PROGRAM).exe LICENSE.TXT $(PROGRAM).doc
|
||||
108
srogue/armor.c
Normal file
108
srogue/armor.c
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* This file contains misc functions for dealing with armor
|
||||
*
|
||||
* @(#)armor.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "rogue.h"
|
||||
#include "rogue.ext"
|
||||
|
||||
/*
|
||||
* wear:
|
||||
* The player wants to wear something, so let the hero try
|
||||
*/
|
||||
wear()
|
||||
{
|
||||
reg struct linked_list *item;
|
||||
reg struct object *obj;
|
||||
|
||||
if (cur_armor != NULL) {
|
||||
msg("You are already wearing some.");
|
||||
after = FALSE;
|
||||
return;
|
||||
}
|
||||
if ((item = get_item("wear", ARMOR)) == NULL)
|
||||
return;
|
||||
obj = OBJPTR(item);
|
||||
if (obj->o_type != ARMOR) {
|
||||
msg("You can't wear that.");
|
||||
return;
|
||||
}
|
||||
waste_time();
|
||||
msg("Wearing %s.", a_magic[obj->o_which].mi_name);
|
||||
cur_armor = obj;
|
||||
setoflg(obj,ISKNOW);
|
||||
nochange = FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* take_off:
|
||||
* Get the armor off of the players back
|
||||
*/
|
||||
take_off()
|
||||
{
|
||||
reg struct object *obj;
|
||||
|
||||
if ((obj = cur_armor) == NULL) {
|
||||
msg("Not wearing any armor.");
|
||||
return;
|
||||
}
|
||||
if (!dropcheck(cur_armor))
|
||||
return;
|
||||
cur_armor = NULL;
|
||||
msg("Was wearing %c) %s",pack_char(obj),inv_name(obj,TRUE));
|
||||
nochange = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* initarmor:
|
||||
* Initialize some armor.
|
||||
*/
|
||||
initarmor(obj, what)
|
||||
struct object *obj;
|
||||
int what;
|
||||
{
|
||||
struct init_armor *iwa;
|
||||
struct magic_item *mi;
|
||||
|
||||
obj->o_type = ARMOR;
|
||||
obj->o_which = what;
|
||||
iwa = &armors[what];
|
||||
mi = &a_magic[what];
|
||||
obj->o_vol = iwa->a_vol;
|
||||
obj->o_ac = iwa->a_class;
|
||||
obj->o_weight = iwa->a_wght;
|
||||
obj->o_typname = things[TYP_ARMOR].mi_name;
|
||||
}
|
||||
|
||||
/*
|
||||
* hurt_armor:
|
||||
* Returns TRUE if armor is damaged
|
||||
*/
|
||||
hurt_armor(obj)
|
||||
struct object *obj;
|
||||
{
|
||||
reg int type, ac;
|
||||
|
||||
if (obj != NULL) {
|
||||
if (o_on(obj, ISPROT) || (o_on(obj, ISBLESS) && rnd(100) < 10))
|
||||
return FALSE;
|
||||
ac = obj->o_ac;
|
||||
type = obj->o_which;
|
||||
if (type != PADDED && type != LEATHER)
|
||||
if ((type == STUDDED && ac < 8) || (type != STUDDED && ac < 9))
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
12
srogue/bob.h
Normal file
12
srogue/bob.h
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include <sgtty.h>
|
||||
typedef struct sgttyb SGTTY;
|
||||
static SGTTY _tty, _res_flg;
|
||||
|
||||
121
srogue/bsdtty.c
Normal file
121
srogue/bsdtty.c
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "rogue.h"
|
||||
|
||||
extern bool NONL;
|
||||
|
||||
raw()
|
||||
{
|
||||
/*
|
||||
VERSION 5.0
|
||||
_tty.c_lflag &= ~ICANON;
|
||||
_tty.c_cc[VMIN] = 1;
|
||||
_tty.c_cc[VTIME] = 255;
|
||||
_tty.c_oflag &= ~OPOST;
|
||||
*/
|
||||
_rawmode = TRUE;
|
||||
_tty.sg_flags |= CBREAK;
|
||||
ioctl(_tty_ch, TIOCSETN, &_tty);
|
||||
}
|
||||
|
||||
|
||||
noraw()
|
||||
{
|
||||
/*
|
||||
VERSION 5.0
|
||||
_tty.c_lflag |= ICANON;
|
||||
_tty.c_cc[VMIN] = _res_flg.c_cc[VMIN];
|
||||
_tty.c_cc[VTIME] = _res_flg.c_cc[VTIME];
|
||||
_tty.c_oflag |= OPOST;
|
||||
*/
|
||||
_rawmode = FALSE;
|
||||
_tty.sg_flags &= ~CBREAK;
|
||||
ioctl(_tty_ch, TIOCSETN, &_tty);
|
||||
}
|
||||
|
||||
|
||||
crmode()
|
||||
{
|
||||
/*
|
||||
VERSION 5.0
|
||||
_tty.c_lflag &= ~ICANON;
|
||||
_tty.c_oflag |= ONLCR;
|
||||
_tty.c_cc[VMIN] = 1;
|
||||
_tty.c_cc[VTIME]=255;
|
||||
*/
|
||||
_rawmode = TRUE;
|
||||
_tty.sg_flags |= (CBREAK | CRMOD);
|
||||
ioctl(_tty_ch, TIOCSETN, &_tty);
|
||||
}
|
||||
|
||||
|
||||
nocrmode()
|
||||
{
|
||||
/*
|
||||
_tty.c_lflag |= ICANON;
|
||||
_tty.c_cc[VMIN]=_res_flg.c_cc[VMIN];
|
||||
_tty.c_cc[VTIME]=_res_flg.c_cc[VTIME];
|
||||
*/
|
||||
_rawmode = FALSE;
|
||||
_tty.sg_flags &= ~CBREAK;
|
||||
ioctl(_tty_ch, TIOCSETN, &_tty);
|
||||
}
|
||||
|
||||
|
||||
echo()
|
||||
{
|
||||
_tty.sg_flags |= ECHO;
|
||||
_echoit=TRUE;
|
||||
ioctl(_tty_ch, TIOCSETN, &_tty);
|
||||
}
|
||||
|
||||
noecho()
|
||||
{
|
||||
_tty.sg_flags &= ~ECHO;
|
||||
_echoit = FALSE;
|
||||
ioctl(_tty_ch, TIOCSETN, &_tty);
|
||||
}
|
||||
|
||||
|
||||
nl()
|
||||
{
|
||||
/*
|
||||
VERSION 5.0
|
||||
_tty.c_iflag |= ICRNL;
|
||||
_tty.c_oflag |= ONLCR;
|
||||
*/
|
||||
_tty.sg_flags |= CRMOD;
|
||||
NONL = TRUE;
|
||||
ioctl(_tty_ch, TIOCSETN, &_tty);
|
||||
}
|
||||
|
||||
|
||||
nonl()
|
||||
{
|
||||
/*
|
||||
VERSION 5.0
|
||||
_tty.c_iflag &= ~ICRNL;
|
||||
_tty.c_oflag &= ~ONLCR;
|
||||
*/
|
||||
_tty.sg_flags &= ~CRMOD;
|
||||
NONL = FALSE;
|
||||
ioctl(_tty_ch, TIOCSETN, &_tty);
|
||||
}
|
||||
|
||||
savetty()
|
||||
{
|
||||
ioctl(_tty_ch, TIOCGETP, &_tty);
|
||||
_res_flg = _tty;
|
||||
}
|
||||
|
||||
resetty()
|
||||
{
|
||||
_tty = _res_flg;
|
||||
ioctl(_tty_ch, TIOCSETN, &_tty);
|
||||
}
|
||||
486
srogue/chase.c
Normal file
486
srogue/chase.c
Normal file
|
|
@ -0,0 +1,486 @@
|
|||
/*
|
||||
* Code for one object to chase another
|
||||
*
|
||||
* @(#)chase.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "rogue.h"
|
||||
#include "rogue.ext"
|
||||
|
||||
#define FARAWAY 32767
|
||||
#define RDIST(a, b) (DISTANCE((a)->y, (a)->x, (b).y, (b).x))
|
||||
|
||||
struct coord ch_ret; /* Where chasing takes you */
|
||||
|
||||
/*
|
||||
* runners:
|
||||
* Make all the running monsters move.
|
||||
*/
|
||||
runners()
|
||||
{
|
||||
reg struct thing *tp;
|
||||
reg struct linked_list *mon,*nextmon;
|
||||
|
||||
for (mon = mlist; mon != NULL; mon = nextmon) {
|
||||
tp = THINGPTR(mon);
|
||||
nextmon = next(mon);
|
||||
if (off(*tp, ISHELD) && on(*tp, ISRUN)) {
|
||||
if (tp->t_nomove > 0)
|
||||
if (--tp->t_nomove > 0)
|
||||
continue;
|
||||
if (on(*tp, ISHASTE))
|
||||
if (do_chase(mon) == -1)
|
||||
continue;
|
||||
if (off(*tp, ISSLOW) || tp->t_turn)
|
||||
if (do_chase(mon) == -1)
|
||||
continue;
|
||||
tp->t_turn ^= TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* do_chase:
|
||||
* Make one thing chase another.
|
||||
*/
|
||||
do_chase(mon)
|
||||
struct linked_list *mon;
|
||||
{
|
||||
reg struct thing *th;
|
||||
reg struct room *rer, *ree, *rxx;
|
||||
reg int mindist, i, dist;
|
||||
struct stats *st;
|
||||
bool stoprun = FALSE, ondoor = FALSE, link = FALSE;
|
||||
char runaway, dofight, wound, sch, ch;
|
||||
struct coord this;
|
||||
struct trap *trp;
|
||||
|
||||
th = THINGPTR(mon);
|
||||
wound = th->t_flags & ISWOUND;
|
||||
if (wound)
|
||||
mindist = 0;
|
||||
else
|
||||
mindist = FARAWAY;
|
||||
runaway = wound;
|
||||
dofight = !runaway;
|
||||
rer = th->t_room;
|
||||
if (th->t_type == 'V') {
|
||||
if (rer != NULL && !rf_on(rer, ISDARK)) {
|
||||
/*
|
||||
* Vampires can't stand the light
|
||||
*/
|
||||
if (cansee(th->t_pos.y, th->t_pos.x))
|
||||
msg("The vampire vaporizes into thin air !");
|
||||
killed(mon, FALSE);
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
ree = roomin(th->t_dest); /* room of chasee */
|
||||
this = *th->t_dest;
|
||||
/*
|
||||
* If the object of our desire is in a different
|
||||
* room, then run to the door nearest to our goal.
|
||||
*/
|
||||
if (mvinch(th->t_pos.y, th->t_pos.x) == DOOR)
|
||||
ondoor = TRUE;
|
||||
rxx = NULL;
|
||||
if (rer != NULL || ree != NULL) {
|
||||
/*
|
||||
* Monster not in room, hero in room. Run to closest door
|
||||
* in hero's room if not wounded. Run away if wounded.
|
||||
*/
|
||||
if (rer == NULL && ree != NULL) {
|
||||
if (!wound)
|
||||
rxx = ree;
|
||||
}
|
||||
/*
|
||||
* Monster in a room, hero not in room. If on a door,
|
||||
* then use closest distance. If not on a door, then
|
||||
* run to closest door in monsters room.
|
||||
*/
|
||||
else if (rer != NULL && ree == NULL) {
|
||||
if (!ondoor) {
|
||||
rxx = rer;
|
||||
if (wound)
|
||||
runaway = FALSE;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Both hero and monster in a DIFFERENT room. Set flag to
|
||||
* check for links between the monster's and hero's rooms.
|
||||
* If no links are found, then the closest door in the
|
||||
* monster's room is used.
|
||||
*/
|
||||
else if (rer != ree) {
|
||||
if (!wound) {
|
||||
link = TRUE;
|
||||
if (ondoor)
|
||||
rxx = ree; /* if on door, run to heros room */
|
||||
else
|
||||
rxx = rer; /* else to nearest door this room */
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Both hero and monster in same room. If monster is
|
||||
* wounded, find the best door to run to.
|
||||
*/
|
||||
else if (wound) {
|
||||
struct coord *ex;
|
||||
int poss, mdtd, hdtd, ghdtd, nx, gx = 0, best;
|
||||
|
||||
best = ghdtd = -FARAWAY;
|
||||
for (nx = 0; nx < ree->r_nexits; nx++) {
|
||||
ex = &ree->r_exit[nx];
|
||||
if (mvinch(ex->y, ex->x) == SECRETDOOR)
|
||||
continue;
|
||||
gx += 1;
|
||||
mdtd = abs(th->t_pos.y - ex->y) + abs(th->t_pos.x - ex->x);
|
||||
hdtd = abs(hero.y - ex->y) + abs(hero.x - ex->x);
|
||||
poss = hdtd - mdtd; /* possible move */
|
||||
if (poss > best) {
|
||||
best = poss;
|
||||
this = *ex;
|
||||
}
|
||||
else if (poss == best && hdtd > ghdtd) {
|
||||
ghdtd = hdtd;
|
||||
best = poss;
|
||||
this = *ex;
|
||||
}
|
||||
}
|
||||
runaway = FALSE; /* go for target */
|
||||
if (best < 1)
|
||||
dofight = TRUE; /* fight if we must */
|
||||
mdtd = (gx <= 1 && best < 1);
|
||||
if (ondoor || mdtd) {
|
||||
this = hero;
|
||||
runaway = TRUE;
|
||||
if (!mdtd)
|
||||
dofight = FALSE;
|
||||
}
|
||||
}
|
||||
if (rxx != NULL) {
|
||||
for (i = 0; i < rxx->r_nexits; i += 1) {
|
||||
dist = RDIST(th->t_dest, rxx->r_exit[i]);
|
||||
if (link && rxx->r_ptr[i] == ree)
|
||||
dist = -1;
|
||||
if ((!wound && dist < mindist) ||
|
||||
(wound && dist > mindist)) {
|
||||
this = rxx->r_exit[i];
|
||||
mindist = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (DISTANCE(hero.y, hero.x, th->t_pos.y, th->t_pos.x) <= 3)
|
||||
dofight = TRUE;
|
||||
/*
|
||||
* this now contains what we want to run to this time
|
||||
* so we run to it. If we hit it we either want to
|
||||
* fight it or stop running.
|
||||
*/
|
||||
if (chase(th, &this, runaway, dofight) == FIGHT) {
|
||||
return( attack(th) );
|
||||
}
|
||||
else if ((th->t_flags & (ISSTUCK | ISPARA)))
|
||||
return(0); /* if paralyzed or stuck */
|
||||
if ((trp = trap_at(ch_ret.y, ch_ret.x)) != NULL) {
|
||||
ch = be_trapped(&ch_ret, th);
|
||||
if (ch == GONER || nlmove) {
|
||||
if (ch == GONER)
|
||||
remove_monster(&th->t_pos, mon);
|
||||
nlmove = FALSE;
|
||||
return((ch == GONER) ? -1 : 0);
|
||||
}
|
||||
}
|
||||
if (pl_off(ISBLIND))
|
||||
mvwaddch(cw,th->t_pos.y,th->t_pos.x,th->t_oldch);
|
||||
sch = mvwinch(cw, ch_ret.y, ch_ret.x);
|
||||
if (rer != NULL && rf_on(rer,ISDARK) && sch == FLOOR &&
|
||||
DISTANCE(ch_ret.y,ch_ret.x,th->t_pos.y,th->t_pos.x) < 3 &&
|
||||
pl_off(ISBLIND))
|
||||
th->t_oldch = ' ';
|
||||
else
|
||||
th->t_oldch = sch;
|
||||
if (cansee(unc(ch_ret)) && off(*th, ISINVIS))
|
||||
mvwaddch(cw, ch_ret.y, ch_ret.x, th->t_type);
|
||||
mvwaddch(mw, th->t_pos.y, th->t_pos.x, ' ');
|
||||
mvwaddch(mw, ch_ret.y, ch_ret.x, th->t_type);
|
||||
th->t_oldpos = th->t_pos;
|
||||
th->t_pos = ch_ret;
|
||||
th->t_room = roomin(&ch_ret);
|
||||
i = 5;
|
||||
if (th->t_flags & ISREGEN)
|
||||
i = 40;
|
||||
st = &th->t_stats;
|
||||
if (rnd(100) < i) {
|
||||
if (++st->s_hpt > st->s_maxhp)
|
||||
st->s_hpt = st->s_maxhp;
|
||||
if (!monhurt(th))
|
||||
th->t_flags &= ~ISWOUND;
|
||||
}
|
||||
if (stoprun && ce(th->t_pos, *(th->t_dest)))
|
||||
th->t_flags &= ~ISRUN;
|
||||
return CHASE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* chase:
|
||||
* Find the spot for the chaser to move closer to the
|
||||
* chasee. Returns TRUE if we want to keep on chasing
|
||||
* later FALSE if we reach the goal.
|
||||
*/
|
||||
chase(tp, ee, runaway, dofight)
|
||||
struct thing *tp;
|
||||
struct coord *ee;
|
||||
bool runaway, dofight;
|
||||
{
|
||||
reg int x, y, ch;
|
||||
reg int dist, thisdist, closest;
|
||||
reg struct coord *er = &tp->t_pos;
|
||||
struct coord try, closecoord;
|
||||
int numsteps, onscare;
|
||||
|
||||
/*
|
||||
* If the thing is confused, let it move randomly.
|
||||
*/
|
||||
ch = CHASE;
|
||||
onscare = FALSE;
|
||||
if (on(*tp, ISHUH)) {
|
||||
ch_ret = *rndmove(tp);
|
||||
dist = DISTANCE(hero.y, hero.x, ch_ret.y, ch_ret.x);
|
||||
if (rnd(1000) < 5)
|
||||
tp->t_flags &= ~ISHUH;
|
||||
if (dist == 0)
|
||||
ch = FIGHT;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Otherwise, find the the best spot to run to
|
||||
* in order to get to your goal.
|
||||
*/
|
||||
numsteps = 0;
|
||||
if (runaway)
|
||||
closest = 0;
|
||||
else
|
||||
closest = FARAWAY;
|
||||
ch_ret = *er;
|
||||
closecoord = tp->t_oldpos;
|
||||
for (y = er->y - 1; y <= er->y + 1; y += 1) {
|
||||
for (x = er->x - 1; x <= er->x + 1; x += 1) {
|
||||
if (!cordok(y, x))
|
||||
continue;
|
||||
try.x = x;
|
||||
try.y = y;
|
||||
if (!diag_ok(er, &try))
|
||||
continue;
|
||||
ch = winat(y, x);
|
||||
if (step_ok(ch)) {
|
||||
struct trap *trp;
|
||||
|
||||
if (isatrap(ch)) {
|
||||
trp = trap_at(y, x);
|
||||
if (trp != NULL && off(*tp, ISHUH)) {
|
||||
/*
|
||||
* Dont run over found traps unless
|
||||
* the hero is standing on it. If confused,
|
||||
* then he can run into them.
|
||||
*/
|
||||
if (trp->tr_flags & ISFOUND) {
|
||||
if (trp->tr_type == POOL && rnd(100) < 80)
|
||||
continue;
|
||||
else if (y != hero.y || x != hero.x)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Check for scare monster scrolls.
|
||||
*/
|
||||
if (ch == SCROLL) {
|
||||
struct linked_list *item;
|
||||
|
||||
item = find_obj(y, x);
|
||||
if (item != NULL)
|
||||
if ((OBJPTR(item))->o_which == S_SCARE) {
|
||||
if (ce(hero, try))
|
||||
onscare = TRUE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Vampires will not run into a lit room.
|
||||
*/
|
||||
if (tp->t_type == 'V') {
|
||||
struct room *lr;
|
||||
|
||||
lr = roomin(&try);
|
||||
if (lr != NULL && !rf_on(lr, ISDARK))
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* This is a valid place to step
|
||||
*/
|
||||
if (y == hero.y && x == hero.x) {
|
||||
if (dofight) {
|
||||
ch_ret = try; /* if fighting */
|
||||
return FIGHT; /* hit hero */
|
||||
}
|
||||
else
|
||||
continue;
|
||||
}
|
||||
thisdist = DISTANCE(y, x, ee->y, ee->x);
|
||||
if (thisdist <= 0) {
|
||||
ch_ret = try; /* got here but */
|
||||
return CHASE; /* dont fight */
|
||||
}
|
||||
numsteps += 1;
|
||||
if ((!runaway && thisdist < closest) ||
|
||||
(runaway && thisdist > closest)) {
|
||||
/*
|
||||
* dont count the monsters last position as
|
||||
* the closest spot, unless running away and
|
||||
* in the same room.
|
||||
*/
|
||||
if (!ce(try, tp->t_oldpos) || (runaway
|
||||
&& player.t_room == tp->t_room
|
||||
&& tp->t_room != NULL)) {
|
||||
closest = thisdist;
|
||||
closecoord = try;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If dead end, then go back from whence you came.
|
||||
* Otherwise, pick the closest of the remaining spots.
|
||||
*/
|
||||
if (numsteps > 0) /* move to best spot */
|
||||
ch_ret = closecoord;
|
||||
else { /* nowhere to go */
|
||||
if (DISTANCE(tp->t_pos.y, tp->t_pos.x, hero.y, hero.x) < 2)
|
||||
if (!onscare)
|
||||
ch_ret = hero;
|
||||
}
|
||||
if (ce(hero, ch_ret))
|
||||
ch = FIGHT;
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* runto:
|
||||
* Set a monster running after something
|
||||
*/
|
||||
runto(runner, spot)
|
||||
struct coord *runner;
|
||||
struct coord *spot;
|
||||
{
|
||||
reg struct linked_list *item;
|
||||
reg struct thing *tp;
|
||||
|
||||
if ((item = find_mons(runner->y, runner->x)) == NULL)
|
||||
return;
|
||||
tp = THINGPTR(item);
|
||||
if (tp->t_flags & ISPARA)
|
||||
return;
|
||||
tp->t_dest = spot;
|
||||
tp->t_flags |= ISRUN;
|
||||
tp->t_flags &= ~ISHELD;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* roomin:
|
||||
* Find what room some coordinates are in.
|
||||
* NULL means they aren't in any room.
|
||||
*/
|
||||
struct room *
|
||||
roomin(cp)
|
||||
struct coord *cp;
|
||||
{
|
||||
reg struct room *rp;
|
||||
|
||||
if (cordok(cp->y, cp->x)) {
|
||||
for (rp = rooms; rp < &rooms[MAXROOMS]; rp += 1)
|
||||
if (inroom(rp, cp))
|
||||
return rp;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* find_mons:
|
||||
* Find the monster from his coordinates
|
||||
*/
|
||||
struct linked_list *
|
||||
find_mons(y, x)
|
||||
int y, x;
|
||||
{
|
||||
reg struct linked_list *item;
|
||||
reg 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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* diag_ok:
|
||||
* Check to see if the move is legal if it is diagonal
|
||||
*/
|
||||
diag_ok(sp, ep)
|
||||
struct coord *sp, *ep;
|
||||
{
|
||||
if (ep->x == sp->x || ep->y == sp->y)
|
||||
return TRUE;
|
||||
if (step_ok(mvinch(ep->y,sp->x)) && step_ok(mvinch(sp->y,ep->x)))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* cansee:
|
||||
* returns true if the hero can see a certain coordinate.
|
||||
*/
|
||||
cansee(y, x)
|
||||
int y, x;
|
||||
{
|
||||
reg struct room *rer;
|
||||
struct coord tp;
|
||||
|
||||
if (pl_on(ISBLIND))
|
||||
return FALSE;
|
||||
/*
|
||||
* We can only see if the hero in the same room as
|
||||
* the coordinate and the room is lit or if it is close.
|
||||
*/
|
||||
if (DISTANCE(y, x, hero.y, hero.x) < 3)
|
||||
return TRUE;
|
||||
tp.y = y;
|
||||
tp.x = x;
|
||||
rer = roomin(&tp);
|
||||
if (rer != NULL && levtype != MAZELEV)
|
||||
if (rer == player.t_room && !rf_on(rer,ISDARK))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
714
srogue/command.c
Normal file
714
srogue/command.c
Normal file
|
|
@ -0,0 +1,714 @@
|
|||
/*
|
||||
* Read and execute the user commands
|
||||
*
|
||||
* @(#)command.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <signal.h>
|
||||
#include <limits.h>
|
||||
#include "rogue.h"
|
||||
#include "rogue.ext"
|
||||
#ifdef __DJGPP__
|
||||
#include <process.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* command:
|
||||
* Process the user commands
|
||||
*/
|
||||
command()
|
||||
{
|
||||
reg char ch;
|
||||
reg int ntimes = 1; /* Number of player moves */
|
||||
static char countch, direction, newcount = FALSE;
|
||||
|
||||
if (pl_on(ISHASTE))
|
||||
ntimes++;
|
||||
/*
|
||||
* Let the daemons start up
|
||||
*/
|
||||
while (ntimes-- > 0) {
|
||||
do_daemons(BEFORE);
|
||||
look(TRUE);
|
||||
if (!running)
|
||||
door_stop = FALSE;
|
||||
lastscore = purse;
|
||||
wmove(cw, hero.y, hero.x);
|
||||
if (!(running || count))
|
||||
draw(cw); /* Draw screen */
|
||||
take = 0;
|
||||
after = TRUE;
|
||||
/*
|
||||
* Read command or continue run
|
||||
*/
|
||||
if (wizard)
|
||||
waswizard = TRUE;
|
||||
if (player.t_nocmd <= 0) {
|
||||
player.t_nocmd = 0;
|
||||
if (running)
|
||||
ch = runch;
|
||||
else if (count)
|
||||
ch = countch;
|
||||
else {
|
||||
ch = readchar();
|
||||
if (mpos != 0 && !running) /* Erase message if its there */
|
||||
msg("");
|
||||
}
|
||||
}
|
||||
else
|
||||
ch = '.';
|
||||
if (player.t_nocmd > 0) {
|
||||
if (--player.t_nocmd <= 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');
|
||||
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;
|
||||
}
|
||||
}
|
||||
switch (ch) {
|
||||
case 'f':
|
||||
case 'g':
|
||||
if (pl_off(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(); after = FALSE;
|
||||
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 (!get_dir())
|
||||
after = FALSE;
|
||||
else
|
||||
missile(delta.y, delta.x);
|
||||
when 'Q' : after = FALSE; quit(-1);
|
||||
when 'i' : after = FALSE; inventory(pack, 0);
|
||||
when 'I' : after = FALSE; picky_inven();
|
||||
when 'd' : drop(NULL);
|
||||
when 'q' : quaff();
|
||||
when 'r' : read_scroll();
|
||||
when 'e' : eat();
|
||||
when 'w' : wield();
|
||||
when 'W' : wear();
|
||||
when 'T' : take_off();
|
||||
when 'P' : ring_on();
|
||||
when 'R' : ring_off();
|
||||
when 'O' : option();
|
||||
when 'c' : call();
|
||||
when '>' : after = FALSE; d_level();
|
||||
when '<' : after = FALSE; u_level();
|
||||
when '?' : after = FALSE; help();
|
||||
when '/' : after = FALSE; identify(0);
|
||||
when 's' : search();
|
||||
when 'z' : do_zap(FALSE);
|
||||
when 'p':
|
||||
if (get_dir())
|
||||
do_zap(TRUE);
|
||||
else
|
||||
after = FALSE;
|
||||
when 'v': msg("Super Rogue version %s.",release);
|
||||
when 'D': dip_it();
|
||||
when CTRL('L') : after = FALSE; restscr(cw);
|
||||
when CTRL('R') : after = FALSE; msg(huh);
|
||||
when 'a': after = FALSE; dispmax();
|
||||
when '@' : if (author())
|
||||
msg("Hero @ %d,%d : Stairs @ %d,%d",hero.y,hero.x,stairs.y,stairs.x);
|
||||
when 'S' :
|
||||
after = FALSE;
|
||||
if (save_game()) {
|
||||
wclear(cw);
|
||||
draw(cw);
|
||||
endwin();
|
||||
byebye(0);
|
||||
}
|
||||
when '.' : ; /* Rest command */
|
||||
when ' ' : after = FALSE; /* do nothing */
|
||||
when '=' :
|
||||
if (author()) {
|
||||
activity();
|
||||
after = FALSE;
|
||||
}
|
||||
when CTRL('P') :
|
||||
after = FALSE;
|
||||
if (wizard) {
|
||||
wizard = FALSE;
|
||||
msg("Not wizard any more");
|
||||
}
|
||||
else {
|
||||
wizard = passwd();
|
||||
if (wizard) {
|
||||
msg("Welcome back, Bob!!!!!");
|
||||
waswizard = TRUE;
|
||||
}
|
||||
else
|
||||
msg("Sorry");
|
||||
}
|
||||
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;
|
||||
if (wizard) switch (ch) {
|
||||
case CTRL('A') : ;
|
||||
when 'C' : create_obj(FALSE);
|
||||
when CTRL('I') : inventory(lvl_obj, 1);
|
||||
when CTRL('W') : whatis(NULL);
|
||||
when CTRL('D') : level++; new_level(NORMLEV);
|
||||
when CTRL('U') : if (level > 1) level--; new_level(NORMLEV);
|
||||
when CTRL('F') : displevl();
|
||||
when CTRL('X') : dispmons();
|
||||
when CTRL('T') : teleport(rndspot,&player);
|
||||
when CTRL('E') : msg("food left: %d", food_left);
|
||||
when CTRL('O') : add_pass();
|
||||
when 'M' : {
|
||||
int tlev, whichlev;
|
||||
prbuf[0] = '\0';
|
||||
msg("Which level? ");
|
||||
if (get_str(prbuf,cw) == NORM) {
|
||||
whichlev = NORMLEV;
|
||||
tlev = atoi(prbuf);
|
||||
if (tlev < 1)
|
||||
level = 1;
|
||||
if (tlev >= 200) {
|
||||
tlev -= 199;
|
||||
whichlev = MAZELEV;
|
||||
}
|
||||
else if (tlev >= 100) {
|
||||
tlev -= 99;
|
||||
whichlev = POSTLEV;
|
||||
}
|
||||
level = tlev;
|
||||
new_level(whichlev);
|
||||
}
|
||||
}
|
||||
when CTRL('N') : {
|
||||
struct linked_list *item;
|
||||
|
||||
item = get_item("charge", STICK);
|
||||
if (item != NULL) {
|
||||
(OBJPTR(item))->o_charges = 10000;
|
||||
msg("");
|
||||
}
|
||||
}
|
||||
when CTRL('H') : {
|
||||
int i;
|
||||
struct linked_list *item;
|
||||
struct object *obj;
|
||||
|
||||
him->s_exp = e_levels[him->s_lvl + 7] + 1;
|
||||
check_level();
|
||||
/*
|
||||
* Give the rogue a very good sword
|
||||
*/
|
||||
item = new_thing(FALSE, WEAPON, TWOSWORD);
|
||||
obj = OBJPTR(item);
|
||||
obj->o_hplus = 3;
|
||||
obj->o_dplus = 3;
|
||||
obj->o_flags = ISKNOW;
|
||||
i = add_pack(item, TRUE);
|
||||
if (i)
|
||||
cur_weapon = obj;
|
||||
else
|
||||
discard(item);
|
||||
/*
|
||||
* And his suit of armor
|
||||
*/
|
||||
item = new_thing(FALSE, ARMOR, PLATEARMOR);
|
||||
obj = OBJPTR(item);
|
||||
obj->o_ac = -8;
|
||||
obj->o_flags = ISKNOW;
|
||||
i = add_pack(item, TRUE);
|
||||
if (i)
|
||||
cur_armor = obj;
|
||||
else
|
||||
discard(item);
|
||||
nochange = FALSE;
|
||||
}
|
||||
otherwise:
|
||||
msg(illegal, unctrl(ch));
|
||||
count = 0;
|
||||
}
|
||||
else {
|
||||
msg(illegal, unctrl(ch));
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* turn off flags if no longer needed
|
||||
*/
|
||||
if (!running)
|
||||
door_stop = FALSE;
|
||||
}
|
||||
/*
|
||||
* If he ran into something to take, let the
|
||||
* hero pick it up if not in a trading post.
|
||||
*/
|
||||
if (take != 0 && levtype != POSTLEV)
|
||||
pick_up(take);
|
||||
if (!running)
|
||||
door_stop = FALSE;
|
||||
}
|
||||
/*
|
||||
* Kick off the rest if the daemons and fuses
|
||||
*/
|
||||
if (after) {
|
||||
int j;
|
||||
|
||||
look(FALSE);
|
||||
do_daemons(AFTER);
|
||||
do_fuses();
|
||||
if (pl_on(ISSLOW))
|
||||
waste_time();
|
||||
for (j = LEFT; j <= RIGHT; j++) {
|
||||
if (cur_ring[j] != NULL) {
|
||||
if (cur_ring[j]->o_which == R_SEARCH)
|
||||
search();
|
||||
else if (cur_ring[j]->o_which == R_TELEPORT)
|
||||
if (rnd(100) < 5)
|
||||
teleport(rndspot, &player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* quit:
|
||||
* Have player make certain, then exit.
|
||||
*/
|
||||
void
|
||||
quit(int a)
|
||||
{
|
||||
reg char ch, good;
|
||||
/*
|
||||
* Reset the signal in case we got here via an interrupt
|
||||
*/
|
||||
if (signal(SIGINT, quit) != quit)
|
||||
mpos = 0;
|
||||
msg("Really quit? [y/n/s]");
|
||||
/* ch = tolower(readchar());*/
|
||||
ch = readchar();
|
||||
if (ch == 'y') {
|
||||
clear();
|
||||
move(LINES-1, 0);
|
||||
refresh();
|
||||
score(purse, CHICKEN, 0);
|
||||
byebye(0);
|
||||
}
|
||||
else if (ch == 's') {
|
||||
good = save_game();
|
||||
if (good) {
|
||||
wclear(cw);
|
||||
draw(cw);
|
||||
endwin();
|
||||
byebye(0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
signal(SIGINT, quit);
|
||||
wmove(cw, 0, 0);
|
||||
wclrtoeol(cw);
|
||||
draw(cw);
|
||||
mpos = 0;
|
||||
count = 0;
|
||||
nochange = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* search:
|
||||
* Player gropes about him to find hidden things.
|
||||
*/
|
||||
|
||||
search()
|
||||
{
|
||||
reg int x, y;
|
||||
reg char ch;
|
||||
|
||||
/*
|
||||
* Look all around the hero, if there is something hidden there,
|
||||
* give him a chance to find it. If its found, display it.
|
||||
*/
|
||||
if (pl_on(ISBLIND))
|
||||
return;
|
||||
for (x = hero.x - 1; x <= hero.x + 1; x++) {
|
||||
for (y = hero.y - 1; y <= hero.y + 1; y++) {
|
||||
ch = winat(y, x);
|
||||
if (isatrap(ch)) { /* see if its a trap */
|
||||
reg struct trap *tp;
|
||||
|
||||
if ((tp = trap_at(y, x)) == NULL)
|
||||
break;
|
||||
if (tp->tr_flags & ISFOUND)
|
||||
break; /* no message if its seen */
|
||||
if (mvwinch(cw, y, x) == ch)
|
||||
break;
|
||||
if (rnd(100) > (him->s_lvl * 9 + herowis() * 5))
|
||||
break;
|
||||
tp->tr_flags |= ISFOUND;
|
||||
mvwaddch(cw, y, x, tp->tr_type);
|
||||
count = 0;
|
||||
running = FALSE;
|
||||
msg(tr_name(tp->tr_type));
|
||||
}
|
||||
else if(ch == SECRETDOOR) {
|
||||
if (rnd(100) < (him->s_lvl * 4 + herowis() * 5)) {
|
||||
mvaddch(y, x, DOOR);
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* help:
|
||||
* Give single character help, or the whole mess if he wants it
|
||||
*/
|
||||
help()
|
||||
{
|
||||
extern struct h_list helpstr[];
|
||||
reg struct h_list *strp;
|
||||
reg char helpch;
|
||||
reg int cnt;
|
||||
|
||||
strp = &helpstr[0];
|
||||
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) {
|
||||
msg("%s%s", unctrl(strp->h_ch), strp->h_desc);
|
||||
break;
|
||||
}
|
||||
strp++;
|
||||
}
|
||||
if (strp->h_ch != helpch)
|
||||
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);
|
||||
cnt++;
|
||||
strp++;
|
||||
}
|
||||
wmove(hw, LINES-1, 0);
|
||||
wprintw(hw,spacemsg);
|
||||
draw(hw);
|
||||
wait_for(hw,' ');
|
||||
wclear(hw);
|
||||
draw(hw);
|
||||
wmove(cw, 0, 0);
|
||||
wclrtoeol(cw);
|
||||
touchwin(cw);
|
||||
nochange = FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* identify:
|
||||
* Tell the player what a certain thing is.
|
||||
*/
|
||||
char *
|
||||
identify(what)
|
||||
int what;
|
||||
{
|
||||
reg char ch, *str;
|
||||
|
||||
if (what == 0) {
|
||||
msg("What do you want identified? ");
|
||||
ch = readchar();
|
||||
mpos = 0;
|
||||
if (ch == ESCAPE) {
|
||||
msg("");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
ch = what;
|
||||
if (isalpha(ch))
|
||||
str = monsters[midx(ch)].m_name;
|
||||
else {
|
||||
switch(ch) {
|
||||
case '|':
|
||||
case '-': str = "the wall of a room";
|
||||
when GOLD: str = "gold";
|
||||
when STAIRS: str = "passage leading up/down";
|
||||
when DOOR: str = "door";
|
||||
when FLOOR: str = "room floor";
|
||||
when PLAYER: str = "you";
|
||||
when PASSAGE: str = "passage";
|
||||
when POST: str = "trading post";
|
||||
when MAZETRAP: str = "maze trap";
|
||||
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 POOL: str = "magic pool";
|
||||
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 AMULET: str = "The Amulet of Yendor";
|
||||
when RING: str = "ring";
|
||||
when STICK: str = "wand or staff";
|
||||
otherwise:
|
||||
if (what == 0)
|
||||
str = "unknown character";
|
||||
else
|
||||
str = "a magical ghost";
|
||||
}
|
||||
}
|
||||
if (what == 0)
|
||||
msg("'%s' : %s", unctrl(ch), str);
|
||||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
* d_level:
|
||||
* He wants to go down a level
|
||||
*/
|
||||
d_level()
|
||||
{
|
||||
if (winat(hero.y, hero.x) != STAIRS)
|
||||
msg("I see no way down.");
|
||||
else {
|
||||
if (pl_on(ISHELD)) {
|
||||
msg("You are being held.");
|
||||
return;
|
||||
}
|
||||
level++;
|
||||
new_level(NORMLEV);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* u_level:
|
||||
* He wants to go up a level
|
||||
*/
|
||||
u_level()
|
||||
{
|
||||
if (winat(hero.y, hero.x) == STAIRS) {
|
||||
if (pl_on(ISHELD)) {
|
||||
msg("You are being held.");
|
||||
return;
|
||||
}
|
||||
else { /* player not held here */
|
||||
if (amulet) {
|
||||
level--;
|
||||
if (level == 0)
|
||||
total_winner();
|
||||
new_level(NORMLEV);
|
||||
msg("You feel a wrenching sensation in your gut.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
msg("I see no way up.");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Let him escape for a while
|
||||
*/
|
||||
shell()
|
||||
{
|
||||
reg int pid;
|
||||
reg char *sh;
|
||||
int ret_status;
|
||||
|
||||
/*
|
||||
* Set the terminal back to original mode
|
||||
*/
|
||||
sh = getenv("SHELL");
|
||||
wclear(hw);
|
||||
wmove(hw, LINES-1, 0);
|
||||
draw(hw);
|
||||
endwin();
|
||||
in_shell = TRUE;
|
||||
fflush(stdout);
|
||||
/*
|
||||
* Fork and do a shell
|
||||
*/
|
||||
#ifndef __DJGPP__
|
||||
while((pid = fork()) < 0)
|
||||
sleep(1);
|
||||
if (pid == 0) {
|
||||
setuid(playuid); /* Set back to original user */
|
||||
setgid(playgid);
|
||||
execl(sh == NULL ? "/bin/sh" : sh, "shell", "-i", 0);
|
||||
perror("No shelly");
|
||||
byebye(-1);
|
||||
}
|
||||
else {
|
||||
signal(SIGINT, SIG_IGN);
|
||||
signal(SIGQUIT, SIG_IGN);
|
||||
while (wait(&ret_status) != pid)
|
||||
continue;
|
||||
signal(SIGINT, quit);
|
||||
signal(SIGQUIT, endit);
|
||||
|
||||
#else
|
||||
{
|
||||
char shell[PATH_MAX];
|
||||
|
||||
if (sh && *sh)
|
||||
strncpy(shell,sh,PATH_MAX);
|
||||
else
|
||||
sprintf(shell, "%s\\bin\\sh.exe", getenv("DJDIR"));
|
||||
|
||||
if (spawnl(P_WAIT,shell, "shell", "-i", 0) == -1)
|
||||
msg("No shelly: %s", shell);
|
||||
|
||||
#endif
|
||||
printf("\n%s", retstr);
|
||||
fflush(stdout);
|
||||
noecho();
|
||||
crmode();
|
||||
in_shell = FALSE;
|
||||
wait_for(cw, '\n');
|
||||
restscr(cw);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* call:
|
||||
* Allow a user to call a potion, scroll, or ring something
|
||||
*/
|
||||
call()
|
||||
{
|
||||
reg struct object *obj;
|
||||
reg struct linked_list *item;
|
||||
reg char **guess, *elsewise;
|
||||
int wh;
|
||||
|
||||
if ((item = get_item("call", 0)) == NULL)
|
||||
return;
|
||||
obj = OBJPTR(item);
|
||||
wh = obj->o_which;
|
||||
switch (obj->o_type) {
|
||||
case RING:
|
||||
guess = r_guess;
|
||||
elsewise = (r_guess[wh] != NULL ? r_guess[wh] : r_stones[wh]);
|
||||
when POTION:
|
||||
guess = p_guess;
|
||||
elsewise = (p_guess[wh] != NULL ? p_guess[wh] : p_colors[wh]);
|
||||
when SCROLL:
|
||||
guess = s_guess;
|
||||
elsewise = (s_guess[wh] != NULL ? s_guess[wh] : s_names[wh]);
|
||||
when STICK:
|
||||
guess = ws_guess;
|
||||
elsewise =(ws_guess[wh] != NULL ?
|
||||
ws_guess[wh] : ws_stuff[wh].ws_made);
|
||||
otherwise:
|
||||
msg("You can't call %ss anything",obj->o_typname);
|
||||
return;
|
||||
}
|
||||
msg("Was called \"%s\"", elsewise);
|
||||
msg(callit);
|
||||
if (guess[wh] != NULL)
|
||||
free(guess[wh]);
|
||||
strcpy(prbuf, elsewise);
|
||||
if (get_str(prbuf, cw) == NORM) {
|
||||
guess[wh] = new(strlen(prbuf) + 1);
|
||||
strcpy(guess[wh], prbuf);
|
||||
}
|
||||
}
|
||||
130
srogue/cx.h
Normal file
130
srogue/cx.h
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sgtty.h>
|
||||
|
||||
#define bool char /* boolean variable */
|
||||
#define reg register /* register abbr. */
|
||||
|
||||
#define TRUE (1)
|
||||
#define FALSE (0)
|
||||
#define ERR (0) /* default return on error */
|
||||
#define OK (1) /* default return on good run */
|
||||
|
||||
#define _SUBWIN 01 /* window is a subwindow */
|
||||
#define _ENDLINE 02 /* lines go to end of screen */
|
||||
#define _FULLWIN 04 /* window is entire screen */
|
||||
#define _SCROLLWIN 010 /* window could cause scroll */
|
||||
#define _STANDOUT 0200 /* standout mode in effect */
|
||||
#define _NOCHANGE -1 /* no change on this line */
|
||||
|
||||
#define _puts(s) tputs(s, 0, _putchar);
|
||||
|
||||
typedef struct sgttyb SGTTY;
|
||||
|
||||
#ifndef WINDOW
|
||||
|
||||
#define WINDOW struct _win_st
|
||||
|
||||
/* window description structure */
|
||||
struct _win_st {
|
||||
short _cury, _curx; /* current y,x positions */
|
||||
short _maxy, _maxx; /* maximum y,x positions */
|
||||
short _begy, _begx; /* start y,x positions */
|
||||
short _flags; /* various window flags */
|
||||
bool _clear; /* need to clear */
|
||||
bool _leave; /* leave cur x,y at last update */
|
||||
bool _scroll; /* scrolls allowed */
|
||||
char **_y; /* actual window */
|
||||
short *_firstch; /* first change on line */
|
||||
short *_lastch; /* last change on line */
|
||||
};
|
||||
|
||||
extern bool My_term, /* user specied terminal */
|
||||
_echoit, /* set if echoing characters */
|
||||
_rawmode; /* set if terminal in raw mode */
|
||||
|
||||
extern char *Def_term, /* default terminal type */
|
||||
ttytype[]; /* long name of current term */
|
||||
# ifdef DEBUG
|
||||
extern FILE *outf; /* error outfile */
|
||||
# endif
|
||||
|
||||
extern int LINES, COLS; /* # of lines & columns */
|
||||
extern int _tty_ch; /* channel with tty on it */
|
||||
extern WINDOW *stdscr, *curscr;
|
||||
|
||||
static SGTTY _tty, _res_flg;
|
||||
|
||||
/*
|
||||
* Define VOID to stop lint from generating "null effect"
|
||||
* comments.
|
||||
*/
|
||||
# ifdef lint
|
||||
int __void__; /* place to assign to */
|
||||
|
||||
# define VOID(x) (__void__ = (int) (x))
|
||||
# else
|
||||
# define VOID(x) (x)
|
||||
# endif
|
||||
|
||||
# endif
|
||||
|
||||
/*
|
||||
* psuedo functions for standard screen
|
||||
*/
|
||||
#define addch(ch) VOID(waddch(stdscr, ch))
|
||||
#define getch() VOID(wgetch(stdscr))
|
||||
#define addstr(str) VOID(waddstr(stdscr, str))
|
||||
#define getstr(str) VOID(wgetstr(stdscr, str))
|
||||
#define move(y, x) VOID(wmove(stdscr, y, x))
|
||||
#define clear() VOID(wclear(stdscr))
|
||||
#define erase() VOID(werase(stdscr))
|
||||
#define clrtobot() VOID(wclrtobot(stdscr))
|
||||
#define clrtoeol() VOID(wclrtoeol(stdscr))
|
||||
#define insertln() VOID(winsertln(stdscr))
|
||||
#define deleteln() VOID(wdeleteln(stdscr))
|
||||
#define refresh() VOID(wrefresh(stdscr))
|
||||
#define inch() VOID(winch(stdscr))
|
||||
|
||||
#ifdef STANDOUT
|
||||
#define standout() VOID(wstandout(stdscr))
|
||||
#define standend() VOID(wstandend(stdscr))
|
||||
#endif
|
||||
|
||||
/*
|
||||
# define CBREAK FALSE
|
||||
# define _IOSTRG 01
|
||||
*/
|
||||
|
||||
/*
|
||||
* mv functions
|
||||
*/
|
||||
#define mvwaddch(win,y,x,ch) VOID(wmove(win,y,x)==ERR?ERR:waddch(win,ch))
|
||||
#define mvwgetch(win,y,x,ch) VOID(wmove(win,y,x)==ERR?ERR:wgetch(win,ch))
|
||||
#define mvwaddstr(win,y,x,str) VOID(wmove(win,y,x)==ERR?ERR:waddstr(win,str))
|
||||
#define mvwgetstr(win,y,x,str) VOID(wmove(win,y,x)==ERR?ERR:wgetstr(win,str))
|
||||
#define mvwinch(win,y,x) VOID(wmove(win,y,x) == ERR ? ERR : winch(win))
|
||||
#define mvaddch(y,x,ch) mvwaddch(stdscr,y,x,ch)
|
||||
#define mvgetch(y,x,ch) mvwgetch(stdscr,y,x,ch)
|
||||
#define mvaddstr(y,x,str) mvwaddstr(stdscr,y,x,str)
|
||||
#define mvgetstr(y,x,str) mvwgetstr(stdscr,y,x,str)
|
||||
#define mvinch(y,x) mvwinch(stdscr,y,x)
|
||||
|
||||
/*
|
||||
* psuedo functions
|
||||
*/
|
||||
|
||||
#define clearok(win,bf) (win->_clear = bf)
|
||||
#define leaveok(win,bf) (win->_leave = bf)
|
||||
#define scrollok(win,bf) (win->_scroll = bf)
|
||||
#define getyx(win,y,x) y = win->_cury, x = win->_curx
|
||||
#define winch(win) (win->_y[win->_cury][win->_curx])
|
||||
|
||||
WINDOW *initscr(), *newwin();
|
||||
177
srogue/daemon.c
Normal file
177
srogue/daemon.c
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* Contains functions for dealing with things that
|
||||
* happen in the future.
|
||||
*
|
||||
* @(#)daemon.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "rogue.h"
|
||||
#include "rogue.ext"
|
||||
|
||||
#define EMPTY 0
|
||||
#define DAEMON -1
|
||||
|
||||
#define _X_ { 0, 0, 0, 0 }
|
||||
|
||||
struct delayed_action d_list[MAXDAEMONS] = {
|
||||
_X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_,
|
||||
_X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_, _X_,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* d_insert:
|
||||
* Insert a function in the daemon list.
|
||||
*/
|
||||
struct delayed_action *
|
||||
d_insert(func, arg, type, time)
|
||||
int arg, type, time, (*func)();
|
||||
{
|
||||
reg struct delayed_action *dev;
|
||||
|
||||
if (demoncnt < MAXDAEMONS) {
|
||||
dev = &d_list[demoncnt];
|
||||
dev->d_type = type;
|
||||
dev->d_time = time;
|
||||
dev->d_func = func;
|
||||
dev->d_arg = arg;
|
||||
demoncnt += 1;
|
||||
return dev;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
d_delete(wire)
|
||||
struct delayed_action *wire;
|
||||
{
|
||||
reg struct delayed_action *d1, *d2;
|
||||
|
||||
for (d1 = d_list; d1 < &d_list[demoncnt]; d1++) {
|
||||
if (wire == d1) {
|
||||
for (d2 = d1 + 1; d2 < &d_list[demoncnt]; d2++)
|
||||
*d1++ = *d2;
|
||||
demoncnt -= 1;
|
||||
d1 = &d_list[demoncnt];
|
||||
d1->d_type = EMPTY;
|
||||
d1->d_func = EMPTY;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* find_slot:
|
||||
* Find a particular slot in the table
|
||||
*/
|
||||
struct delayed_action *
|
||||
find_slot(func)
|
||||
int (*func)();
|
||||
{
|
||||
reg struct delayed_action *dev;
|
||||
|
||||
for (dev = d_list; dev < &d_list[demoncnt]; 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)
|
||||
int arg, type, (*func)();
|
||||
{
|
||||
d_insert(func, arg, type, DAEMON);
|
||||
}
|
||||
|
||||
/*
|
||||
* do_daemons:
|
||||
* Run all the daemons that are active with the current
|
||||
* flag, passing the argument to the function.
|
||||
*/
|
||||
do_daemons(flag)
|
||||
int flag;
|
||||
{
|
||||
reg struct delayed_action *dev;
|
||||
|
||||
for (dev = d_list; dev < &d_list[demoncnt]; dev++)
|
||||
if (dev->d_type == flag && dev->d_time == DAEMON)
|
||||
(*dev->d_func)(dev->d_arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* fuse:
|
||||
* Start a fuse to go off in a certain number of turns
|
||||
*/
|
||||
fuse(func, arg, time)
|
||||
int (*func)(), arg, time;
|
||||
{
|
||||
d_insert(func, arg, AFTER, time);
|
||||
}
|
||||
|
||||
/*
|
||||
* lengthen:
|
||||
* Increase the time until a fuse goes off
|
||||
*/
|
||||
lengthen(func, xtime)
|
||||
int (*func)(), xtime;
|
||||
{
|
||||
reg struct delayed_action *wire;
|
||||
|
||||
for (wire = d_list; wire < &d_list[demoncnt]; wire++)
|
||||
if (wire->d_type != EMPTY && func == wire->d_func)
|
||||
wire->d_time += xtime;
|
||||
}
|
||||
|
||||
/*
|
||||
* extinguish:
|
||||
* Put out a fuse. Find all such fuses and kill them.
|
||||
*/
|
||||
extinguish(func)
|
||||
int (*func)();
|
||||
{
|
||||
reg struct delayed_action *dev;
|
||||
|
||||
for (dev = d_list; dev < &d_list[demoncnt]; dev++)
|
||||
if (dev->d_type != EMPTY && func == dev->d_func)
|
||||
d_delete(dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* do_fuses:
|
||||
* Decrement counters and start needed fuses
|
||||
*/
|
||||
do_fuses()
|
||||
{
|
||||
reg struct delayed_action *dev;
|
||||
|
||||
for (dev = d_list; dev < &d_list[demoncnt]; dev++) {
|
||||
if (dev->d_type == AFTER && dev->d_time > DAEMON) {
|
||||
if (--dev->d_time == 0) {
|
||||
(*dev->d_func)(dev->d_arg);
|
||||
d_delete(dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* activity:
|
||||
* Show wizard number of demaons and memory blocks used
|
||||
*/
|
||||
activity()
|
||||
{
|
||||
msg("Daemons = %d : Memory Items = %d : Memory Used = %d",
|
||||
demoncnt,total,sbrk(0));
|
||||
}
|
||||
254
srogue/daemons.c
Normal file
254
srogue/daemons.c
Normal file
|
|
@ -0,0 +1,254 @@
|
|||
/*
|
||||
* All the daemon and fuse functions are in here
|
||||
*
|
||||
* @(#)daemons.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "rogue.h"
|
||||
#include "rogue.ext"
|
||||
|
||||
int between = 0;
|
||||
|
||||
/*
|
||||
* doctor:
|
||||
* A healing daemon that restores hit points after rest
|
||||
*/
|
||||
doctor(fromfuse)
|
||||
int fromfuse;
|
||||
{
|
||||
reg int *thp, lv, ohp, ccon;
|
||||
|
||||
lv = him->s_lvl;
|
||||
thp = &him->s_hpt;
|
||||
ohp = *thp;
|
||||
quiet += 1;
|
||||
|
||||
ccon = him->s_ef.a_con;
|
||||
if (ccon > 16 && !isfight)
|
||||
*thp += rnd(ccon - 15);
|
||||
if (lv < 8) {
|
||||
if (quiet > 20 - lv * 2)
|
||||
*thp += 1;
|
||||
}
|
||||
else {
|
||||
if (quiet >= 3)
|
||||
*thp += rnd(lv - 7) + 1;
|
||||
}
|
||||
if (isring(LEFT, R_REGEN))
|
||||
*thp += 1;
|
||||
if (isring(RIGHT, R_REGEN))
|
||||
*thp += 1;
|
||||
if (pl_on(ISREGEN))
|
||||
*thp += 1;
|
||||
if (ohp != *thp) {
|
||||
nochange = FALSE;
|
||||
if (*thp > him->s_maxhp)
|
||||
*thp = him->s_maxhp;
|
||||
quiet = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Swander:
|
||||
* Called when it is time to start rolling for wandering monsters
|
||||
*/
|
||||
swander(fromfuse)
|
||||
int fromfuse;
|
||||
{
|
||||
daemon(rollwand, TRUE, BEFORE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* rollwand:
|
||||
* Called to roll to see if a wandering monster starts up
|
||||
*/
|
||||
rollwand(fromfuse)
|
||||
int fromfuse;
|
||||
{
|
||||
|
||||
if (++between >= 4) {
|
||||
if (roll(1, 6) == 4) {
|
||||
if (levtype != POSTLEV) /* no monsters for posts */
|
||||
wanderer();
|
||||
extinguish(rollwand);
|
||||
fuse(swander, TRUE, WANDERTIME);
|
||||
}
|
||||
between = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* unconfuse:
|
||||
* Release the poor player from his confusion
|
||||
*/
|
||||
unconfuse(fromfuse)
|
||||
int fromfuse;
|
||||
{
|
||||
if (pl_on(ISHUH))
|
||||
msg("You feel less confused now.");
|
||||
player.t_flags &= ~ISHUH;
|
||||
}
|
||||
|
||||
/*
|
||||
* unsee:
|
||||
* He lost his see invisible power
|
||||
*/
|
||||
unsee(fromfuse)
|
||||
int fromfuse;
|
||||
{
|
||||
player.t_flags &= ~CANSEE;
|
||||
}
|
||||
|
||||
/*
|
||||
* sight:
|
||||
* He gets his sight back
|
||||
*/
|
||||
sight(fromfuse)
|
||||
int fromfuse;
|
||||
{
|
||||
if (pl_on(ISBLIND))
|
||||
msg("The veil of darkness lifts.");
|
||||
player.t_flags &= ~ISBLIND;
|
||||
light(&hero);
|
||||
}
|
||||
|
||||
/*
|
||||
* nohaste:
|
||||
* End the hasting
|
||||
*/
|
||||
nohaste(fromfuse)
|
||||
int fromfuse;
|
||||
{
|
||||
if (pl_on(ISHASTE))
|
||||
msg("You feel yourself slowing down.");
|
||||
player.t_flags &= ~ISHASTE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* stomach:
|
||||
* Digest the hero's food
|
||||
*/
|
||||
stomach(fromfuse)
|
||||
int fromfuse;
|
||||
{
|
||||
reg int oldfood, old_hunger;
|
||||
|
||||
old_hunger = hungry_state;
|
||||
if (food_left <= 0) { /* the hero is fainting */
|
||||
if (--food_left == -150) {
|
||||
msg("Your stomach writhes with hunger pains.");
|
||||
}
|
||||
else if (food_left < -350) {
|
||||
msg("You starve to death !!");
|
||||
msg(" ");
|
||||
death(K_STARVE);
|
||||
}
|
||||
if (player.t_nocmd > 0 || rnd(100) > 20)
|
||||
return;
|
||||
player.t_nocmd = rnd(8)+4;
|
||||
msg("You faint.");
|
||||
running = FALSE;
|
||||
count = 0;
|
||||
hungry_state = F_FAINT;
|
||||
}
|
||||
else {
|
||||
oldfood = food_left;
|
||||
food_left -= ringfood + foodlev - amulet;
|
||||
if (player.t_nocmd > 0) /* wait till he can move */
|
||||
return;
|
||||
if (food_left < WEAKTIME && oldfood >= WEAKTIME) {
|
||||
msg("You are starting to feel weak.");
|
||||
hungry_state = F_WEAK;
|
||||
}
|
||||
else if(food_left < HUNGTIME && oldfood >= HUNGTIME) {
|
||||
msg("Getting hungry.");
|
||||
hungry_state = F_HUNGRY;
|
||||
}
|
||||
}
|
||||
if (old_hunger != hungry_state)
|
||||
updpack(); /* new pack weight */
|
||||
wghtchk(FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* noteth:
|
||||
* Hero is no longer etherereal
|
||||
*/
|
||||
noteth(fromfuse)
|
||||
int fromfuse;
|
||||
{
|
||||
int ch;
|
||||
|
||||
if (pl_on(ISETHER)) {
|
||||
msg("You begin to feel more corporeal.");
|
||||
ch = player.t_oldch;
|
||||
if (dead_end(ch)) {
|
||||
msg("You materialize in %s.",identify(ch));
|
||||
msg(" ");
|
||||
death(K_STONE); /* can't materialize in walls */
|
||||
}
|
||||
}
|
||||
player.t_flags &= ~ISETHER;
|
||||
}
|
||||
|
||||
/*
|
||||
* sapem:
|
||||
* Sap the hero's life away
|
||||
*/
|
||||
sapem(fromfuse)
|
||||
int fromfuse;
|
||||
{
|
||||
chg_abil(rnd(4) + 1, -1, TRUE);
|
||||
fuse(sapem, TRUE, 150);
|
||||
nochange = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* notslow:
|
||||
* Restore the hero's normal speed
|
||||
*/
|
||||
notslow(fromfuse)
|
||||
int fromfuse;
|
||||
{
|
||||
if (pl_on(ISSLOW))
|
||||
msg("You no longer feel hindered.");
|
||||
player.t_flags &= ~ISSLOW;
|
||||
}
|
||||
|
||||
/*
|
||||
* notregen:
|
||||
* Hero is no longer regenerative
|
||||
*/
|
||||
notregen(fromfuse)
|
||||
int fromfuse;
|
||||
{
|
||||
if (pl_on(ISREGEN))
|
||||
msg("You no longer feel bolstered.");
|
||||
player.t_flags &= ~ISREGEN;
|
||||
}
|
||||
|
||||
/*
|
||||
* notinvinc:
|
||||
* Hero not invincible any more
|
||||
*/
|
||||
notinvinc(fromfuse)
|
||||
int fromfuse;
|
||||
{
|
||||
if (pl_on(ISINVINC))
|
||||
msg("You no longer feel invincible.");
|
||||
player.t_flags &= ~ISINVINC;
|
||||
}
|
||||
199
srogue/disply.c
Normal file
199
srogue/disply.c
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
* various display routines and flag checking functions
|
||||
*
|
||||
* @(#)disply.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "rogue.h"
|
||||
#include <ctype.h>
|
||||
#include "rogue.ext"
|
||||
|
||||
/*
|
||||
* displevl:
|
||||
* Display detailed level for wizard and scroll
|
||||
*/
|
||||
displevl()
|
||||
{
|
||||
reg char ch, mch;
|
||||
reg int i,j;
|
||||
reg struct room *rp;
|
||||
|
||||
for (rp = rooms; rp < &rooms[MAXROOMS]; rp++)
|
||||
rp->r_flags &= ~ISDARK;
|
||||
|
||||
for (i = 0; i < LINES - 2; i++) {
|
||||
for (j = 0; j < COLS - 1; j++) {
|
||||
ch = mvinch(i,j);
|
||||
if (isatrap(ch)) {
|
||||
struct trap *what;
|
||||
|
||||
what = trap_at(i, j);
|
||||
if (what != NULL)
|
||||
what->tr_flags |= ISFOUND;
|
||||
}
|
||||
else if (ch == SECRETDOOR) {
|
||||
ch = DOOR;
|
||||
mvaddch(i, j, ch);
|
||||
}
|
||||
else if (illeg_ch(ch)) {
|
||||
ch = FLOOR;
|
||||
mvaddch(i, j, ch);
|
||||
}
|
||||
if (mvwinch(mw, i, j) != ' ') {
|
||||
struct linked_list *what;
|
||||
struct thing *it;
|
||||
|
||||
what = find_mons(i, j);
|
||||
if (what == NULL) {
|
||||
ch = FLOOR;
|
||||
mvaddch(i, j, ch);
|
||||
}
|
||||
else {
|
||||
it = THINGPTR(what);
|
||||
it->t_oldch = ch;
|
||||
}
|
||||
}
|
||||
mch = mvwinch(cw, i, j);
|
||||
if (isalpha(mch))
|
||||
ch = mch;
|
||||
mvwaddch(cw, i, j, ch);
|
||||
}
|
||||
}
|
||||
nochange = FALSE; /* display status again */
|
||||
draw(cw);
|
||||
}
|
||||
|
||||
/*
|
||||
* dispmons:
|
||||
* Show monsters for wizard and potion
|
||||
*/
|
||||
dispmons()
|
||||
{
|
||||
reg int ch, y, x;
|
||||
reg struct thing *it;
|
||||
reg struct linked_list *item;
|
||||
|
||||
for (item = mlist; item != NULL; item = next(item)) {
|
||||
it = THINGPTR(item);
|
||||
y = it->t_pos.y;
|
||||
x = it->t_pos.x;
|
||||
mvwaddch(cw, y, x, it->t_type);
|
||||
it->t_flags |= ISFOUND;
|
||||
if (it->t_type == 'M') /* if a mimic */
|
||||
it->t_disguise = 'M'; /* give it away */
|
||||
}
|
||||
draw(cw);
|
||||
}
|
||||
|
||||
/*
|
||||
* winat:
|
||||
* Get whatever character is at a location on the screen
|
||||
*/
|
||||
winat(y, x)
|
||||
int x, y;
|
||||
{
|
||||
reg char ch;
|
||||
|
||||
if (mvwinch(mw,y,x) == ' ')
|
||||
ch = mvinch(y, x); /* non-monsters */
|
||||
else
|
||||
ch = winch(mw); /* monsters */
|
||||
return ch;
|
||||
}
|
||||
|
||||
/*
|
||||
* cordok:
|
||||
* Returns TRUE if coordinate is on usable screen
|
||||
*/
|
||||
cordok(y, x)
|
||||
int y, x;
|
||||
{
|
||||
if (x < 0 || y < 0 || x >= COLS || y >= LINES - 1)
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* pl_on:
|
||||
* Returns TRUE if the player's flag is set
|
||||
*/
|
||||
pl_on(what)
|
||||
long what;
|
||||
{
|
||||
return (player.t_flags & what);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* pl_off:
|
||||
* Returns TRUE when player's flag is reset
|
||||
*/
|
||||
pl_off(what)
|
||||
long what;
|
||||
{
|
||||
return (!(player.t_flags & what));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* o_on:
|
||||
* Returns TRUE in the objects flag is set
|
||||
*/
|
||||
o_on(what,bit)
|
||||
struct object *what;
|
||||
long bit;
|
||||
{
|
||||
reg int flag;
|
||||
|
||||
flag = FALSE;
|
||||
if (what != NULL)
|
||||
flag = (what->o_flags & bit);
|
||||
return flag;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* o_off:
|
||||
* Returns TRUE is the objects flag is reset
|
||||
*/
|
||||
o_off(what,bit)
|
||||
struct object *what;
|
||||
long bit;
|
||||
{
|
||||
reg int flag;
|
||||
|
||||
flag = FALSE;
|
||||
if (what != NULL)
|
||||
flag = !(what->o_flags & bit);
|
||||
return flag;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* setoflg:
|
||||
* Set the specified flag for the object
|
||||
*/
|
||||
setoflg(what,bit)
|
||||
struct object *what;
|
||||
long bit;
|
||||
{
|
||||
what->o_flags |= bit;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* resoflg:
|
||||
* Reset the specified flag for the object
|
||||
*/
|
||||
resoflg(what,bit)
|
||||
struct object *what;
|
||||
long bit;
|
||||
{
|
||||
what->o_flags &= ~bit;
|
||||
}
|
||||
237
srogue/encumb.c
Normal file
237
srogue/encumb.c
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
/*
|
||||
* Stuff to do with encumberence
|
||||
*
|
||||
* @(#)encumb.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "rogue.h"
|
||||
#include "rogue.ext"
|
||||
|
||||
/*
|
||||
* updpack:
|
||||
* Update his pack weight and adjust fooduse accordingly
|
||||
*/
|
||||
updpack()
|
||||
{
|
||||
reg int topcarry, curcarry;
|
||||
|
||||
him->s_carry = totalenc(); /* get total encumb */
|
||||
curcarry = packweight(); /* get pack weight */
|
||||
topcarry = him->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 */
|
||||
him->s_pack = curcarry; /* update pack weight */
|
||||
packvol = pack_vol(); /* update pack volume */
|
||||
nochange = FALSE; /* also change display */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* packweight:
|
||||
* Get the total weight of the hero's pack
|
||||
*/
|
||||
packweight()
|
||||
{
|
||||
reg struct object *obj;
|
||||
reg struct linked_list *pc;
|
||||
reg int weight, i;
|
||||
|
||||
weight = 0;
|
||||
for (pc = pack ; pc != NULL ; pc = next(pc)) {
|
||||
obj = OBJPTR(pc);
|
||||
weight += itemweight(obj) * obj->o_count;
|
||||
}
|
||||
if (weight < 0) /* in case of amulet */
|
||||
weight = 0;
|
||||
for (i = LEFT; i <= RIGHT; i += 1) {
|
||||
obj = cur_ring[i];
|
||||
if (obj != NULL) {
|
||||
if (obj->o_type == R_HEAVY && o_off(obj, ISBLESS))
|
||||
weight += weight / 4;
|
||||
}
|
||||
}
|
||||
return weight;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* itemweight:
|
||||
* Get the weight of an object
|
||||
*/
|
||||
itemweight(wh)
|
||||
struct object *wh;
|
||||
{
|
||||
reg int weight;
|
||||
|
||||
weight = wh->o_weight; /* get base weight */
|
||||
switch (wh->o_type) {
|
||||
case ARMOR:
|
||||
if ((armors[wh->o_which].a_class - wh->o_ac) > 0)
|
||||
weight /= 2;
|
||||
when WEAPON:
|
||||
if ((wh->o_hplus + wh->o_dplus) > 0)
|
||||
weight /= 2;
|
||||
}
|
||||
if (o_on(wh,ISCURSED))
|
||||
weight += weight / 5; /* 20% more for cursed */
|
||||
if (o_on(wh, ISBLESS))
|
||||
weight -= weight / 5; /* 20% less for blessed */
|
||||
return weight;
|
||||
}
|
||||
|
||||
/*
|
||||
* pack_vol:
|
||||
* Get the total volume of the hero's pack
|
||||
*/
|
||||
pack_vol()
|
||||
{
|
||||
reg struct object *obj;
|
||||
reg struct linked_list *pc;
|
||||
reg int volume;
|
||||
|
||||
volume = 0;
|
||||
for (pc = pack ; pc != NULL ; pc = next(pc)) {
|
||||
obj = OBJPTR(pc);
|
||||
volume += itemvol(obj);
|
||||
}
|
||||
return volume;
|
||||
}
|
||||
|
||||
/*
|
||||
* itemvol:
|
||||
* Get the volume of an object
|
||||
*/
|
||||
itemvol(wh)
|
||||
struct object *wh;
|
||||
{
|
||||
reg int volume, what, extra;
|
||||
|
||||
extra = 0;
|
||||
what = getindex(wh->o_type);
|
||||
switch (wh->o_type) {
|
||||
case ARMOR: extra = armors[wh->o_which].a_vol;
|
||||
when WEAPON: extra = weaps[wh->o_which].w_vol;
|
||||
when STICK: if (strcmp(ws_stuff[wh->o_which].ws_type,"staff") == 0)
|
||||
extra = V_WS_STAFF;
|
||||
else
|
||||
extra = V_WS_WAND;
|
||||
}
|
||||
volume = thnginfo[what].mf_vol + extra;
|
||||
volume *= wh->o_count;
|
||||
return volume;
|
||||
}
|
||||
|
||||
/*
|
||||
* playenc:
|
||||
* Get hero's carrying ability above norm
|
||||
*/
|
||||
playenc()
|
||||
{
|
||||
reg estr = him->s_ef.a_str;
|
||||
if (estr >= 24)
|
||||
return 3000;
|
||||
switch(him->s_ef.a_str) {
|
||||
case 23: return 2000;
|
||||
case 22: return 1500;
|
||||
case 21: return 1250;
|
||||
case 20: return 1100;
|
||||
case 19: return 1000;
|
||||
case 18: return 700;
|
||||
case 17: return 500;
|
||||
case 16: return 350;
|
||||
case 15:
|
||||
case 14: return 200;
|
||||
case 13:
|
||||
case 12: return 100;
|
||||
case 11:
|
||||
case 10:
|
||||
case 9:
|
||||
case 8: return 0;
|
||||
case 7:
|
||||
case 6: return -150;
|
||||
case 5:
|
||||
case 4: return -250;
|
||||
}
|
||||
return -350;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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(fromfuse)
|
||||
int fromfuse;
|
||||
{
|
||||
reg int dropchk, err = TRUE;
|
||||
reg char ch;
|
||||
|
||||
inwhgt = TRUE;
|
||||
if (him->s_pack > him->s_carry) {
|
||||
ch = player.t_oldch;
|
||||
extinguish(wghtchk);
|
||||
if ((ch != FLOOR && ch != PASSAGE) || isfight) {
|
||||
fuse(wghtchk, TRUE, 1);
|
||||
inwhgt = FALSE;
|
||||
return;
|
||||
}
|
||||
msg("Your pack is too heavy for you.");
|
||||
do {
|
||||
dropchk = drop(NULL);
|
||||
if (dropchk == SOMTHERE)
|
||||
err = FALSE;
|
||||
else 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);
|
||||
}
|
||||
711
srogue/fight.c
Normal file
711
srogue/fight.c
Normal file
|
|
@ -0,0 +1,711 @@
|
|||
/*
|
||||
* All the fighting gets done here
|
||||
*
|
||||
* @(#)fight.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include "rogue.h"
|
||||
#include "rogue.ext"
|
||||
|
||||
|
||||
/*
|
||||
* fight:
|
||||
* The player attacks the monster.
|
||||
*/
|
||||
fight(mp, weap, thrown)
|
||||
struct coord *mp;
|
||||
struct object *weap;
|
||||
bool thrown;
|
||||
{
|
||||
|
||||
reg struct thing *tp;
|
||||
reg struct stats *st;
|
||||
reg struct linked_list *item;
|
||||
bool did_hit = TRUE;
|
||||
|
||||
if (pl_on(ISETHER)) /* cant fight when ethereal */
|
||||
return 0;
|
||||
|
||||
if ((item = find_mons(mp->y, mp->x)) == NULL) {
|
||||
mvaddch(mp->y, mp->x, FLOOR);
|
||||
mvwaddch(mw, mp->y, mp->x, ' ');
|
||||
look(FALSE);
|
||||
msg("That monster must have been an illusion.");
|
||||
return 0;
|
||||
}
|
||||
tp = THINGPTR(item);
|
||||
st = &tp->t_stats;
|
||||
/*
|
||||
* Since we are fighting, things are not quiet so
|
||||
* no healing takes place.
|
||||
*/
|
||||
quiet = 0;
|
||||
isfight = TRUE;
|
||||
runto(mp, &hero);
|
||||
/*
|
||||
* Let him know it was really a mimic (if it was one).
|
||||
*/
|
||||
if(tp->t_type == 'M' && tp->t_disguise != 'M' && pl_off(ISBLIND)) {
|
||||
msg("Wait! That's a mimic!");
|
||||
tp->t_disguise = 'M';
|
||||
did_hit = thrown;
|
||||
}
|
||||
if (did_hit) {
|
||||
reg char *mname;
|
||||
|
||||
did_hit = FALSE;
|
||||
if (pl_on(ISBLIND))
|
||||
mname = "it";
|
||||
else
|
||||
mname = monsters[tp->t_indx].m_name;
|
||||
/*
|
||||
* If the hero can see the invisibles, then
|
||||
* make it easier to hit.
|
||||
*/
|
||||
if (pl_on(CANSEE) && on(*tp, ISINVIS) && off(*tp, WASHIT)) {
|
||||
tp->t_flags |= WASHIT;
|
||||
st->s_arm += 3;
|
||||
}
|
||||
if (roll_em(him, st, weap, thrown)) {
|
||||
did_hit = TRUE;
|
||||
if (thrown)
|
||||
thunk(weap, mname);
|
||||
else
|
||||
hit(NULL);
|
||||
if (pl_on(CANHUH)) {
|
||||
msg("Your hands stop glowing red");
|
||||
msg("The %s appears confused.", mname);
|
||||
tp->t_flags |= ISHUH;
|
||||
player.t_flags &= ~CANHUH;
|
||||
/*
|
||||
* If our hero was stuck by a bone devil,
|
||||
* release him now because the devil is
|
||||
* confused.
|
||||
*/
|
||||
if (pl_on(ISHELD))
|
||||
unhold(tp->t_type);
|
||||
}
|
||||
if (st->s_hpt <= 0)
|
||||
killed(item, TRUE);
|
||||
else if (monhurt(tp) && off(*tp, ISWOUND)) {
|
||||
if (levtype != MAZELEV && tp->t_room != NULL &&
|
||||
!rf_on(tp->t_room, ISTREAS)) {
|
||||
tp->t_flags |= ISWOUND;
|
||||
msg("You wounded %s.",prname(mname,FALSE));
|
||||
unhold(tp->t_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (thrown)
|
||||
bounce(weap, mname);
|
||||
else
|
||||
miss(NULL);
|
||||
}
|
||||
}
|
||||
count = 0;
|
||||
return did_hit;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* attack:
|
||||
* The monster attacks the player
|
||||
*/
|
||||
attack(mp)
|
||||
struct thing *mp;
|
||||
{
|
||||
reg char *mname;
|
||||
|
||||
if (pl_on(ISETHER)) /* ethereal players cant be hit */
|
||||
return(0);
|
||||
if (mp->t_flags & ISPARA) /* paralyzed monsters */
|
||||
return(0);
|
||||
running = FALSE;
|
||||
quiet = 0;
|
||||
isfight = TRUE;
|
||||
if (mp->t_type == 'M' && pl_off(ISBLIND))
|
||||
mp->t_disguise = 'M';
|
||||
if (pl_on(ISBLIND))
|
||||
mname = "it";
|
||||
else
|
||||
mname = monsters[mp->t_indx].m_name;
|
||||
if (roll_em(&mp->t_stats, him, NULL, FALSE)) {
|
||||
if (pl_on(ISINVINC)) {
|
||||
msg("%s does not harm you.",prname(mname,TRUE));
|
||||
}
|
||||
else {
|
||||
nochange = FALSE;
|
||||
if (mp->t_type != 'E')
|
||||
hit(mname);
|
||||
if (him->s_hpt <= 0)
|
||||
death(mp->t_indx);
|
||||
if (off(*mp, ISCANC))
|
||||
switch (mp->t_type) {
|
||||
case 'R':
|
||||
if (hurt_armor(cur_armor)) {
|
||||
msg("Your armor weakens.");
|
||||
cur_armor->o_ac++;
|
||||
}
|
||||
when 'E':
|
||||
/*
|
||||
* The gaze of the floating eye hypnotizes you
|
||||
*/
|
||||
if (pl_off(ISBLIND) && player.t_nocmd <= 0) {
|
||||
player.t_nocmd = rnd(16) + 25;
|
||||
msg("You are transfixed.");
|
||||
}
|
||||
when 'Q':
|
||||
if (!save(VS_POISON) && !iswearing(R_SUSAB)) {
|
||||
if (him->s_ef.a_dex > MINABIL) {
|
||||
chg_abil(DEX, -1, TRUE);
|
||||
msg("You feel less agile.");
|
||||
}
|
||||
}
|
||||
when 'A':
|
||||
if (!save(VS_POISON) && herostr() > MINABIL) {
|
||||
if (!iswearing(R_SUSTSTR) && !iswearing(R_SUSAB)) {
|
||||
if (levcount > 0) {
|
||||
chg_abil(STR, -1, TRUE);
|
||||
msg("A sting has weakened you");
|
||||
}
|
||||
}
|
||||
else
|
||||
msg("Sting has no effect.");
|
||||
}
|
||||
when 'W':
|
||||
if (rnd(100) < 15 && !iswearing(R_SUSAB)) {
|
||||
if (him->s_exp <= 0)
|
||||
death(mp->t_indx);
|
||||
msg("You suddenly feel weaker.");
|
||||
if (--him->s_lvl == 0) {
|
||||
him->s_exp = 0;
|
||||
him->s_lvl = 1;
|
||||
}
|
||||
else
|
||||
him->s_exp = e_levels[him->s_lvl - 1] + 1;
|
||||
chg_hpt(-roll(1,10),TRUE,mp->t_indx);
|
||||
}
|
||||
when 'F':
|
||||
player.t_flags |= ISHELD;
|
||||
sprintf(monsters[midx('F')].m_stats.s_dmg,"%dd1",++fung_hit);
|
||||
when 'L': {
|
||||
long lastpurse;
|
||||
struct linked_list *lep;
|
||||
|
||||
lastpurse = purse;
|
||||
purse -= GOLDCALC;
|
||||
if (!save(VS_MAGIC))
|
||||
purse -= GOLDCALC + GOLDCALC + GOLDCALC + GOLDCALC;
|
||||
if (purse < 0)
|
||||
purse = 0;
|
||||
if (purse != lastpurse)
|
||||
msg("Your purse feels lighter.");
|
||||
lep = find_mons(mp->t_pos.y,mp->t_pos.x);
|
||||
if (lep != NULL)
|
||||
{
|
||||
remove_monster(&mp->t_pos, lep);
|
||||
mp = NULL;
|
||||
}
|
||||
}
|
||||
when 'N': {
|
||||
struct linked_list *steal, *list;
|
||||
struct object *sobj;
|
||||
int stworth = 0, wo;
|
||||
|
||||
/*
|
||||
* Nymph's steal a magic item, look through the pack
|
||||
* and pick out one we like, namely the object worth
|
||||
* the most bucks.
|
||||
*/
|
||||
steal = NULL;
|
||||
for (list = pack; list != NULL; list = next(list)) {
|
||||
wo = get_worth(OBJPTR(list));
|
||||
if (wo > stworth) {
|
||||
stworth = wo;
|
||||
steal = list;
|
||||
}
|
||||
}
|
||||
if (steal != NULL) {
|
||||
sobj = OBJPTR(steal);
|
||||
if (o_off(sobj, ISPROT)) {
|
||||
struct linked_list *nym;
|
||||
|
||||
nym = find_mons(mp->t_pos.y, mp->t_pos.x);
|
||||
if (nym != NULL)
|
||||
{
|
||||
remove_monster(&mp->t_pos, nym);
|
||||
mp = NULL;
|
||||
}
|
||||
msg("She stole %s!", inv_name(sobj, TRUE));
|
||||
detach(pack, steal);
|
||||
discard(steal);
|
||||
cur_null(sobj);
|
||||
updpack();
|
||||
}
|
||||
}
|
||||
}
|
||||
when 'c':
|
||||
if (!save(VS_PETRIFICATION)) {
|
||||
msg("Your body begins to solidify.");
|
||||
msg("You are turned to stone !!! --More--");
|
||||
wait_for(cw, ' ');
|
||||
death(mp->t_indx);
|
||||
}
|
||||
when 'd':
|
||||
if (rnd(100) < 50 && !(mp->t_flags & ISHUH))
|
||||
player.t_flags |= ISHELD;
|
||||
if (!save(VS_POISON)) {
|
||||
if (iswearing(R_SUSAB) || iswearing(R_SUSTSTR))
|
||||
msg("Sting has no effect.");
|
||||
else {
|
||||
int fewer, ostr;
|
||||
|
||||
fewer = roll(1,4);
|
||||
ostr = herostr();
|
||||
chg_abil(STR,-fewer,TRUE);
|
||||
if (herostr() < ostr) {
|
||||
fewer = ostr - herostr();
|
||||
fuse(rchg_str, fewer - 1, 10);
|
||||
}
|
||||
msg("You feel weaker now.");
|
||||
}
|
||||
}
|
||||
when 'g':
|
||||
if (!save(VS_BREATH) && !iswearing(R_BREATH)) {
|
||||
msg("You feel singed.");
|
||||
chg_hpt(-roll(1,8),FALSE,mp->t_indx);
|
||||
}
|
||||
when 'h':
|
||||
if (!save(VS_BREATH) && !iswearing(R_BREATH)) {
|
||||
msg("You are seared.");
|
||||
chg_hpt(-roll(1,4),FALSE,mp->t_indx);
|
||||
}
|
||||
when 'p':
|
||||
if (!save(VS_POISON) && herostr() > MINABIL) {
|
||||
if (!iswearing(R_SUSTSTR) && !iswearing(R_SUSAB)) {
|
||||
msg("You are gnawed.");
|
||||
chg_abil(STR,-1,TRUE);
|
||||
}
|
||||
}
|
||||
when 'u':
|
||||
if (!save(VS_POISON) && herostr() > MINABIL) {
|
||||
if (!iswearing(R_SUSTSTR) && !iswearing(R_SUSAB)) {
|
||||
msg("You are bitten.");
|
||||
chg_abil(STR, -1, TRUE);
|
||||
fuse(rchg_str, 1, roll(5,10));
|
||||
}
|
||||
}
|
||||
when 'w':
|
||||
if (!save(VS_POISON) && !iswearing(R_SUSAB)) {
|
||||
msg("You feel devitalized.");
|
||||
chg_hpt(-1,TRUE,mp->t_indx);
|
||||
}
|
||||
when 'i':
|
||||
if (!save(VS_PARALYZATION) && !iswearing(R_SUSAB)) {
|
||||
if (pl_on(ISSLOW))
|
||||
lengthen(notslow,roll(3,10));
|
||||
else {
|
||||
msg("You feel impaired.");
|
||||
player.t_flags |= ISSLOW;
|
||||
fuse(notslow,TRUE,roll(5,10));
|
||||
}
|
||||
}
|
||||
otherwise:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (mp->t_type != 'E') {
|
||||
if (mp->t_type == 'F') {
|
||||
him->s_hpt -= fung_hit;
|
||||
if (him->s_hpt <= 0)
|
||||
death(mp->t_indx);
|
||||
}
|
||||
miss(mname);
|
||||
}
|
||||
flushinp(); /* flush type ahead */
|
||||
count = 0;
|
||||
|
||||
if (mp == NULL)
|
||||
return(-1);
|
||||
else
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* swing:
|
||||
* Returns true if the swing hits
|
||||
*/
|
||||
swing(at_lvl, op_arm, wplus)
|
||||
int at_lvl, op_arm, wplus;
|
||||
{
|
||||
reg int res = rnd(20)+1;
|
||||
reg int need = (21 - at_lvl) - op_arm;
|
||||
|
||||
return (res + wplus >= need);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* check_level:
|
||||
* Check to see if the guy has gone up a level.
|
||||
*/
|
||||
check_level()
|
||||
{
|
||||
reg int lev, add, dif;
|
||||
|
||||
for (lev = 0; e_levels[lev] != 0; lev++)
|
||||
if (e_levels[lev] > him->s_exp)
|
||||
break;
|
||||
lev += 1;
|
||||
if (lev > him->s_lvl) {
|
||||
dif = lev - him->s_lvl;
|
||||
add = roll(dif, 10) + (dif * getpcon(him));
|
||||
him->s_maxhp += add;
|
||||
if ((him->s_hpt += add) > him->s_maxhp)
|
||||
him->s_hpt = him->s_maxhp;
|
||||
msg("Welcome to level %d", lev);
|
||||
}
|
||||
him->s_lvl = lev;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* roll_em:
|
||||
* Roll several attacks
|
||||
*/
|
||||
roll_em(att, def, weap, hurl)
|
||||
struct stats *att, *def;
|
||||
struct object *weap;
|
||||
bool hurl;
|
||||
{
|
||||
reg char *cp;
|
||||
reg int ndice, nsides, def_arm, prop_hplus, prop_dplus;
|
||||
reg bool did_hit = FALSE;
|
||||
char *mindex();
|
||||
|
||||
prop_hplus = prop_dplus = 0;
|
||||
if (weap == NULL) {
|
||||
cp = att->s_dmg;
|
||||
}
|
||||
else if (hurl) {
|
||||
if (o_on(weap,ISMISL) && cur_weapon != NULL &&
|
||||
cur_weapon->o_which == weap->o_launch) {
|
||||
cp = weap->o_hurldmg;
|
||||
prop_hplus = cur_weapon->o_hplus;
|
||||
prop_dplus = cur_weapon->o_dplus;
|
||||
}
|
||||
else
|
||||
cp = (o_on(weap,ISMISL) ? weap->o_damage : weap->o_hurldmg);
|
||||
}
|
||||
else {
|
||||
cp = weap->o_damage;
|
||||
/*
|
||||
* Drain a staff of striking
|
||||
*/
|
||||
if (weap->o_type == STICK && weap->o_which == WS_HIT
|
||||
&& weap->o_charges == 0) {
|
||||
strcpy(weap->o_damage, "0d0");
|
||||
weap->o_hplus = weap->o_dplus = 0;
|
||||
}
|
||||
}
|
||||
while(1) {
|
||||
int damage;
|
||||
int hplus = prop_hplus + (weap == NULL ? 0 : weap->o_hplus);
|
||||
int dplus = prop_dplus + (weap == NULL ? 0 : weap->o_dplus);
|
||||
|
||||
if (att == him && weap == cur_weapon) {
|
||||
if (isring(LEFT, R_ADDDAM))
|
||||
dplus += cur_ring[LEFT]->o_ac;
|
||||
else if (isring(LEFT, R_ADDHIT))
|
||||
hplus += cur_ring[LEFT]->o_ac;
|
||||
if (isring(RIGHT, R_ADDDAM))
|
||||
dplus += cur_ring[RIGHT]->o_ac;
|
||||
else if (isring(RIGHT, R_ADDHIT))
|
||||
hplus += cur_ring[RIGHT]->o_ac;
|
||||
}
|
||||
ndice = atoi(cp);
|
||||
if ((cp = mindex(cp, 'd')) == NULL)
|
||||
break;
|
||||
nsides = atoi(++cp);
|
||||
|
||||
if (def == him) { /* defender is hero */
|
||||
if (cur_armor != NULL)
|
||||
def_arm = cur_armor->o_ac;
|
||||
else
|
||||
def_arm = def->s_arm;
|
||||
if (isring(LEFT, R_PROTECT))
|
||||
def_arm -= cur_ring[LEFT]->o_ac;
|
||||
if (isring(RIGHT, R_PROTECT))
|
||||
def_arm -= cur_ring[RIGHT]->o_ac;
|
||||
}
|
||||
else /* defender is monster */
|
||||
def_arm = def->s_arm;
|
||||
if (hurl)
|
||||
hplus += getpdex(att,TRUE);
|
||||
if (swing(att->s_lvl, def_arm + getpdex(def, FALSE),
|
||||
hplus + str_plus(att))) {
|
||||
reg int proll;
|
||||
|
||||
proll = roll(ndice, nsides);
|
||||
damage = dplus + proll + add_dam(att);
|
||||
if (pl_off(ISINVINC) || def != him)
|
||||
def->s_hpt -= max(0, damage);
|
||||
did_hit = TRUE;
|
||||
}
|
||||
if ((cp = mindex(cp, '/')) == NULL)
|
||||
break;
|
||||
cp++;
|
||||
}
|
||||
return did_hit;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* mindex:
|
||||
* Look for char 'c' in string pointed to by 'cp'
|
||||
*/
|
||||
char *
|
||||
mindex(cp, c)
|
||||
char *cp, c;
|
||||
{
|
||||
reg int i;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
if (*cp != c) cp++;
|
||||
if (*cp == c)
|
||||
return cp;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* prname:
|
||||
* The print name of a combatant
|
||||
*/
|
||||
char *
|
||||
prname(who, upper)
|
||||
char *who;
|
||||
bool upper;
|
||||
{
|
||||
static char tbuf[LINLEN];
|
||||
|
||||
*tbuf = '\0';
|
||||
if (who == 0)
|
||||
strcpy(tbuf, "you");
|
||||
else if (pl_on(ISBLIND))
|
||||
strcpy(tbuf, "it");
|
||||
else {
|
||||
strcpy(tbuf, "the ");
|
||||
strcat(tbuf, who);
|
||||
}
|
||||
if (upper)
|
||||
*tbuf = toupper(*tbuf);
|
||||
return tbuf;
|
||||
}
|
||||
|
||||
/*
|
||||
* hit:
|
||||
* Print a message to indicate a succesful hit
|
||||
*/
|
||||
hit(er)
|
||||
char *er;
|
||||
{
|
||||
msg("%s hit.",prname(er, TRUE));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* miss:
|
||||
* Print a message to indicate a poor swing
|
||||
*/
|
||||
miss(er)
|
||||
char *er;
|
||||
{
|
||||
msg("%s miss%s.",prname(er, TRUE),(er == 0 ? "":"es"));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* save_throw:
|
||||
* See if a creature saves against something
|
||||
*/
|
||||
save_throw(which, tp)
|
||||
int which;
|
||||
struct thing *tp;
|
||||
{
|
||||
reg int need;
|
||||
reg struct stats *st;
|
||||
|
||||
st = &tp->t_stats;
|
||||
need = 14 + which - (st->s_lvl / 2) - getpwis(st);
|
||||
return (roll(1, 20) >= need);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* save:
|
||||
* See if he saves against various nasty things
|
||||
*/
|
||||
save(which)
|
||||
int which;
|
||||
{
|
||||
return save_throw(which, &player);
|
||||
}
|
||||
|
||||
/*
|
||||
* raise_level:
|
||||
* The guy just magically went up a level.
|
||||
*/
|
||||
raise_level()
|
||||
{
|
||||
him->s_exp = e_levels[him->s_lvl-1] + 1L;
|
||||
check_level();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* thunk:
|
||||
* A missile hits a monster
|
||||
*/
|
||||
thunk(weap, mname)
|
||||
struct object *weap;
|
||||
char *mname;
|
||||
{
|
||||
if (weap->o_type == WEAPON)
|
||||
msg("The %s hits the %s.",w_magic[weap->o_which].mi_name,mname);
|
||||
else
|
||||
msg("You hit the %s.", mname);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* bounce:
|
||||
* A missile misses a monster
|
||||
*/
|
||||
bounce(weap, mname)
|
||||
struct object *weap;
|
||||
char *mname;
|
||||
{
|
||||
if (weap->o_type == WEAPON)
|
||||
msg("The %s misses the %s.", w_magic[weap->o_which].mi_name,mname);
|
||||
else
|
||||
msg("You missed the %s.", mname);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* remove:
|
||||
* Remove a monster from the screen
|
||||
*/
|
||||
remove_monster(mp, item)
|
||||
struct coord *mp;
|
||||
struct linked_list *item;
|
||||
{
|
||||
reg char what;
|
||||
|
||||
mvwaddch(mw, mp->y, mp->x, ' ');
|
||||
if (pl_on(ISBLIND))
|
||||
what = ' '; /* if blind, then a blank */
|
||||
else
|
||||
what = (THINGPTR(item))->t_oldch; /* normal char */
|
||||
mvwaddch(cw, mp->y, mp->x, what);
|
||||
detach(mlist, item);
|
||||
discard(item);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* is_magic:
|
||||
* Returns true if an object radiates magic
|
||||
*/
|
||||
is_magic(obj)
|
||||
struct object *obj;
|
||||
{
|
||||
switch (obj->o_type) {
|
||||
case ARMOR:
|
||||
return obj->o_ac != armors[obj->o_which].a_class;
|
||||
case WEAPON:
|
||||
return obj->o_hplus != 0 || obj->o_dplus != 0;
|
||||
case POTION:
|
||||
case SCROLL:
|
||||
case STICK:
|
||||
case RING:
|
||||
case AMULET:
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* killed:
|
||||
* Called to put a monster to death
|
||||
*/
|
||||
killed(item, pr)
|
||||
struct linked_list *item;
|
||||
bool pr;
|
||||
{
|
||||
reg struct thing *tp;
|
||||
reg struct object *obj;
|
||||
struct linked_list *pitem, *nexti, *itspack;
|
||||
struct coord here;
|
||||
|
||||
nochange = FALSE;
|
||||
tp = THINGPTR(item);
|
||||
here = tp->t_pos;
|
||||
if (pr) {
|
||||
addmsg("Defeated ");
|
||||
if (pl_on(ISBLIND))
|
||||
msg("it.");
|
||||
else
|
||||
msg("%s.", monsters[tp->t_indx].m_name);
|
||||
}
|
||||
him->s_exp += tp->t_stats.s_exp;
|
||||
isfight = FALSE;
|
||||
check_level();
|
||||
unhold(tp->t_type); /* free player if held */
|
||||
if (tp->t_type == 'L') {
|
||||
reg struct room *rp;
|
||||
|
||||
rp = roomin(&here);
|
||||
if (rp != NULL) {
|
||||
if (rp->r_goldval!=0 || fallpos(&here, &rp->r_gold, FALSE)) {
|
||||
rp->r_goldval += GOLDCALC;
|
||||
if (!save_throw(VS_MAGIC,tp))
|
||||
rp->r_goldval += GOLDCALC + GOLDCALC + GOLDCALC
|
||||
+ GOLDCALC + GOLDCALC;
|
||||
mvaddch(rp->r_gold.y, rp->r_gold.x, GOLD);
|
||||
if (!rf_on(rp,ISDARK)) {
|
||||
light(&hero);
|
||||
mvwaddch(cw, hero.y, hero.x, PLAYER);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pitem = tp->t_pack;
|
||||
itspack = tp->t_pack;
|
||||
remove_monster(&here, item);
|
||||
while (pitem != NULL) {
|
||||
nexti = next(pitem);
|
||||
obj = OBJPTR(pitem);
|
||||
obj->o_pos = here;
|
||||
detach(itspack, pitem);
|
||||
fall(pitem, FALSE);
|
||||
pitem = nexti;
|
||||
}
|
||||
}
|
||||
446
srogue/global.c
Normal file
446
srogue/global.c
Normal file
|
|
@ -0,0 +1,446 @@
|
|||
/*
|
||||
* global variable declaration
|
||||
*
|
||||
* @(#)global.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "rogue.h"
|
||||
|
||||
struct room rooms[MAXROOMS]; /* One for each room -- A level */
|
||||
struct room *oldrp; /* Roomin(&oldpos) */
|
||||
struct linked_list *mlist = NULL; /* monsters on this level */
|
||||
struct thing player; /* The rogue */
|
||||
struct stats max_stats; /* The maximum for the player */
|
||||
struct linked_list *lvl_obj = NULL; /* objects on this level */
|
||||
struct object *cur_weapon = NULL; /* Which weapon he is weilding */
|
||||
struct object *cur_armor = NULL; /* the rogue's armor */
|
||||
struct object *cur_ring[2]; /* Which rings are being worn */
|
||||
struct stats *him; /* pointer to hero stats */
|
||||
struct trap traps[MAXTRAPS]; /* traps on this level */
|
||||
|
||||
int playuid; /* uid of current player */
|
||||
int playgid; /* gid of current player */
|
||||
int level = 1; /* What level rogue is on */
|
||||
int levcount = 0; /* # of active mons this level */
|
||||
int levtype = NORMLEV; /* type of level this is, maze, etc. */
|
||||
int trader = 0; /* no. of purchases */
|
||||
int curprice = -1; /* current price of item */
|
||||
int purse = 0; /* How much gold the rogue has */
|
||||
int mpos = 0; /* Where cursor is on top line */
|
||||
int ntraps; /* # of traps on this level */
|
||||
int packvol = 0; /* volume of things in pack */
|
||||
int total = 0; /* Total dynamic memory bytes */
|
||||
int demoncnt = 0; /* number of active daemons */
|
||||
int lastscore = -1; /* Score before this turn */
|
||||
int no_food = 0; /* # of levels without food */
|
||||
int seed; /* Random number seed */
|
||||
int dnum; /* Dungeon number */
|
||||
int count = 0; /* # of times to repeat cmd */
|
||||
int fung_hit = 0; /* # of time fungi has hit */
|
||||
int quiet = 0; /* # of quiet turns */
|
||||
int max_level = 1; /* Deepest player has gone */
|
||||
int food_left = HUNGERTIME; /* Amount of food stomach */
|
||||
int group = NEWGROUP; /* Current group number */
|
||||
int hungry_state = F_OKAY; /* How hungry is he */
|
||||
int foodlev = 1; /* how fast he eats food */
|
||||
int ringfood = 0; /* rings affect on food consumption */
|
||||
char take; /* Thing the rogue is taking */
|
||||
char runch; /* Direction player is running */
|
||||
char curpurch[15]; /* name of item ready to buy */
|
||||
|
||||
char prbuf[LINLEN]; /* Buffer for sprintfs */
|
||||
char whoami[LINLEN]; /* Name of player */
|
||||
char fruit[LINLEN]; /* Favorite fruit */
|
||||
char huh[LINLEN]; /* The last message printed */
|
||||
char file_name[LINLEN]; /* Save file name */
|
||||
char scorefile[LINLEN]; /* place for scorefile */
|
||||
char home[LINLEN]; /* User's home directory */
|
||||
char outbuf[BUFSIZ]; /* Output buffer for stdout */
|
||||
|
||||
char *s_guess[MAXSCROLLS]; /* his guess at what scroll is */
|
||||
char *p_guess[MAXPOTIONS]; /* his guess at what potion is */
|
||||
char *r_guess[MAXRINGS]; /* his guess at what ring is */
|
||||
char *ws_guess[MAXSTICKS]; /* his guess at what wand is */
|
||||
|
||||
bool isfight = FALSE; /* true if player is fighting */
|
||||
bool nlmove = FALSE; /* true when transported to new level */
|
||||
bool inpool = FALSE; /* true if hero standing in pool */
|
||||
bool inwhgt = FALSE; /* true if from wghtchk() */
|
||||
bool running = FALSE; /* True if player is running */
|
||||
bool playing = TRUE; /* True until he quits */
|
||||
bool wizard = FALSE; /* True if he is a wizard */
|
||||
bool after = TRUE; /* True if we want after daemons */
|
||||
bool door_stop = FALSE; /* Stop run when we pass a door */
|
||||
bool firstmove = FALSE; /* First move after door_stop */
|
||||
bool waswizard = FALSE; /* Was a wizard sometime */
|
||||
bool amulet = FALSE; /* He found the amulet */
|
||||
bool in_shell = FALSE; /* True if executing a shell */
|
||||
bool nochange = FALSE; /* true if last stat same as now */
|
||||
|
||||
bool s_know[MAXSCROLLS]; /* Does he know about a scroll */
|
||||
bool p_know[MAXPOTIONS]; /* Does he know about a potion */
|
||||
bool r_know[MAXRINGS]; /* Does he know about a ring */
|
||||
bool ws_know[MAXSTICKS]; /* Does he know about a stick */
|
||||
|
||||
char spacemsg[] = { "-- Press space to continue --" };
|
||||
char morestr[] = { "-- More --" };
|
||||
char retstr[] = { "[Press return to continue]" };
|
||||
char wizstr[] = { "Wizards Password: " };
|
||||
char illegal[] = { "Illegal command '%s'." };
|
||||
char callit[] = { "Call it: " };
|
||||
char starlist[] = { " (* for a list)" };
|
||||
|
||||
struct coord oldpos; /* Pos before last look() call */
|
||||
struct coord delta; /* Change indicated to get_dir() */
|
||||
struct coord stairs; /* where the stairs are put */
|
||||
struct coord rndspot = { -1, -1 }; /* for random teleporting */
|
||||
|
||||
struct monster *mtlev[MONRANGE];
|
||||
|
||||
#define _r {10,10,10,10} /* real ability (unused) */
|
||||
#define _p 0,0,0,0 /* hit points, pack, carry (unused) */
|
||||
#define _c 10 /* constitution (unused) */
|
||||
|
||||
/*
|
||||
* NAME SHOW CARRY {LEVEL} FLAGS _r {STR DEX WIS _c} EXP LVL ARM _p DMG
|
||||
*/
|
||||
struct monster monsters[MAXMONS + 1] = {
|
||||
{"giant ant",'A',0,{3,12,1},ISMEAN,{_r,{10,16,5,_c},10,2,3,_p,"1d6"}},
|
||||
{"bat",'B',0,{1,6,1},ISHUH,{_r,{10,10,10,_c},1,1,3,_p,"1d2"}},
|
||||
{"centaur",'C',15,{8,17,1},0,{_r,{16,10,15,_c},15,4,4,_p,"1d6/1d6"}},
|
||||
{"red dragon",'D',100,{21,500,0},ISGREED,{_r,{17,10,17,_c},9000,11,-1,_p,"1d8/1d8/3d10"}},
|
||||
{"floating eye",'E',0,{2,11,0},0,{_r,{10,10,10,_c},5,1,9,_p,"0d0"}},
|
||||
{"violet fungi",'F',0,{15,24,0},ISMEAN|ISSTUCK,{_r,{10,5,3,_c},85,8,2,_p,"000d0"}},
|
||||
{"gnome",'G',10,{6,15,1},0,{_r,{10,10,11,_c},8,1,5,_p,"1d6"}},
|
||||
{"hobgoblin",'H',0,{1,8,1},ISMEAN,{_r,{10,10,10,_c},3,1,5,_p,"1d8"}},
|
||||
{"invisible stalker",'I',0,{16,25,1},ISINVIS|ISHUH,{_r,{10,15,15,_c},120,8,2,_p,"4d4"}},
|
||||
{"jackal",'J',0,{1,6,1},ISMEAN,{_r,{10,10,10,_c},2,1,7,_p,"1d2"}},
|
||||
{"kobold",'K',0,{1,6,1},ISMEAN,{_r,{10,10,10,_c},1,1,8,_p,"1d4"}},
|
||||
{"leprechaun",'L',0,{7,16,0},0,{_r,{10,15,16,_c},10,3,8,_p,"1d1"}},
|
||||
{"mimic",'M',30,{19,500,0},0,{_r,{10,10,10,_c},140,8,7,_p,"3d4"}},
|
||||
{"nymph",'N',100,{11,20,0},0,{_r,{10,18,18,_c},40,3,9,_p,"0d0"}},
|
||||
{"orc",'O',15,{4,13,1},0,{_r,{10,10,10,10},5,1,6,_p,"1d8"}},
|
||||
{"purple worm",'P',70,{22,500,0},0,{_r,{18,5,10,_c},7000,15,6,_p,"2d12/2d4"}},
|
||||
{"quasit",'Q',30,{10,19,1},ISMEAN,{_r,{10,15,16,_c},35,3,2,_p,"1d2/1d2/1d4"}},
|
||||
{"rust monster",'R',0,{9,18,1},ISMEAN,{_r,{10,10,10,_c},25,5,2,_p,"0d0/0d0"}},
|
||||
{"snake",'S',0,{1,7,1},ISMEAN,{_r,{10,10,10,_c},3,1,5,_p,"1d3"}},
|
||||
{"troll",'T',50,{13,22,0},ISMEAN|ISREGEN,{_r,{10,10,11,_c},55,6,4,_p,"1d8/1d8/2d6"}},
|
||||
{"umber hulk",'U',40,{18,500,1},ISMEAN,{_r,{17,10,10,_c},130,8,2,_p,"3d4/3d4/2d5"}},
|
||||
{"vampire",'V',20,{20,500,1},ISMEAN|ISREGEN,{_r,{21,16,16,_c},380,8,1,_p,"1d10"}},
|
||||
{"wraith",'W',0,{14,23,1},ISMEAN,{_r,{10,10,10,_c},55,5,4,_p,"1d6"}},
|
||||
{"xorn",'X',0,{17,26,1},ISMEAN,{_r,{17,6,11,_c},120,7,-2,_p,"1d3/1d3/1d3/4d6"}},
|
||||
{"yeti",'Y',30,{12,21,1},ISMEAN,{_r,{10,10,10,_c},50,4,6,_p,"1d6/1d6"}},
|
||||
{"zombie",'Z',0,{5,14,1},ISMEAN,{_r,{10,10,10,_c},7,2,8,_p,"1d8"}},
|
||||
{"anhkheg",'a',10,{7,16,1},ISMEAN,{_r,{10,15,3,_c},20,3,2,_p,"3d6"}},
|
||||
{"giant beetle",'b',0,{9,18,1},ISMEAN,{_r,{10,15,10,_c},30,5,3,_p,"4d4"}},
|
||||
{"cockatrice",'c',100,{8,17,0},0,{_r,{10,10,11,_c},200,5,6,_p,"1d3"}},
|
||||
{"bone devil",'d',0,{27,500,1},ISMEAN,{_r,{18,10,16,_c},8000,12,-1,_p,"5d4"}},
|
||||
{"elasmosaurus",'e',0,{28,500,1},ISMEAN,{_r,{17,5,3,_c},4500,12,7,_p,"4d6"}},
|
||||
{"killer frog",'f',0,{3,8,1},ISMEAN,{_r,{10,10,10,_c},4,3,8,_p,"2d3/1d4"}},
|
||||
{"green dragon",'g',50,{25,500,1},0,{_r,{18,10,18,_c},7500,10,2,_p,"1d6/1d6/2d10"}},
|
||||
{"hell hound",'h',20,{10,19,1},ISMEAN,{_r,{10,15,10,_c},30,5,4,_p,"1d10"}},
|
||||
{"imp",'i',20,{2,9,1},ISMEAN|ISREGEN,{_r,{10,14,11,_c},6,2,1,_p,"1d4"}},
|
||||
{"jaguar",'j',0,{10,19,0},0,{_r,{10,10,11,_c},25,8,6,_p,"2d3/2d5"}},
|
||||
{"koppleganger",'k',20,{8,17,1},ISMEAN,{_r,{10,10,16,_c},35,4,5,_p,"1d12"}},
|
||||
{"lonchu",'l',15,{2,9,1},ISMEAN,{_r,{10,4,18,_c},5,2,1,_p,"1d4/1d4"}},
|
||||
{"minotaur",'m',0,{12,21,1},ISMEAN,{_r,{10,10,11,_c},40,8,6,_p,"1d3/2d4"}},
|
||||
{"neotyugh",'n',10,{14,23,1},ISMEAN,{_r,{10,6,4,_c},50,6,3,_p,"1d8/1d8/2d3"}},
|
||||
{"ogre",'o',50,{7,16,1},0,{_r,{20,10,10,_c},15,4,5,_p,"2d6"}},
|
||||
{"pseudo dragon",'p',50,{9,18,1},0,{_r,{10,10,16,_c},20,4,2,_p,"2d3/1d6"}},
|
||||
{"quellit",'q',85,{30,500,1},0,{_r,{17,10,10,_c},12500,17,0,_p,"2d10/2d6"}},
|
||||
{"rhynosphinx",'r',40,{26,500,0},0,{_r,{19,6,18,_c},5000,13,-1,_p,"2d10/2d8"}},
|
||||
{"shadow",'s',15,{5,14,1},ISMEAN|ISREGEN|ISINVIS,{_r,{10,17,18,_c},6,3,5,_p,"1d6"}},
|
||||
{"titanothere",'t',0,{19,500,0},0,{_r,{17,6,3,_c},750,14,6,_p,"2d8/1d6"}},
|
||||
{"ulodyte",'u',10,{2,8,1},ISMEAN,{_r,{10,10,10,_c},3,2,5,_p,"1d3/1d3"}},
|
||||
{"vrock",'v',0,{4,13,1},ISMEAN,{_r,{10,10,11,_c},8,3,2,_p,"1d4/1d6"}},
|
||||
{"wuccubi",'w',0,{14,23,1},ISMEAN,{_r,{10,10,10,_c},90,6,0,_p,"1d4/1d10"}},
|
||||
{"xonoclon",'x',0,{20,500,0},0,{_r,{19,10,4,_c},1750,14,0,_p,"3d8"}},
|
||||
{"yeenoghu",'y',10,{15,24,1},ISMEAN,{_r,{17,15,10,_c},250,8,1,_p,"3d6"}},
|
||||
{"zemure",'z',0,{1,6,1},ISMEAN|ISREGEN,{_r,{10,10,10,_c},4,2,7,_p,"1d4"}},
|
||||
{"devil Asmodeus",'A',-1,{1,500,1},ISMEAN|ISREGEN,{_r,{24,18,18,_c},500000,40,-10,_p,"4d10/4d10"}},
|
||||
};
|
||||
|
||||
#undef _p /* erase these definitions */
|
||||
#undef _c
|
||||
#undef _r
|
||||
|
||||
struct h_list helpstr[] = {
|
||||
'?', " prints help",
|
||||
'/', " identify object",
|
||||
'h', " left",
|
||||
'j', " down",
|
||||
'k', " up",
|
||||
'l', " right",
|
||||
'y', " up & left",
|
||||
'u', " up & right",
|
||||
'b', " down & left",
|
||||
'n', " down & right",
|
||||
'H', " run left",
|
||||
'J', " run down",
|
||||
'K', " run up",
|
||||
'L', " run right",
|
||||
'Y', " run up & left",
|
||||
'U', " run up & right",
|
||||
'B', " run down & left",
|
||||
'N', " run down & right",
|
||||
't', "<dir> throw something",
|
||||
'f', "<dir> forward until find something",
|
||||
'p', "<dir> zap a wand in a direction",
|
||||
'z', " zap a wand or staff",
|
||||
'>', " go down a staircase",
|
||||
's', " search for trap/secret door",
|
||||
'.', " (dot) rest for a while",
|
||||
'i', " inventory pack",
|
||||
'I', " inventory single item",
|
||||
'q', " quaff potion",
|
||||
'r', " read a scroll",
|
||||
'e', " eat food",
|
||||
'w', " wield a weapon",
|
||||
'W', " wear armor",
|
||||
'T', " take armor off",
|
||||
'P', " put on ring",
|
||||
'R', " remove ring",
|
||||
'd', " drop object",
|
||||
'c', " call object",
|
||||
'O', " examine/set options",
|
||||
'a', " display maximum stats",
|
||||
'D', " dip object in pool",
|
||||
CTRL('L')," redraw screen",
|
||||
ESCAPE, " cancel command",
|
||||
'!', " shell escape",
|
||||
'S', " save game",
|
||||
'Q', " quit",
|
||||
0, 0
|
||||
};
|
||||
|
||||
char *s_names[MAXSCROLLS]; /* Names of the scrolls */
|
||||
char *p_colors[MAXPOTIONS]; /* Colors of the potions */
|
||||
char *r_stones[MAXRINGS]; /* Stone settings of the rings */
|
||||
struct rod ws_stuff[MAXSTICKS]; /* Stuff for sticks */
|
||||
|
||||
struct magic_item things[NUMTHINGS + 1] = {
|
||||
{ "potion", 257, 5, },
|
||||
{ "scroll", 250, 30, },
|
||||
{ "food", 185, 7, },
|
||||
{ "weapon", 92, 0, },
|
||||
{ "armor", 92, 0, },
|
||||
{ "ring", 62, 5, },
|
||||
{ "stick", 62, 0, },
|
||||
{ "amulet", 0, -250, },
|
||||
{ NULL, 0, 0, },
|
||||
};
|
||||
|
||||
struct magic_item a_magic[MAXARMORS + 1] = {
|
||||
{ "leather armor", 170, 5 },
|
||||
{ "ring mail", 130, 30 },
|
||||
{ "studded leather armor", 130, 20 },
|
||||
{ "scale mail", 120, 3 },
|
||||
{ "padded armor", 100, 250 },
|
||||
{ "chain mail", 90, 75 },
|
||||
{ "splint mail", 90, 80 },
|
||||
{ "banded mail", 90, 90 },
|
||||
{ "plate mail", 50, 400 },
|
||||
{ "plate armor", 30, 650 },
|
||||
{ NULL, 0, 0 },
|
||||
};
|
||||
struct init_armor armors[MAXARMORS] = {
|
||||
{ 8, 150, 500, },
|
||||
{ 7, 250, 650, },
|
||||
{ 7, 200, 550, },
|
||||
{ 6, 400, 900, },
|
||||
{ 6, 100, 450, },
|
||||
{ 5, 300, 650, },
|
||||
{ 4, 400, 700, },
|
||||
{ 4, 350, 600, },
|
||||
{ 3, 450, 950, },
|
||||
{ 2, 350, 750, },
|
||||
};
|
||||
struct magic_item w_magic[MAXWEAPONS + 1] = {
|
||||
{ "mace", 70, 25 },
|
||||
{ "long sword", 70, 60 },
|
||||
{ "short bow", 60, 150 },
|
||||
{ "arrow", 60, 2 },
|
||||
{ "dagger", 20, 5 },
|
||||
{ "rock", 20, 1 },
|
||||
{ "two-handed sword", 50, 120 },
|
||||
{ "sling", 20, 5 },
|
||||
{ "dart", 30, 3 },
|
||||
{ "crossbow", 60, 70 },
|
||||
{ "crossbow bolt", 60, 3 },
|
||||
{ "spear", 70, 8 },
|
||||
{ "trident", 70, 90 },
|
||||
{ "spetum", 70, 50 },
|
||||
{ "bardiche", 70, 30 },
|
||||
{ "pike", 70, 75 },
|
||||
{ "bastard sword", 60, 100 },
|
||||
{ "halberd", 70, 40 },
|
||||
{ NULL, 0, 0 },
|
||||
};
|
||||
|
||||
struct init_weps weaps[MAXWEAPONS] = {
|
||||
{ "2d4", "1d3", 0, 100, 300, NONE },
|
||||
{ "1d10", "1d2", 0, 60, 180, NONE },
|
||||
{ "1d1", "1d1", 0, 40, 190, NONE },
|
||||
{ "1d1", "1d6", ISMANY|ISMISL, 5, 8, BOW },
|
||||
{ "1d6", "1d4", ISMISL, 10, 30, NONE },
|
||||
{ "1d2", "1d4", ISMANY|ISMISL, 5, 10, SLING },
|
||||
{ "3d6", "1d2", 0, 250, 550, NONE },
|
||||
{ "0d0", "0d0", 0, 5, 7, NONE },
|
||||
{ "1d1", "1d3", ISMANY|ISMISL, 5, 5, NONE },
|
||||
{ "1d1", "1d1", 0, 100, 250, NONE },
|
||||
{ "1d2", "1d10", ISMANY|ISMISL, 7, 11, CROSSBOW },
|
||||
{ "1d8", "1d6", ISMISL, 50, 200, NONE },
|
||||
{ "3d4", "1d4", 0, 50, 220, NONE },
|
||||
{ "2d5", "1d3", 0, 50, 200, NONE },
|
||||
{ "3d3", "1d2", 0, 125, 270, NONE },
|
||||
{ "1d12", "1d8", 0, 80, 260, NONE },
|
||||
{ "2d7", "1d2", 0, 100, 400, NONE },
|
||||
{ "2d6", "1d3", 0, 175, 370, NONE },
|
||||
};
|
||||
|
||||
struct magic_item s_magic[MAXSCROLLS + 1] = {
|
||||
{ "monster confusion", 50, 200 },
|
||||
{ "magic mapping", 52, 200 },
|
||||
{ "light", 80, 100 },
|
||||
{ "hold monster", 25, 200 },
|
||||
{ "sleep", 41, 50 },
|
||||
{ "enchant armor", 75, 175 },
|
||||
{ "identify", 211, 150 },
|
||||
{ "scare monster", 42, 300 },
|
||||
{ "gold detection", 32, 100 },
|
||||
{ "teleportation", 73, 200 },
|
||||
{ "enchant weapon", 91, 175 },
|
||||
{ "create monster", 34, 75 },
|
||||
{ "remove curse", 82, 100 },
|
||||
{ "aggravate monsters", 10, 50 },
|
||||
{ "blank paper", 11, 50 },
|
||||
{ "genocide", 5, 350 },
|
||||
{ "item knowledge", 14, 250 },
|
||||
{ "item protection", 9, 250 },
|
||||
{ "demons curse", 5, 25 },
|
||||
{ "transport", 11, 100 },
|
||||
{ "enchantment", 3, 300 },
|
||||
{ "gods blessing", 4, 450 },
|
||||
{ "aquirement", 3, 450 },
|
||||
{ "banishment", 5, 25 },
|
||||
{ "recharge wand", 14, 250 },
|
||||
{ "locate traps", 18, 185 },
|
||||
{ NULL, 0, 0 },
|
||||
};
|
||||
|
||||
struct magic_item p_magic[MAXPOTIONS + 1] = {
|
||||
{ "confusion", 69, 50 },
|
||||
{ "paralysis", 69, 50 },
|
||||
{ "poison", 55, 50 },
|
||||
{ "gain strength", 130, 150 },
|
||||
{ "see invisible", 25, 175 },
|
||||
{ "healing", 120, 130 },
|
||||
{ "monster detection", 59, 120 },
|
||||
{ "magic detection", 54, 105 },
|
||||
{ "raise level", 25, 300 },
|
||||
{ "extra healing", 52, 175 },
|
||||
{ "haste self", 41, 200 },
|
||||
{ "restore strength", 140, 200 },
|
||||
{ "blindness", 25, 50 },
|
||||
{ "thirst quenching", 10, 50 },
|
||||
{ "increase dexterity", 50, 175 },
|
||||
{ "etherealness", 20, 150 },
|
||||
{ "increase wisdom", 35, 175 },
|
||||
{ "regeneration", 10, 175 },
|
||||
{ "super ability", 3, 500 },
|
||||
{ "decrepedness", 4, 25 },
|
||||
{ "invincibility", 4, 500 },
|
||||
{ NULL, 0, 0 },
|
||||
};
|
||||
|
||||
struct magic_item r_magic[MAXRINGS + 1] = {
|
||||
{ "protection", 71, 200 },
|
||||
{ "strength", 70, 200 },
|
||||
{ "sustain strength", 45, 250 },
|
||||
{ "searching", 70, 150 },
|
||||
{ "see invisible", 77, 175 },
|
||||
{ "constitution", 13, 350 },
|
||||
{ "aggravate monster", 60, 100 },
|
||||
{ "agility", 75, 250 },
|
||||
{ "increase damage", 61, 250 },
|
||||
{ "regeneration", 41, 250 },
|
||||
{ "digestion", 60, 225 },
|
||||
{ "teleportation", 60, 100 },
|
||||
{ "stealth", 75, 200 },
|
||||
{ "speed", 40, 225 },
|
||||
{ "find traps", 27, 200 },
|
||||
{ "delusion", 18, 100 },
|
||||
{ "sustain ability", 9, 450 },
|
||||
{ "blindness", 10, 50 },
|
||||
{ "lethargy", 14, 75 },
|
||||
{ "ogre strength", 8, 350 },
|
||||
{ "enfeeblement", 5, 25 },
|
||||
{ "burden", 10, 50 },
|
||||
{ "illumination", 16, 100 },
|
||||
{ "fire protection", 5, 225 },
|
||||
{ "wisdom", 25, 200 },
|
||||
{ "dexterity", 35, 200 },
|
||||
{ NULL, 0, 0 },
|
||||
};
|
||||
|
||||
struct magic_item ws_magic[MAXSTICKS + 1] = {
|
||||
{ "light", 95, 120 },
|
||||
{ "striking", 75, 115 },
|
||||
{ "lightning", 30, 200 },
|
||||
{ "fire", 30, 200 },
|
||||
{ "cold", 30, 200 },
|
||||
{ "polymorph", 95, 210 },
|
||||
{ "magic missile", 70, 170 },
|
||||
{ "haste monster", 80, 50 },
|
||||
{ "slow monster", 90, 220 },
|
||||
{ "drain life", 80, 210 },
|
||||
{ "nothing", 10, 70 },
|
||||
{ "teleport away", 55, 140 },
|
||||
{ "teleport to", 50, 60 },
|
||||
{ "cancellation", 55, 130 },
|
||||
{ "sap life", 20, 50 },
|
||||
{ "curing", 25, 250 },
|
||||
{ "pyromania", 15, 25 },
|
||||
{ "annihilate monster", 5, 750 },
|
||||
{ "paralyze monster", 10, 650 },
|
||||
{ "food absorption", 10, 75 },
|
||||
{ "regenerate monster", 15, 25 },
|
||||
{ "hide monster", 10, 50 },
|
||||
{ "anti-matter", 5, 25 },
|
||||
{ "clone monster", 10, 10 },
|
||||
{ "confuse monster", 15, 150 },
|
||||
{ "degenerate monster", 15, 150 },
|
||||
{ NULL, 0, 0 },
|
||||
};
|
||||
|
||||
struct magic_info thnginfo[NUMTHINGS] = {
|
||||
{ MAXPOTIONS, V_POTION, POTION, p_magic, },
|
||||
{ MAXSCROLLS, V_SCROLL, SCROLL, s_magic, },
|
||||
{ MAXFOODS, V_FOOD, FOOD, NULL, },
|
||||
{ MAXWEAPONS, V_WEAPON, WEAPON, w_magic, },
|
||||
{ MAXARMORS, V_ARMOR, ARMOR, a_magic, },
|
||||
{ MAXRINGS, V_RING, RING, r_magic, },
|
||||
{ MAXSTICKS, V_STICK, STICK, ws_magic, },
|
||||
{ MAXAMULETS, V_AMULET, AMULET, NULL, },
|
||||
};
|
||||
|
||||
long e_levels[] = {
|
||||
10L,20L,40L,80L,160L,320L,640L,1280L,2560L,5120L,10240L,20480L,
|
||||
40920L, 81920L, 163840L, 327680L, 655360L, 1310720L, 2621440L,
|
||||
3932160L, 5242880L, 7864320L, 10485760L, 15728640L, 20971520L,
|
||||
41943040L, 83886080L, 167772160L, 335544320L, 0L,
|
||||
};
|
||||
|
||||
WINDOW *cw; /* what the hero sees */
|
||||
WINDOW *hw; /* utility window */
|
||||
WINDOW *mw; /* monster window */
|
||||
338
srogue/init.c
Normal file
338
srogue/init.c
Normal file
|
|
@ -0,0 +1,338 @@
|
|||
/*
|
||||
* initializate various things
|
||||
*
|
||||
* @(#)init.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include "rogue.h"
|
||||
#include "rogue.ext"
|
||||
|
||||
char *rainbow[NCOLORS] = {
|
||||
"Red", "Blue", "Green", "Yellow",
|
||||
"Black", "Brown", "Orange", "Pink",
|
||||
"Purple", "Grey", "White", "Silver",
|
||||
"Gold", "Violet", "Clear", "Vermilion",
|
||||
"Ecru", "Turquoise","Magenta", "Amber",
|
||||
"Topaz", "Plaid", "Tan", "Tangerine",
|
||||
"Aquamarine", "Scarlet","Khaki", "Crimson",
|
||||
"Indigo", "Beige", "Lavender", "Saffron",
|
||||
};
|
||||
|
||||
char *sylls[NSYLS] = {
|
||||
"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[] = {
|
||||
"Agate", "Alexandrite", "Amethyst",
|
||||
"Azurite", "Carnelian", "Chrysoberyl",
|
||||
"Chrysoprase", "Citrine", "Diamond",
|
||||
"Emerald", "Garnet", "Hematite",
|
||||
"Jacinth", "Jade", "Kryptonite",
|
||||
"Lapus lazuli", "Malachite", "Moonstone",
|
||||
"Obsidian", "Olivine", "Onyx",
|
||||
"Opal", "Pearl", "Peridot",
|
||||
"Quartz", "Rhodochrosite","Ruby",
|
||||
"Sapphire", "Sardonyx", "Serpintine",
|
||||
"Spinel", "Tiger eye", "Topaz",
|
||||
"Tourmaline", "Turquoise",
|
||||
};
|
||||
|
||||
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", "Steel",
|
||||
"Tin", "Titanium", "Zinc",
|
||||
};
|
||||
|
||||
/*
|
||||
* init_everything:
|
||||
* Set up all important stuff.
|
||||
*/
|
||||
init_everything()
|
||||
{
|
||||
init_player(); /* Roll up the rogue */
|
||||
init_things(); /* Set up probabilities */
|
||||
init_names(); /* Set up names of scrolls */
|
||||
init_colors(); /* Set up colors of potions */
|
||||
init_stones(); /* Set up stones in rings */
|
||||
init_materials(); /* Set up materials of wands */
|
||||
}
|
||||
|
||||
/*
|
||||
* init_things:
|
||||
* Initialize the probabilities for types of things
|
||||
*/
|
||||
init_things()
|
||||
{
|
||||
struct magic_item *mi;
|
||||
|
||||
/*
|
||||
* init general things
|
||||
*/
|
||||
for (mi = &things[1]; mi < &things[NUMTHINGS]; mi++)
|
||||
mi->mi_prob += (mi-1)->mi_prob;
|
||||
badcheck("things", things);
|
||||
/*
|
||||
* init armor things
|
||||
*/
|
||||
for (mi = &a_magic[1]; mi < &a_magic[MAXARMORS]; mi++)
|
||||
mi->mi_prob += (mi-1)->mi_prob;
|
||||
badcheck("armor", a_magic);
|
||||
/*
|
||||
* init weapon stuff
|
||||
*/
|
||||
for (mi = &w_magic[1]; mi < &w_magic[MAXWEAPONS]; mi++)
|
||||
mi->mi_prob += (mi-1)->mi_prob;
|
||||
badcheck("weapon", w_magic);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* init_colors:
|
||||
* Initialize the potion color scheme for this time
|
||||
*/
|
||||
init_colors()
|
||||
{
|
||||
reg int i, j;
|
||||
reg char *str;
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* init_names:
|
||||
* Generate the names of the various scrolls
|
||||
*/
|
||||
init_names()
|
||||
{
|
||||
reg int nsyl;
|
||||
reg char *cp, *sp;
|
||||
reg int i, nwords;
|
||||
|
||||
for (i = 0; i < MAXSCROLLS; i++) {
|
||||
cp = prbuf;
|
||||
nwords = rnd(3)+1;
|
||||
while(nwords--) {
|
||||
nsyl = rnd(3)+2;
|
||||
while(nsyl--) {
|
||||
sp = sylls[rnd(NSYLS)];
|
||||
while(*sp)
|
||||
*cp++ = *sp++;
|
||||
}
|
||||
*cp++ = ' ';
|
||||
}
|
||||
*--cp = '\0';
|
||||
s_names[i] = 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);
|
||||
}
|
||||
|
||||
/*
|
||||
* init_stones:
|
||||
* Initialize the ring stone setting scheme for this time
|
||||
*/
|
||||
|
||||
init_stones()
|
||||
{
|
||||
reg int i, j;
|
||||
reg char *str;
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* init_materials:
|
||||
* Initialize the construction materials for wands and staffs
|
||||
*/
|
||||
|
||||
init_materials()
|
||||
{
|
||||
int i, j;
|
||||
char *str;
|
||||
struct rod *rd;
|
||||
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++) {
|
||||
rd = &ws_stuff[i];
|
||||
for (;;) {
|
||||
if (rnd(100) > 50) {
|
||||
j = rnd(NMETAL);
|
||||
if (!metused[j]) {
|
||||
str = metal[j];
|
||||
rd->ws_type = "wand";
|
||||
rd->ws_vol = V_WS_WAND;
|
||||
rd->ws_wght = W_WS_WAND;
|
||||
metused[j] = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
j = rnd(NWOOD);
|
||||
if (!woodused[j]) {
|
||||
str = wood[j];
|
||||
rd->ws_type = "staff";
|
||||
rd->ws_vol = V_WS_STAFF;
|
||||
rd->ws_wght = W_WS_WAND;
|
||||
woodused[j] = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ws_stuff[i].ws_made = 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);
|
||||
}
|
||||
|
||||
badcheck(name, magic)
|
||||
char *name;
|
||||
struct magic_item *magic;
|
||||
{
|
||||
struct magic_item *mg;
|
||||
|
||||
for (mg = magic; mg->mi_name != NULL; mg++)
|
||||
;
|
||||
if ((mg - 1)->mi_prob == 1000)
|
||||
return;
|
||||
printf("\nBad percentages for %s:\n", name);
|
||||
for (mg = magic; mg->mi_name != NULL; mg++)
|
||||
printf("%4d%% %s\n", mg->mi_prob, mg->mi_name);
|
||||
printf("%s", retstr);
|
||||
fflush(stdout);
|
||||
while (getchar() != '\n')
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* init_player:
|
||||
* roll up the rogue
|
||||
*/
|
||||
|
||||
init_player()
|
||||
{
|
||||
player.t_nomove = 0;
|
||||
player.t_nocmd = 0;
|
||||
him = &player.t_stats;
|
||||
him->s_lvl = 1;
|
||||
him->s_exp = 0L;
|
||||
him->s_maxhp = him->s_hpt = pinit(); /* hit points */
|
||||
him->s_re.a_str = pinit(); /* strength */
|
||||
him->s_re.a_dex = pinit(); /* dexterity */
|
||||
him->s_re.a_wis = pinit(); /* wisdom */
|
||||
him->s_re.a_con = pinit(); /* constitution */
|
||||
him->s_ef = him->s_re; /* effective = real */
|
||||
strcpy(him->s_dmg, "1d4");
|
||||
him->s_arm = NORMAC;
|
||||
him->s_carry = totalenc();
|
||||
him->s_pack = 0;
|
||||
pack = NULL; /* empty pack so far */
|
||||
max_stats = *him;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* pinit:
|
||||
* Returns the best 3 of 4 on a 6-sided die
|
||||
*/
|
||||
pinit()
|
||||
{
|
||||
int best[4];
|
||||
reg int i, min, minind, dicetot;
|
||||
|
||||
for (i = 0 ; i < 4 ; i++)
|
||||
best[i] = roll(1,6); /* populate array */
|
||||
min = best[0]; /* assume that 1st entry */
|
||||
minind = 0; /* is the lowest */
|
||||
for (i = 1 ; i < 4 ; i++) { /* find the lowest */
|
||||
if (best[i] < min) { /* if < minimum then update */
|
||||
min = best[i];
|
||||
minind = i; /* point to lowest value */
|
||||
}
|
||||
}
|
||||
dicetot = 0; /* start with nothing */
|
||||
for (i = 0 ; i < 4 ; i++) {
|
||||
if (i != minind) /* if not minimum, then add it */
|
||||
dicetot += best[i];
|
||||
}
|
||||
return(dicetot);
|
||||
}
|
||||
328
srogue/io.c
Normal file
328
srogue/io.c
Normal file
|
|
@ -0,0 +1,328 @@
|
|||
/*
|
||||
* Various input/output functions
|
||||
*
|
||||
* @(#)io.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include "rogue.h"
|
||||
#include "rogue.ext"
|
||||
|
||||
/*
|
||||
* msg:
|
||||
* Display a message at the top of the screen.
|
||||
*/
|
||||
static char msgbuf[BUFSIZ];
|
||||
static int newpos = 0;
|
||||
|
||||
msg(char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
/*
|
||||
* if the string is "", just clear the line
|
||||
*/
|
||||
if (*fmt == '\0') {
|
||||
wmove(cw, 0, 0);
|
||||
wclrtoeol(cw);
|
||||
mpos = 0;
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* otherwise add to the message and flush it out
|
||||
*/
|
||||
va_start(ap, fmt);
|
||||
doadd(fmt, ap);
|
||||
va_end(ap);
|
||||
endmsg();
|
||||
}
|
||||
|
||||
/*
|
||||
* addmsg:
|
||||
* Add things to the current message
|
||||
*/
|
||||
addmsg(char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
doadd(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/*
|
||||
* endmsg:
|
||||
* Display a new msg, giving him a chance to see the
|
||||
* previous one if it is up there with the --More--
|
||||
*/
|
||||
endmsg()
|
||||
{
|
||||
strcpy(huh, msgbuf);
|
||||
if (mpos > 0) {
|
||||
wmove(cw, 0, mpos);
|
||||
waddstr(cw, morestr);
|
||||
draw(cw);
|
||||
wait_for(cw, ' ');
|
||||
}
|
||||
mvwaddstr(cw, 0, 0, msgbuf);
|
||||
wclrtoeol(cw);
|
||||
mpos = newpos;
|
||||
newpos = 0;
|
||||
draw(cw);
|
||||
}
|
||||
|
||||
/*
|
||||
* doadd:
|
||||
* Perform a printf into a buffer
|
||||
*/
|
||||
doadd(char *fmt, va_list ap)
|
||||
{
|
||||
vsprintf(&msgbuf[newpos], fmt, ap);
|
||||
newpos = strlen(msgbuf);
|
||||
}
|
||||
|
||||
/*
|
||||
* step_ok:
|
||||
* Returns TRUE if it is ok to step on ch
|
||||
*/
|
||||
step_ok(ch)
|
||||
unsigned char ch;
|
||||
{
|
||||
if (dead_end(ch))
|
||||
return FALSE;
|
||||
else if (ch >= 32 && ch <= 127 && !isalpha(ch))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* dead_end:
|
||||
* Returns TRUE if you cant walk through that character
|
||||
*/
|
||||
dead_end(ch)
|
||||
char ch;
|
||||
{
|
||||
if (ch == '-' || ch == '|' || ch == ' ' || ch == SECRETDOOR)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* readchar:
|
||||
* flushes stdout so that screen is up to date and then returns
|
||||
* getchar.
|
||||
*/
|
||||
|
||||
readchar()
|
||||
{
|
||||
char c;
|
||||
|
||||
fflush(stdout);
|
||||
return( wgetch(cw) );
|
||||
}
|
||||
|
||||
char *hungstr[] = {
|
||||
"",
|
||||
" HUNGRY",
|
||||
" STARVING",
|
||||
" FAINTING",
|
||||
};
|
||||
|
||||
/*
|
||||
* status:
|
||||
* Display the important stats line. Keep the cursor where it was.
|
||||
*/
|
||||
status(fromfuse)
|
||||
int fromfuse;
|
||||
{
|
||||
reg int totwght, carwght;
|
||||
reg struct real *stef, *stre, *stmx;
|
||||
reg char *pb;
|
||||
int oy, ox, ch;
|
||||
static char buf[LINLEN];
|
||||
static char hwidth[] = { "%2d(%2d)" };
|
||||
|
||||
/*
|
||||
* If nothing has changed since the last time, then done
|
||||
*/
|
||||
if (nochange)
|
||||
return;
|
||||
nochange = TRUE;
|
||||
updpack(); /* get all weight info */
|
||||
stef = &player.t_stats.s_ef;
|
||||
stre = &player.t_stats.s_re;
|
||||
stmx = &max_stats.s_re;
|
||||
totwght = him->s_carry / 10;
|
||||
carwght = him->s_pack / 10;
|
||||
getyx(cw, oy, ox);
|
||||
if (him->s_maxhp >= 100) {
|
||||
hwidth[1] = '3'; /* if hit point >= 100 */
|
||||
hwidth[5] = '3'; /* change %2d to %3d */
|
||||
}
|
||||
if (stre->a_str < stmx->a_str)
|
||||
ch = '*';
|
||||
else
|
||||
ch = ' ';
|
||||
sprintf(buf, "Str: %2d(%c%2d)", stef->a_str, ch, stre->a_str);
|
||||
pb = &buf[strlen(buf)];
|
||||
if (stre->a_dex < stmx->a_dex)
|
||||
ch = '*';
|
||||
else
|
||||
ch = ' ';
|
||||
sprintf(pb, " Dex: %2d(%c%2d)", stef->a_dex, ch, stre->a_dex);
|
||||
pb = &buf[strlen(buf)];
|
||||
if (stre->a_wis < stmx->a_wis)
|
||||
ch = '*';
|
||||
else
|
||||
ch = ' ';
|
||||
sprintf(pb, " Wis: %2d(%c%2d)", stef->a_wis, ch, stre->a_wis);
|
||||
pb = &buf[strlen(buf)];
|
||||
if (stre->a_con < stmx->a_con)
|
||||
ch = '*';
|
||||
else
|
||||
ch = ' ';
|
||||
sprintf(pb, " Con: %2d(%c%2d)", stef->a_con, ch, stre->a_con);
|
||||
pb = &buf[strlen(buf)];
|
||||
sprintf(pb, " Carry: %3d(%3d)", carwght, totwght);
|
||||
mvwaddstr(cw, LINES - 1, 0, buf);
|
||||
sprintf(buf, "Level: %d Gold: %5d Hp: ",level, purse);
|
||||
pb = &buf[strlen(buf)];
|
||||
sprintf(pb, hwidth, him->s_hpt, him->s_maxhp);
|
||||
pb = &buf[strlen(buf)];
|
||||
sprintf(pb," Ac: %-2d Exp: %d/%ld",cur_armor == NULL ? him->s_arm :
|
||||
cur_armor->o_ac, him->s_lvl, him->s_exp);
|
||||
carwght = (packvol * 100) / V_PACK;
|
||||
pb = &buf[strlen(buf)];
|
||||
sprintf(pb, " Vol: %3d%%", carwght);
|
||||
mvwaddstr(cw, LINES - 2, 0, buf);
|
||||
waddstr(cw, hungstr[hungry_state]);
|
||||
wclrtoeol(cw);
|
||||
wmove(cw, oy, ox);
|
||||
}
|
||||
|
||||
/*
|
||||
* dispmax:
|
||||
* Display the hero's maximum status
|
||||
*/
|
||||
dispmax()
|
||||
{
|
||||
reg struct real *hmax;
|
||||
|
||||
hmax = &max_stats.s_re;
|
||||
msg("Maximums: Str = %d Dex = %d Wis = %d Con = %d",
|
||||
hmax->a_str, hmax->a_dex, hmax->a_wis, hmax->a_con);
|
||||
}
|
||||
|
||||
/*
|
||||
* illeg_ch:
|
||||
* Returns TRUE if a char shouldn't show on the screen
|
||||
*/
|
||||
illeg_ch(ch)
|
||||
unsigned char ch;
|
||||
{
|
||||
if (ch < 32 || ch > 127)
|
||||
return TRUE;
|
||||
if (ch >= '0' && ch <= '9')
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* wait_for:
|
||||
* Sit around until the guy types the right key
|
||||
*/
|
||||
wait_for(win,ch)
|
||||
WINDOW *win;
|
||||
char ch;
|
||||
{
|
||||
register char c;
|
||||
|
||||
if (ch == '\n')
|
||||
while ((c = wgetch(win)) != '\n' && c != '\r')
|
||||
continue;
|
||||
else
|
||||
while (wgetch(win) != ch)
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef NEED_GETTIME
|
||||
#include <stdio.h>
|
||||
#include <pwd.h>
|
||||
|
||||
/*
|
||||
* gettime:
|
||||
* This routine returns the current time as a string
|
||||
*/
|
||||
#ifdef ATT
|
||||
#include <time.h>
|
||||
#endif
|
||||
#ifdef BSD
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
char *
|
||||
gettime()
|
||||
{
|
||||
register char *timeptr;
|
||||
char *ctime();
|
||||
long int now, time();
|
||||
|
||||
time(&now); /* get current time */
|
||||
timeptr = ctime(&now); /* convert to string */
|
||||
return timeptr; /* return the string */
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
/*
|
||||
* npch:
|
||||
* Get the next char in line for inventories
|
||||
*/
|
||||
npch(ch)
|
||||
char ch;
|
||||
{
|
||||
reg char nch;
|
||||
if (ch >= 'z')
|
||||
nch = 'A';
|
||||
else
|
||||
nch = ch + 1;
|
||||
return nch;
|
||||
}
|
||||
110
srogue/list.c
Normal file
110
srogue/list.c
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Functions for dealing with linked lists of goodies
|
||||
*
|
||||
* @(#)list.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "rogue.h"
|
||||
#include "rogue.ext"
|
||||
|
||||
/*
|
||||
* detach:
|
||||
* Takes an item out of whatever linked list it might be in
|
||||
*/
|
||||
|
||||
_detach(list, item)
|
||||
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)
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* _free_list: Throw the whole blamed thing away
|
||||
*/
|
||||
_free_list(ptr)
|
||||
struct linked_list **ptr;
|
||||
{
|
||||
register struct linked_list *item;
|
||||
|
||||
while (*ptr != NULL) {
|
||||
item = *ptr;
|
||||
*ptr = next(item);
|
||||
discard(item);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* discard: free up an item
|
||||
*/
|
||||
discard(item)
|
||||
struct linked_list *item;
|
||||
{
|
||||
total -= 2;
|
||||
FREE(item->l_data);
|
||||
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;
|
||||
|
||||
item = (struct linked_list *) new(sizeof *item);
|
||||
item->l_data = new(size);
|
||||
item->l_next = item->l_prev = NULL;
|
||||
return item;
|
||||
}
|
||||
|
||||
char *
|
||||
new(size)
|
||||
int size;
|
||||
{
|
||||
register char *space = ALLOC(size);
|
||||
|
||||
if (space == NULL) {
|
||||
sprintf(prbuf,"Rogue ran out of memory (%d).",sbrk(0));
|
||||
fatal(prbuf);
|
||||
}
|
||||
total++;
|
||||
return space;
|
||||
}
|
||||
472
srogue/main.c
Normal file
472
srogue/main.c
Normal file
|
|
@ -0,0 +1,472 @@
|
|||
/*
|
||||
* Rogue
|
||||
* Exploring the dungeons of doom
|
||||
*
|
||||
* @(#)main.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
#include <termios.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <pwd.h>
|
||||
#include <limits.h>
|
||||
#include <sys/stat.h>
|
||||
#include "rogue.h"
|
||||
|
||||
#ifdef ATT
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#ifdef BSD
|
||||
#define srand48(seed) srandom(seed)
|
||||
#define lrand48() random()
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include "rogue.ext"
|
||||
|
||||
struct termios terminal;
|
||||
|
||||
main(argc, argv, envp)
|
||||
char **argv;
|
||||
char **envp;
|
||||
{
|
||||
register char *env;
|
||||
register struct linked_list *item;
|
||||
register struct object *obj;
|
||||
struct passwd *pw;
|
||||
struct passwd *getpwuid();
|
||||
char alldone, wpt;
|
||||
char *getpass(), *xcrypt(), *strrchr();
|
||||
int lowtime;
|
||||
time_t now;
|
||||
char *roguehome();
|
||||
char *homedir = roguehome();
|
||||
|
||||
#ifdef __DJGPP__
|
||||
_fmode = O_BINARY;
|
||||
#endif
|
||||
|
||||
if (homedir == NULL)
|
||||
homedir = "";
|
||||
|
||||
playuid = getuid();
|
||||
|
||||
if (setuid(playuid) < 0) {
|
||||
printf("Cannot change to effective uid: %d\n", playuid);
|
||||
exit(1);
|
||||
}
|
||||
playgid = getgid();
|
||||
|
||||
/* check for print-score option */
|
||||
|
||||
strcpy(scorefile, homedir);
|
||||
|
||||
if (*scorefile)
|
||||
strcat(scorefile,"/");
|
||||
strcat(scorefile, "srogue.scr");
|
||||
|
||||
if(argc >= 2 && strcmp(argv[1], "-s") == 0)
|
||||
{
|
||||
showtop(0);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (argc >= 2 && author() && strcmp(argv[1],"-a") == 0)
|
||||
{
|
||||
wizard = TRUE;
|
||||
argv++;
|
||||
argc--;
|
||||
}
|
||||
|
||||
/* Check to see if he is a wizard */
|
||||
|
||||
if (argc >= 2 && strcmp(argv[1],"-w") == 0)
|
||||
{
|
||||
if (strcmp(PASSWD, xcrypt(getpass(wizstr),"mT")) == 0)
|
||||
{
|
||||
wizard = TRUE;
|
||||
argv++;
|
||||
argc--;
|
||||
}
|
||||
}
|
||||
time(&now);
|
||||
lowtime = (int) now;
|
||||
|
||||
/* get home and options from environment */
|
||||
|
||||
if ((env = getenv("HOME")) != NULL)
|
||||
strcpy(home, env);
|
||||
else if ((pw = getpwuid(playuid)) != NULL)
|
||||
strcpy(home, pw->pw_dir);
|
||||
else
|
||||
home[0] = '\0';
|
||||
|
||||
if (strcmp(home,"/") == 0)
|
||||
home[0] = '\0';
|
||||
|
||||
if ((strlen(home) > 0) && (home[strlen(home)-1] != '/'))
|
||||
strcat(home, "/");
|
||||
|
||||
strcpy(file_name, home);
|
||||
strcat(file_name, "srogue.sav");
|
||||
|
||||
if ((env = getenv("ROGUEOPTS")) != NULL)
|
||||
parse_opts(env);
|
||||
|
||||
if (env == NULL || whoami[0] == '\0')
|
||||
{
|
||||
if((pw = getpwuid(playuid)) == NULL)
|
||||
{
|
||||
printf("Say, who are you?\n");
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
strucpy(whoami, pw->pw_name, strlen(pw->pw_name));
|
||||
}
|
||||
|
||||
if (env == NULL || fruit[0] == '\0')
|
||||
strcpy(fruit, "juicy-fruit");
|
||||
|
||||
if (argc == 2)
|
||||
if(!restore(argv[1], envp)) /* NOTE: NEVER RETURNS */
|
||||
exit(1);
|
||||
|
||||
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, One moment while I open the door to the dungeon...\n", whoami);
|
||||
|
||||
fflush(stdout);
|
||||
seed = dnum;
|
||||
srand48(seed); /* init rnd number gen */
|
||||
|
||||
signal(SIGINT, byebye); /* just in case */
|
||||
signal(SIGQUIT ,byebye);
|
||||
|
||||
init_everything();
|
||||
|
||||
#ifdef __INTERIX
|
||||
setenv("TERM","interix");
|
||||
#endif
|
||||
|
||||
initscr(); /* Start up cursor package */
|
||||
|
||||
if (strcmp(termname(),"dumb") == 0)
|
||||
{
|
||||
endwin();
|
||||
printf("ERROR in terminal parameters.\n");
|
||||
printf("Check TERM in environment.\n");
|
||||
byebye(1);
|
||||
}
|
||||
|
||||
if (LINES < 24 || COLS < 80) {
|
||||
endwin();
|
||||
printf("ERROR: screen size too small\n");
|
||||
byebye(1);
|
||||
}
|
||||
|
||||
if ((whoami == NULL) || (*whoami == '\0') || (strcmp(whoami,"dosuser")==0))
|
||||
{
|
||||
echo();
|
||||
mvaddstr(23,2,"Rogue's Name? ");
|
||||
wgetnstr(stdscr,whoami,MAXSTR);
|
||||
noecho();
|
||||
}
|
||||
|
||||
if ((whoami == NULL) || (*whoami == '\0'))
|
||||
strcpy(whoami,"Rodney");
|
||||
|
||||
setup();
|
||||
|
||||
/* Set up windows */
|
||||
|
||||
cw = newwin(0, 0, 0, 0);
|
||||
mw = newwin(0, 0, 0, 0);
|
||||
hw = newwin(0, 0, 0, 0);
|
||||
waswizard = wizard;
|
||||
|
||||
/* Draw current level */
|
||||
|
||||
new_level(NORMLEV);
|
||||
|
||||
/* Start up daemons and fuses */
|
||||
|
||||
daemon(status, TRUE, BEFORE);
|
||||
daemon(doctor, TRUE, BEFORE);
|
||||
daemon(stomach, TRUE, BEFORE);
|
||||
daemon(runners, TRUE, AFTER);
|
||||
fuse(swander, TRUE, WANDERTIME);
|
||||
|
||||
/* Give the rogue his weaponry */
|
||||
|
||||
do {
|
||||
wpt = pick_one(w_magic);
|
||||
switch (wpt)
|
||||
{
|
||||
case MACE: case SWORD: case TWOSWORD:
|
||||
case SPEAR: case TRIDENT: case SPETUM:
|
||||
case BARDICHE: case PIKE: case BASWORD:
|
||||
case HALBERD:
|
||||
alldone = TRUE;
|
||||
otherwise:
|
||||
alldone = FALSE;
|
||||
}
|
||||
} while(!alldone);
|
||||
|
||||
item = new_thing(FALSE, WEAPON, wpt);
|
||||
obj = OBJPTR(item);
|
||||
obj->o_hplus = rnd(3);
|
||||
obj->o_dplus = rnd(3);
|
||||
obj->o_flags = ISKNOW;
|
||||
add_pack(item, TRUE);
|
||||
cur_weapon = obj;
|
||||
|
||||
/* Now a bow */
|
||||
|
||||
item = new_thing(FALSE, WEAPON, BOW);
|
||||
obj = OBJPTR(item);
|
||||
obj->o_hplus = rnd(3);
|
||||
obj->o_dplus = rnd(3);
|
||||
obj->o_flags = ISKNOW;
|
||||
add_pack(item, TRUE);
|
||||
|
||||
/* Now some arrows */
|
||||
|
||||
item = new_thing(FALSE, WEAPON, ARROW);
|
||||
obj = OBJPTR(item);
|
||||
obj->o_count = 25 + rnd(15);
|
||||
obj->o_hplus = rnd(2);
|
||||
obj->o_dplus = rnd(2);
|
||||
obj->o_flags = ISKNOW;
|
||||
add_pack(item, TRUE);
|
||||
|
||||
/* And his suit of armor */
|
||||
|
||||
wpt = pick_one(a_magic);
|
||||
item = new_thing(FALSE, ARMOR, wpt);
|
||||
obj = OBJPTR(item);
|
||||
obj->o_flags = ISKNOW;
|
||||
obj->o_ac = armors[wpt].a_class - rnd(4);
|
||||
cur_armor = obj;
|
||||
add_pack(item, TRUE);
|
||||
|
||||
/* Give him some food */
|
||||
|
||||
item = new_thing(FALSE, FOOD, 0);
|
||||
add_pack(item, TRUE);
|
||||
|
||||
playit();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* endit:
|
||||
* Exit the program abnormally.
|
||||
*/
|
||||
void
|
||||
endit(int a)
|
||||
{
|
||||
fatal("Ok, if you want to exit that badly, I'll have to allow it");
|
||||
}
|
||||
|
||||
/*
|
||||
* fatal:
|
||||
* Exit the program, printing a message.
|
||||
*/
|
||||
|
||||
fatal(s)
|
||||
char *s;
|
||||
{
|
||||
clear();
|
||||
refresh();
|
||||
endwin();
|
||||
fprintf(stderr,"%s\n\r",s);
|
||||
fflush(stderr);
|
||||
byebye(2);
|
||||
}
|
||||
|
||||
/*
|
||||
* byebye:
|
||||
* Exit here and reset the users terminal parameters
|
||||
* to the way they were when he started
|
||||
*/
|
||||
|
||||
void
|
||||
byebye(how)
|
||||
int how;
|
||||
{
|
||||
if (!isendwin())
|
||||
endwin();
|
||||
|
||||
exit(how); /* exit like flag says */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* rnd:
|
||||
* Pick a very random number.
|
||||
*/
|
||||
rnd(range)
|
||||
int range;
|
||||
{
|
||||
reg int wh;
|
||||
|
||||
if (range == 0)
|
||||
wh = 0;
|
||||
else {
|
||||
wh = lrand48() % range;
|
||||
wh &= 0x7FFFFFFF;
|
||||
}
|
||||
return wh;
|
||||
}
|
||||
|
||||
/*
|
||||
* roll:
|
||||
* roll a number of dice
|
||||
*/
|
||||
roll(number, sides)
|
||||
int number, sides;
|
||||
{
|
||||
reg int dtotal = 0;
|
||||
|
||||
while(number-- > 0)
|
||||
dtotal += rnd(sides)+1;
|
||||
return dtotal;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** setup: Setup signal catching functions
|
||||
*/
|
||||
setup()
|
||||
{
|
||||
signal(SIGHUP, auto_save);
|
||||
signal(SIGINT, auto_save);
|
||||
signal(SIGQUIT, byebye);
|
||||
signal(SIGILL, game_err);
|
||||
signal(SIGTRAP, game_err);
|
||||
#ifdef SIGIOT
|
||||
signal(SIGIOT, game_err);
|
||||
#endif
|
||||
#ifdef SIGEMT
|
||||
signal(SIGEMT, game_err);
|
||||
#endif
|
||||
signal(SIGFPE, game_err);
|
||||
#ifdef SIGBUS
|
||||
signal(SIGBUS, game_err);
|
||||
#endif
|
||||
signal(SIGSEGV, game_err);
|
||||
#ifdef SIGSYS
|
||||
signal(SIGSYS, game_err);
|
||||
#endif
|
||||
signal(SIGPIPE, game_err);
|
||||
signal(SIGTERM, game_err);
|
||||
|
||||
cbreak();
|
||||
noecho();
|
||||
}
|
||||
|
||||
/*
|
||||
** playit: The main loop of the program. Loop until the game is over,
|
||||
** refreshing things and looking at the proper times.
|
||||
*/
|
||||
|
||||
playit()
|
||||
{
|
||||
reg char *opts;
|
||||
|
||||
tcgetattr(0,&terminal);
|
||||
|
||||
|
||||
/* parse environment declaration of options */
|
||||
|
||||
if ((opts = getenv("ROGUEOPTS")) != NULL)
|
||||
parse_opts(opts);
|
||||
|
||||
player.t_oldpos = hero;
|
||||
oldrp = roomin(&hero);
|
||||
nochange = FALSE;
|
||||
while (playing)
|
||||
command(); /* Command execution */
|
||||
endit(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** author: See if a user is an author of the program
|
||||
*/
|
||||
author()
|
||||
{
|
||||
switch (playuid) {
|
||||
case 100:
|
||||
case 0:
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
directory_exists(char *dirname)
|
||||
{
|
||||
struct stat sb;
|
||||
|
||||
if (stat(dirname, &sb) == 0) /* path exists */
|
||||
return (S_ISDIR (sb.st_mode));
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
char *
|
||||
roguehome()
|
||||
{
|
||||
static char path[1024];
|
||||
char *end,*home;
|
||||
|
||||
if ( (home = getenv("ROGUEHOME")) != NULL)
|
||||
{
|
||||
if (*home)
|
||||
{
|
||||
strncpy(path, home, PATH_MAX - 20);
|
||||
|
||||
end = &path[strlen(path)-1];
|
||||
|
||||
|
||||
while( (end >= path) && ((*end == '/') || (*end == '\\')))
|
||||
*end-- = '\0';
|
||||
|
||||
if (directory_exists(path))
|
||||
return(path);
|
||||
}
|
||||
}
|
||||
|
||||
if (directory_exists("/var/games/roguelike"))
|
||||
return("/var/games/roguelike");
|
||||
if (directory_exists("/var/lib/roguelike"))
|
||||
return("/var/lib/roguelike");
|
||||
if (directory_exists("/var/roguelike"))
|
||||
return("/var/roguelike");
|
||||
if (directory_exists("/usr/games/lib"))
|
||||
return("/usr/games/lib");
|
||||
if (directory_exists("/games/roguelik"))
|
||||
return("/games/roguelik");
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
102
srogue/makevers.c
Normal file
102
srogue/makevers.c
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Change the version number of rogue
|
||||
*
|
||||
* The version must be in the file in the format of:
|
||||
*
|
||||
* " * @(#)filename\tVERSION\t ..."
|
||||
*
|
||||
* Where VERSION is a 3 character string, i.e., "8.2"
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
long clock;
|
||||
struct tm *tp;
|
||||
char who[100];
|
||||
|
||||
char *strrchr(), *strchr(), *fgets();
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
register int i;
|
||||
register char *ptr;
|
||||
char ts[30];
|
||||
FILE *fp;
|
||||
|
||||
strcpy(who, argv[0]);
|
||||
if (argc < 3) {
|
||||
fprintf(stderr,"Usage: %s VERSION c_files\n", who);
|
||||
exit(1);
|
||||
}
|
||||
if (strlen(argv[1]) != 3) {
|
||||
fprintf(stderr,"%s: VERSION must be length 3\n", who);
|
||||
exit(1);
|
||||
}
|
||||
time(&clock);
|
||||
tp = localtime(&clock);
|
||||
sprintf(ts,"%2d/%2d/%2d",tp->tm_mon + 1,tp->tm_mday,tp->tm_year);
|
||||
for (i = 2; i < argc; i++) {
|
||||
ptr = strrchr(argv[i], '.');
|
||||
/*
|
||||
* make sure that files end in ".c" or ".h"
|
||||
*/
|
||||
if (ptr != NULL) {
|
||||
++ptr;
|
||||
if (*ptr == 'c' || *ptr == 'h')
|
||||
updvers(argv[1], argv[i]);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* now install new "version.c" file
|
||||
*/
|
||||
fp = fopen("vers.c", "w");
|
||||
if (fp == NULL) {
|
||||
fprintf(stderr,"%s: cant write version.c file\n",who);
|
||||
exit(1);
|
||||
}
|
||||
fprintf(fp, "/*\n * version number.\n */\n");
|
||||
fprintf(fp, "char version[] = ");
|
||||
fprintf(fp, "%c@(#)vers.c\t%3s\t(rdk)\t%s%c;\n", '"',
|
||||
argv[1], ts, '"');
|
||||
fprintf(fp, "char *release = \"%s (%s)\";\n", argv[1],ts);
|
||||
fclose(fp);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#define LINESIZ 132
|
||||
|
||||
updvers(vers, fname)
|
||||
char *fname;
|
||||
char *vers;
|
||||
{
|
||||
register FILE *fp;
|
||||
register char *ptr, *c;
|
||||
char line[LINESIZ];
|
||||
|
||||
if ((fp = fopen(fname, "r+")) == NULL) {
|
||||
fprintf(stderr,"%s: Not able to update %s\n", who, fname);
|
||||
return;
|
||||
}
|
||||
while ((c = fgets(line, LINESIZ, fp)) != NULL) {
|
||||
if (line[1] == '*' && line[3] == '@' && line[5] == '#') {
|
||||
ptr = strchr(line, '\t');
|
||||
if (ptr != NULL) {
|
||||
fseek(fp, -strlen(line), 1);
|
||||
sprintf(ptr, "\t%3s\t(rdk)\t%2d/%2d/%2d\n", vers,
|
||||
tp->tm_mon + 1, tp->tm_mday, tp->tm_year);
|
||||
fprintf(fp, "%s", line);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
401
srogue/misc.c
Normal file
401
srogue/misc.c
Normal file
|
|
@ -0,0 +1,401 @@
|
|||
/*
|
||||
* all sorts of miscellaneous routines
|
||||
*
|
||||
* @(#)misc.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "rogue.h"
|
||||
#include <ctype.h>
|
||||
#include "rogue.ext"
|
||||
|
||||
/*
|
||||
* waste_time:
|
||||
* Do nothing but let other things happen
|
||||
*/
|
||||
waste_time()
|
||||
{
|
||||
if (inwhgt) /* if from wghtchk, then done */
|
||||
return;
|
||||
do_daemons(BEFORE);
|
||||
do_daemons(AFTER);
|
||||
do_fuses();
|
||||
}
|
||||
|
||||
/*
|
||||
* getindex:
|
||||
* Convert a type into an index for the things structures
|
||||
*/
|
||||
getindex(what)
|
||||
char what;
|
||||
{
|
||||
int index = -1;
|
||||
|
||||
switch (what) {
|
||||
case POTION: index = TYP_POTION;
|
||||
when SCROLL: index = TYP_SCROLL;
|
||||
when FOOD: index = TYP_FOOD;
|
||||
when RING: index = TYP_RING;
|
||||
when AMULET: index = TYP_AMULET;
|
||||
when ARMOR: index = TYP_ARMOR;
|
||||
when WEAPON: index = TYP_WEAPON;
|
||||
when STICK: index = TYP_STICK;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
/*
|
||||
* tr_name:
|
||||
* print the name of a trap
|
||||
*/
|
||||
char *
|
||||
tr_name(ch)
|
||||
char ch;
|
||||
{
|
||||
reg char *s;
|
||||
|
||||
switch (ch) {
|
||||
case TRAPDOOR:
|
||||
s = "A trapdoor.";
|
||||
when BEARTRAP:
|
||||
s = "A beartrap.";
|
||||
when SLEEPTRAP:
|
||||
s = "A sleeping gas trap.";
|
||||
when ARROWTRAP:
|
||||
s = "An arrow trap.";
|
||||
when TELTRAP:
|
||||
s = "A teleport trap.";
|
||||
when DARTTRAP:
|
||||
s = "A dart trap.";
|
||||
when POOL:
|
||||
s = "A magic pool.";
|
||||
when POST:
|
||||
s = "A trading post.";
|
||||
when MAZETRAP:
|
||||
s = "A maze trap.";
|
||||
otherwise:
|
||||
s = "A bottomless pit."; /* shouldn't get here */
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look:
|
||||
* A quick glance all around the player
|
||||
*/
|
||||
look(wakeup)
|
||||
bool wakeup;
|
||||
{
|
||||
reg char ch;
|
||||
reg int oldx, oldy, y, x;
|
||||
reg struct room *rp;
|
||||
int ey, ex, oex, oey;
|
||||
int passcount = 0;
|
||||
bool inpass, blind;
|
||||
|
||||
getyx(cw, oldy, oldx);
|
||||
oex = player.t_oldpos.x;
|
||||
oey = player.t_oldpos.y;
|
||||
blind = pl_on(ISBLIND);
|
||||
if ((oldrp != NULL && rf_on(oldrp,ISDARK)) || blind) {
|
||||
for (x = oex - 1; x <= oex + 1; x += 1)
|
||||
for (y = oey - 1; y <= oey + 1; y += 1)
|
||||
if ((y != hero.y || x != hero.x) && show(y, x) == FLOOR)
|
||||
mvwaddch(cw, y, x, ' ');
|
||||
}
|
||||
rp = player.t_room;
|
||||
inpass = (rp == NULL); /* TRUE when not in a room */
|
||||
ey = hero.y + 1;
|
||||
ex = hero.x + 1;
|
||||
for (x = hero.x - 1; x <= ex; x += 1) {
|
||||
if (x >= 0 && x <= COLS - 1) {
|
||||
for (y = hero.y - 1; y <= ey; y += 1) {
|
||||
if (y <= 0 || y >= LINES - 2)
|
||||
continue;
|
||||
if (isalpha(mvwinch(mw, y, x))) {
|
||||
reg struct linked_list *it;
|
||||
reg struct thing *tp;
|
||||
|
||||
if (wakeup || (!inpass && rf_on(rp, ISTREAS)))
|
||||
it = wake_monster(y, x);
|
||||
else
|
||||
it = find_mons(y, x);
|
||||
if (it == NULL) /* lost monster */
|
||||
mvaddch(y, x, FLOOR);
|
||||
else {
|
||||
tp = THINGPTR(it);
|
||||
if (isatrap(tp->t_oldch = mvinch(y, x))) {
|
||||
struct trap *trp;
|
||||
|
||||
if ((trp = trap_at(y,x)) == NULL)
|
||||
break;
|
||||
if (trp->tr_flags & ISFOUND)
|
||||
tp->t_oldch = trp->tr_type;
|
||||
else
|
||||
tp->t_oldch = FLOOR;
|
||||
}
|
||||
if (tp->t_oldch == FLOOR && rf_on(rp,ISDARK))
|
||||
if (!blind)
|
||||
tp->t_oldch = ' ';
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Secret doors show as walls
|
||||
*/
|
||||
if ((ch = show(y, x)) == SECRETDOOR) {
|
||||
if (inpass || y == rp->r_pos.y || y == rp->r_pos.y + rp->r_max.y - 1)
|
||||
ch = '-';
|
||||
else
|
||||
ch = '|';
|
||||
}
|
||||
/*
|
||||
* Don't show room walls if he is in a passage
|
||||
*/
|
||||
if (!blind) {
|
||||
if ((y == hero.y && x == hero.x) || (inpass && (ch == '-' || ch == '|')))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
ch = ' ';
|
||||
wmove(cw, y, x);
|
||||
waddch(cw, ch);
|
||||
if (door_stop && !firstmove && running) {
|
||||
switch (runch) {
|
||||
case 'h':
|
||||
if (x == ex)
|
||||
continue;
|
||||
when 'j':
|
||||
if (y == hero.y - 1)
|
||||
continue;
|
||||
when 'k':
|
||||
if (y == ey)
|
||||
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 += 1;
|
||||
break;
|
||||
case FLOOR:
|
||||
case '|':
|
||||
case '-':
|
||||
case ' ':
|
||||
break;
|
||||
default:
|
||||
running = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (door_stop && !firstmove && passcount > 1)
|
||||
running = FALSE;
|
||||
mvwaddch(cw, hero.y, hero.x, PLAYER);
|
||||
wmove(cw, oldy, oldx);
|
||||
player.t_oldpos = hero;
|
||||
oldrp = rp;
|
||||
}
|
||||
|
||||
/*
|
||||
* find_obj:
|
||||
* find the unclaimed object at y, x
|
||||
*/
|
||||
struct linked_list *
|
||||
find_obj(y, x)
|
||||
int y, x;
|
||||
{
|
||||
reg struct linked_list *obj;
|
||||
reg 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;
|
||||
}
|
||||
|
||||
/*
|
||||
* eat:
|
||||
* Let the hero eat some food.
|
||||
*/
|
||||
eat()
|
||||
{
|
||||
reg struct linked_list *item;
|
||||
reg struct object *obj;
|
||||
reg int goodfood, cursed;
|
||||
|
||||
if ((item = get_item("eat", FOOD)) == NULL)
|
||||
return;
|
||||
obj = OBJPTR(item);
|
||||
if (obj->o_type != FOOD) {
|
||||
msg("That's Inedible!");
|
||||
after = FALSE;
|
||||
return;
|
||||
}
|
||||
cursed = 1;
|
||||
if (o_on(obj, ISCURSED))
|
||||
cursed += 1;
|
||||
else if (o_on(obj, ISBLESS))
|
||||
cursed -= 1;
|
||||
if (obj->o_which == FRUITFOOD) {
|
||||
msg("My, that was a yummy %s.", fruit);
|
||||
goodfood = 100;
|
||||
}
|
||||
else {
|
||||
if (rnd(100) > 80 || o_on(obj, ISCURSED)) {
|
||||
msg("Yuk, this food tastes like ARA.");
|
||||
goodfood = 300;
|
||||
him->s_exp += 1;
|
||||
check_level();
|
||||
}
|
||||
else {
|
||||
msg("Yum, that tasted good.");
|
||||
goodfood = 200;
|
||||
}
|
||||
}
|
||||
goodfood *= cursed;
|
||||
if ((food_left += HUNGERTIME + rnd(400) - goodfood) > STOMACHSIZE)
|
||||
food_left = STOMACHSIZE;
|
||||
hungry_state = F_OKAY;
|
||||
updpack(); /* update pack */
|
||||
if (obj == cur_weapon)
|
||||
cur_weapon = NULL;
|
||||
del_pack(item); /* get rid of the food */
|
||||
}
|
||||
|
||||
/*
|
||||
* aggravate:
|
||||
* aggravate all the monsters on this level
|
||||
*/
|
||||
aggravate()
|
||||
{
|
||||
reg struct linked_list *mi;
|
||||
|
||||
for (mi = mlist; mi != NULL; mi = next(mi))
|
||||
runto(&(THINGPTR(mi))->t_pos, &hero);
|
||||
}
|
||||
|
||||
/*
|
||||
* vowelstr:
|
||||
* If string starts with a vowel, return "n" for an "an"
|
||||
*/
|
||||
char *
|
||||
vowelstr(str)
|
||||
char *str;
|
||||
{
|
||||
switch (tolower(*str)) {
|
||||
case 'a':
|
||||
case 'e':
|
||||
case 'i':
|
||||
case 'o':
|
||||
case 'u':
|
||||
return "n";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* is_current:
|
||||
* See if the object is one of the currently used items
|
||||
*/
|
||||
is_current(obj)
|
||||
struct object *obj;
|
||||
{
|
||||
if (obj == NULL)
|
||||
return FALSE;
|
||||
if (obj == cur_armor || obj == cur_weapon || obj == cur_ring[LEFT]
|
||||
|| obj == cur_ring[RIGHT]) {
|
||||
msg("Already in use.");
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* get_dir:
|
||||
* Set up the direction coordinates
|
||||
*/
|
||||
get_dir()
|
||||
{
|
||||
reg char *prompt;
|
||||
reg bool gotit;
|
||||
|
||||
prompt = "Direction: ";
|
||||
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 (pl_on(ISHUH) && rnd(100) > 80) {
|
||||
do {
|
||||
delta.y = rnd(3) - 1;
|
||||
delta.x = rnd(3) - 1;
|
||||
} while (delta.y == 0 && delta.x == 0);
|
||||
}
|
||||
mpos = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* initfood:
|
||||
* Set up stuff for a food-type object
|
||||
*/
|
||||
initfood(what)
|
||||
struct object *what;
|
||||
{
|
||||
what->o_type = FOOD;
|
||||
what->o_group = NORMFOOD;
|
||||
if (rnd(100) < 15)
|
||||
what->o_group = FRUITFOOD;
|
||||
what->o_which = what->o_group;
|
||||
what->o_count = 1 + extras();
|
||||
what->o_flags = ISKNOW;
|
||||
what->o_weight = things[TYP_FOOD].mi_wght;
|
||||
what->o_typname = things[TYP_FOOD].mi_name;
|
||||
what->o_hplus = what->o_dplus = 0;
|
||||
what->o_vol = itemvol(what);
|
||||
}
|
||||
386
srogue/monsters.c
Normal file
386
srogue/monsters.c
Normal file
|
|
@ -0,0 +1,386 @@
|
|||
/*
|
||||
* File with various monster functions in it
|
||||
*
|
||||
* @(#)monsters.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "rogue.h"
|
||||
#include <ctype.h>
|
||||
#include "rogue.ext"
|
||||
|
||||
/*
|
||||
* rnd_mon:
|
||||
* Pick a monster to show up. The lower the level,
|
||||
* the meaner the monster.
|
||||
*/
|
||||
rnd_mon(wander,baddie)
|
||||
bool wander;
|
||||
bool baddie; /* TRUE when from a polymorph stick */
|
||||
{
|
||||
reg int i, ok, cnt;
|
||||
|
||||
cnt = 0;
|
||||
if (levcount == 0) /* if only asmodeus possible */
|
||||
return(MAXMONS);
|
||||
if (baddie) {
|
||||
while (1) {
|
||||
i = rnd(MAXMONS); /* pick ANY monster */
|
||||
if (monsters[i].m_lev.l_lev < 0) /* skip genocided ones */
|
||||
continue;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
ok = FALSE;
|
||||
do {
|
||||
/*
|
||||
* get a random monster from this range
|
||||
*/
|
||||
i = rnd(levcount);
|
||||
/*
|
||||
* Only create a wandering monster if we want one
|
||||
* (or the count is exceeded)
|
||||
*/
|
||||
if (!wander || mtlev[i]->m_lev.d_wand || ++cnt > 500)
|
||||
ok = TRUE;
|
||||
} while(!ok);
|
||||
return (midx(mtlev[i]->m_show));
|
||||
}
|
||||
|
||||
/*
|
||||
* lev_mon:
|
||||
* This gets all monsters possible on this level
|
||||
*/
|
||||
lev_mon()
|
||||
{
|
||||
reg int i;
|
||||
reg struct monster *mm;
|
||||
|
||||
levcount = 0;
|
||||
for (i = 0; i < MAXMONS; i++) {
|
||||
mm = &monsters[i];
|
||||
if (mm->m_lev.h_lev >= level && mm->m_lev.l_lev <= level) {
|
||||
mtlev[levcount] = mm;
|
||||
if (++levcount >= MONRANGE)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (levcount == 0) /* if no monsters are possible */
|
||||
mtlev[0] = &monsters[MAXMONS]; /* then asmodeus 'A' */
|
||||
}
|
||||
|
||||
/*
|
||||
* new_monster:
|
||||
* Pick a new monster and add it to the list
|
||||
*/
|
||||
struct linked_list *
|
||||
new_monster(type, cp, treas)
|
||||
struct coord *cp;
|
||||
bool treas;
|
||||
char type;
|
||||
{
|
||||
reg struct linked_list *item;
|
||||
reg struct thing *tp;
|
||||
reg struct monster *mp;
|
||||
reg struct stats *st;
|
||||
float killexp; /* experience gotten for killing him */
|
||||
|
||||
item = new_item(sizeof(struct thing));
|
||||
attach(mlist, item);
|
||||
tp = THINGPTR(item);
|
||||
st = &tp->t_stats;
|
||||
mp = &monsters[type]; /* point to this monsters structure */
|
||||
tp->t_type = mp->m_show;
|
||||
tp->t_indx = type;
|
||||
tp->t_pos = *cp;
|
||||
tp->t_room = roomin(cp);
|
||||
tp->t_oldch = mvwinch(cw, cp->y, cp->x);
|
||||
tp->t_nomove = 0;
|
||||
tp->t_nocmd = 0;
|
||||
mvwaddch(mw, cp->y, cp->x, tp->t_type);
|
||||
|
||||
/*
|
||||
* copy monster data
|
||||
*/
|
||||
tp->t_stats = mp->m_stats;
|
||||
|
||||
/*
|
||||
* If below amulet level, make the monsters meaner the
|
||||
* deeper the hero goes.
|
||||
*/
|
||||
if (level > AMLEVEL)
|
||||
st->s_lvl += ((level - AMLEVEL) / 4);
|
||||
|
||||
/*
|
||||
* If monster in treasure room, then tougher.
|
||||
*/
|
||||
if (treas)
|
||||
st->s_lvl += 1;
|
||||
if (levtype == MAZELEV)
|
||||
st->s_lvl += 1;
|
||||
/*
|
||||
* If the hero is going back up, then the monsters are more
|
||||
* prepared for him, so tougher.
|
||||
*/
|
||||
if (goingup())
|
||||
st->s_lvl += 1;
|
||||
|
||||
/*
|
||||
* Get hit points for monster depending on his experience
|
||||
*/
|
||||
st->s_hpt = roll(st->s_lvl, 8);
|
||||
st->s_maxhp = st->s_hpt;
|
||||
/*
|
||||
* Adjust experience point we get for killing it by the
|
||||
* strength of this particular monster by ~~ +- 50%
|
||||
*/
|
||||
killexp = mp->m_stats.s_exp * (0.47 + (float)st->s_hpt /
|
||||
(8 * (float)st->s_lvl));
|
||||
|
||||
st->s_exp = killexp; /* use float for accuracy */
|
||||
if(st->s_exp < 1)
|
||||
st->s_exp = 1; /* minimum 1 experience point */
|
||||
tp->t_flags = mp->m_flags;
|
||||
/*
|
||||
* If monster in treasure room, then MEAN
|
||||
*/
|
||||
if (treas || levtype == MAZELEV)
|
||||
tp->t_flags |= ISMEAN;
|
||||
tp->t_turn = TRUE;
|
||||
tp->t_pack = NULL;
|
||||
/*
|
||||
* Dont wander if treas room
|
||||
*/
|
||||
if (iswearing(R_AGGR) && !treas)
|
||||
runto(cp, &hero);
|
||||
if (tp->t_type == 'M') {
|
||||
char mch;
|
||||
|
||||
if (tp->t_pack != NULL)
|
||||
mch = (OBJPTR(tp->t_pack))->o_type;
|
||||
else {
|
||||
switch (rnd(level >= AMLEVEL ? 9 : 8)) {
|
||||
case 0: mch = GOLD;
|
||||
when 1: mch = POTION;
|
||||
when 2: mch = SCROLL;
|
||||
when 3: mch = STAIRS;
|
||||
when 4: mch = WEAPON;
|
||||
when 5: mch = ARMOR;
|
||||
when 6: mch = RING;
|
||||
when 7: mch = STICK;
|
||||
when 8: mch = AMULET;
|
||||
}
|
||||
}
|
||||
if (treas)
|
||||
mch = 'M'; /* no disguise in treasure room */
|
||||
tp->t_disguise = mch;
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
/*
|
||||
* wanderer:
|
||||
* A wandering monster has awakened and is headed for the player
|
||||
*/
|
||||
wanderer()
|
||||
{
|
||||
reg int ch;
|
||||
reg struct room *rp, *hr = player.t_room;
|
||||
reg struct linked_list *item;
|
||||
reg struct thing *tp;
|
||||
struct coord mp;
|
||||
|
||||
do {
|
||||
rp = &rooms[rnd_room()];
|
||||
if (rp != hr || levtype == MAZELEV) {
|
||||
mp = *rnd_pos(rp);
|
||||
ch = mvinch(mp.y, mp.x);
|
||||
}
|
||||
} while (!step_ok(ch));
|
||||
item = new_monster(rnd_mon(TRUE,FALSE), &mp, FALSE);
|
||||
tp = THINGPTR(item);
|
||||
tp->t_flags |= ISRUN;
|
||||
tp->t_dest = &hero;
|
||||
}
|
||||
|
||||
/*
|
||||
* wake_monster:
|
||||
* What to do when the hero steps next to a monster
|
||||
*/
|
||||
struct linked_list *
|
||||
wake_monster(y, x)
|
||||
int y, x;
|
||||
{
|
||||
reg struct thing *tp;
|
||||
reg struct linked_list *it;
|
||||
reg struct room *rp;
|
||||
reg char ch;
|
||||
bool treas = FALSE;
|
||||
|
||||
if ((it = find_mons(y, x)) == NULL)
|
||||
return NULL;
|
||||
tp = THINGPTR(it);
|
||||
ch = tp->t_type;
|
||||
/*
|
||||
* Every time he sees mean monster, it might start chasing him
|
||||
*/
|
||||
rp = player.t_room;
|
||||
if (rp != NULL && rf_on(rp,ISTREAS)) {
|
||||
tp->t_flags &= ~ISHELD;
|
||||
treas = TRUE;
|
||||
}
|
||||
if (treas || (rnd(100) > 33 && on(*tp,ISMEAN) && off(*tp,ISHELD) &&
|
||||
!iswearing(R_STEALTH))) {
|
||||
tp->t_dest = &hero;
|
||||
tp->t_flags |= ISRUN;
|
||||
}
|
||||
if (ch == 'U' && pl_off(ISBLIND)) {
|
||||
if ((rp != NULL && !rf_on(rp,ISDARK) && levtype != MAZELEV)
|
||||
|| DISTANCE(y, x, hero.y, hero.x) < 3) {
|
||||
if (off(*tp,ISFOUND) && !save(VS_PETRIFICATION)
|
||||
&& !iswearing(R_SUSAB) && pl_off(ISINVINC)) {
|
||||
msg("The umber hulk's gaze has confused you.");
|
||||
if (pl_on(ISHUH))
|
||||
lengthen(unconfuse,rnd(20)+HUHDURATION);
|
||||
else
|
||||
fuse(unconfuse,TRUE,rnd(20)+HUHDURATION);
|
||||
player.t_flags |= ISHUH;
|
||||
}
|
||||
tp->t_flags |= ISFOUND;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Hide invisible monsters
|
||||
*/
|
||||
if ((tp->t_flags & ISINVIS) && pl_off(CANSEE))
|
||||
ch = mvinch(y, x);
|
||||
/*
|
||||
* Let greedy ones guard gold
|
||||
*/
|
||||
if (on(*tp, ISGREED) && off(*tp, ISRUN)) {
|
||||
if (rp != NULL && rp->r_goldval) {
|
||||
tp->t_dest = &rp->r_gold;
|
||||
tp->t_flags |= ISRUN;
|
||||
}
|
||||
}
|
||||
return it;
|
||||
}
|
||||
|
||||
/*
|
||||
* genocide:
|
||||
* Eradicate a monster forevermore
|
||||
*/
|
||||
genocide()
|
||||
{
|
||||
reg struct linked_list *ip, *nip;
|
||||
reg struct thing *mp;
|
||||
struct monster *mm;
|
||||
reg int i, ii, c;
|
||||
|
||||
if (levcount == 0) {
|
||||
mpos = 0;
|
||||
msg("You cannot genocide Asmodeus !!");
|
||||
return;
|
||||
}
|
||||
tryagain:
|
||||
i = TRUE; /* assume an error now */
|
||||
while (i) {
|
||||
msg("Which monster (remember UPPER & lower case)?");
|
||||
c = readchar(); /* get a char */
|
||||
if (c == ESCAPE) { /* he can abort (the fool) */
|
||||
msg("");
|
||||
return;
|
||||
}
|
||||
if (isalpha(c)) /* valid char here */
|
||||
i = FALSE; /* exit the loop */
|
||||
else { /* he didn't type a letter */
|
||||
mpos = 0;
|
||||
msg("Please specify a letter between 'A' and 'z'");
|
||||
}
|
||||
}
|
||||
i = midx(c); /* get index to monster */
|
||||
mm = &monsters[i];
|
||||
if (mm->m_lev.l_lev < 0) {
|
||||
mpos = 0;
|
||||
msg("You have already eliminated the %s.",mm->m_name);
|
||||
goto tryagain;
|
||||
}
|
||||
for (ip = mlist; ip != NULL; ip = nip) {
|
||||
mp = THINGPTR(ip);
|
||||
nip = next(ip);
|
||||
if (mp->t_type == c)
|
||||
remove_monster(&mp->t_pos, ip);
|
||||
}
|
||||
mm->m_lev.l_lev = -1; /* get rid of it */
|
||||
mm->m_lev.h_lev = -1;
|
||||
lev_mon(); /* redo monster list */
|
||||
mpos = 0;
|
||||
msg("You have wiped out the %s.",mm->m_name);
|
||||
}
|
||||
|
||||
/*
|
||||
* unhold:
|
||||
* Release the player from being held
|
||||
*/
|
||||
unhold(whichmon)
|
||||
char whichmon;
|
||||
{
|
||||
switch (whichmon) {
|
||||
case 'F':
|
||||
fung_hit = 0;
|
||||
strcpy(monsters[midx('F')].m_stats.s_dmg, "000d0");
|
||||
case 'd':
|
||||
player.t_flags &= ~ISHELD;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* midx:
|
||||
* This returns an index to 'whichmon'
|
||||
*/
|
||||
midx(whichmon)
|
||||
char whichmon;
|
||||
{
|
||||
if (isupper(whichmon))
|
||||
return(whichmon - 'A'); /* 0 to 25 for uppercase */
|
||||
else if (islower(whichmon))
|
||||
return(whichmon - 'a' + 26); /* 26 to 51 for lowercase */
|
||||
else
|
||||
return(MAXMONS); /* 52 for Asmodeus */
|
||||
}
|
||||
|
||||
/*
|
||||
* monhurt:
|
||||
* See when monster should run or fight. Return
|
||||
* TRUE if hit points less than acceptable.
|
||||
*/
|
||||
monhurt(th)
|
||||
struct thing *th;
|
||||
{
|
||||
reg int ewis, crithp, f1, f2;
|
||||
reg struct stats *st;
|
||||
|
||||
st = &th->t_stats;
|
||||
ewis = st->s_ef.a_wis;
|
||||
if (ewis <= MONWIS) /* stupid monsters dont know */
|
||||
return FALSE;
|
||||
f1 = st->s_maxhp / 4; /* base hpt for being hurt */
|
||||
f2 = (ewis - MONWIS) * 5 / 3; /* bonus for smart monsters */
|
||||
if (th->t_flags & ISWOUND) /* if recovering from being */
|
||||
f1 *= 2; /* wounded, then double the base */
|
||||
crithp = f1 + f2; /* get critical hpt for hurt */
|
||||
if (crithp > st->s_maxhp) /* only up to max hpt */
|
||||
crithp = st->s_maxhp;
|
||||
if (st->s_hpt < crithp) /* if < critical, then still hurt */
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
740
srogue/move.c
Normal file
740
srogue/move.c
Normal file
|
|
@ -0,0 +1,740 @@
|
|||
/*
|
||||
* Hero movement commands
|
||||
*
|
||||
* @(#)move.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include "rogue.h"
|
||||
#include "rogue.ext"
|
||||
|
||||
/*
|
||||
* Used to hold the new hero position
|
||||
*/
|
||||
|
||||
struct coord nh;
|
||||
|
||||
/*
|
||||
* do_run:
|
||||
* Start the hero running
|
||||
*/
|
||||
|
||||
do_run(ch)
|
||||
char ch;
|
||||
{
|
||||
running = TRUE;
|
||||
after = FALSE;
|
||||
runch = ch;
|
||||
}
|
||||
|
||||
/*
|
||||
* do_move:
|
||||
* Check to see that a move is legal. If it is handle the
|
||||
* consequences (fighting, picking up, etc.)
|
||||
*/
|
||||
|
||||
do_move(dy, dx)
|
||||
int dy, dx;
|
||||
{
|
||||
reg int ch;
|
||||
reg struct room *rp;
|
||||
|
||||
firstmove = FALSE;
|
||||
curprice = -1;
|
||||
inpool = FALSE;
|
||||
|
||||
if (player.t_nomove > 0) {
|
||||
player.t_nomove -= 1;
|
||||
msg("You are still stuck in the bear trap.");
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Do a confused move (maybe)
|
||||
*/
|
||||
if ((rnd(100) < 80 && pl_on(ISHUH)) ||
|
||||
(iswearing(R_DELUS) && rnd(100) < 25))
|
||||
nh = *rndmove(&player);
|
||||
else {
|
||||
nh.y = hero.y + dy;
|
||||
nh.x = hero.x + dx;
|
||||
}
|
||||
/*
|
||||
* Check if he tried to move off the screen or make
|
||||
* an illegal diagonal move, and stop him if he did.
|
||||
*/
|
||||
if (!cordok(nh.y, nh.x) ||
|
||||
(pl_off(ISETHER) && !diag_ok(&hero, &nh))) {
|
||||
after = running = FALSE;
|
||||
return;
|
||||
}
|
||||
if (running) {
|
||||
ch = winat(nh.y, nh.x);
|
||||
if (dead_end(ch)) {
|
||||
reg int gox, goy, apsg, whichway;
|
||||
|
||||
gox = goy = apsg = 0;
|
||||
if (dy == 0) {
|
||||
ch = show(hero.y+1,hero.x);
|
||||
if (ch == PASSAGE) {
|
||||
apsg += 1;
|
||||
goy = 1;
|
||||
}
|
||||
ch = show(hero.y-1,hero.x);
|
||||
if (ch == PASSAGE) {
|
||||
apsg += 1;
|
||||
goy = -1;
|
||||
}
|
||||
}
|
||||
else if (dx == 0) {
|
||||
ch = show(hero.y,hero.x+1);
|
||||
if (ch == PASSAGE) {
|
||||
gox = 1;
|
||||
apsg += 1;
|
||||
}
|
||||
ch = show(hero.y,hero.x-1);
|
||||
if (ch == PASSAGE) {
|
||||
gox = -1;
|
||||
apsg += 1;
|
||||
}
|
||||
}
|
||||
if (apsg != 1) {
|
||||
running = after = FALSE;
|
||||
return;
|
||||
}
|
||||
else { /* can still run here */
|
||||
nh.y = hero.y + goy;
|
||||
nh.x = hero.x + gox;
|
||||
whichway = (goy + 1) * 3 + gox + 1;
|
||||
switch(whichway) {
|
||||
case 0: runch = 'y';
|
||||
when 1: runch = 'k';
|
||||
when 2: runch = 'u';
|
||||
when 3: runch = 'h';
|
||||
when 4: runch = '.'; /* shouldn't do */
|
||||
when 5: runch = 'l';
|
||||
when 6: runch = 'b';
|
||||
when 7: runch = 'j';
|
||||
when 8: runch = 'n';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (running && ce(hero, nh))
|
||||
after = running = FALSE;
|
||||
ch = winat(nh.y, nh.x);
|
||||
if (pl_on(ISHELD) && ch != 'F' && ch != 'd') {
|
||||
msg("You are being held.");
|
||||
return;
|
||||
}
|
||||
if (pl_off(ISETHER)) {
|
||||
if (isatrap(ch)) {
|
||||
ch = be_trapped(&nh, &player);
|
||||
if (nlmove) {
|
||||
nlmove = FALSE;
|
||||
return;
|
||||
}
|
||||
else if (ch == POOL)
|
||||
inpool = TRUE;
|
||||
}
|
||||
else if (dead_end(ch)) {
|
||||
after = running = FALSE;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
switch(ch) {
|
||||
case GOLD: case POTION: case SCROLL:
|
||||
case FOOD: case WEAPON: case ARMOR:
|
||||
case RING: case AMULET: case STICK:
|
||||
running = FALSE;
|
||||
take = ch;
|
||||
default:
|
||||
if (illeg_ch(ch)) {
|
||||
running = FALSE;
|
||||
mvaddch(nh.y, nh.x, FLOOR);
|
||||
teleport(rndspot, &player);
|
||||
light(&nh);
|
||||
msg("The spatial warp disappears !");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
rp = roomin(&nh);
|
||||
if (ch == DOOR) { /* just stepped on a door */
|
||||
running = FALSE;
|
||||
if (rp != NULL && rf_on(rp, ISTREAS)) {
|
||||
struct linked_list *item;
|
||||
struct thing *tp;
|
||||
|
||||
for (item = mlist; item != NULL; item = next(item)) {
|
||||
tp = THINGPTR(item);
|
||||
if (tp->t_room == rp)
|
||||
runto(&tp->t_pos, &hero);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ch == STAIRS && pl_off(ISETHER))
|
||||
running = FALSE;
|
||||
else if (isalpha(ch) && pl_off(ISETHER)) {
|
||||
running = FALSE;
|
||||
fight(&nh, cur_weapon, FALSE);
|
||||
return;
|
||||
}
|
||||
if (rp == NULL && player.t_room != NULL)
|
||||
light(&hero); /* exiting a room */
|
||||
else if (rp != NULL && player.t_room == NULL)
|
||||
light(&nh); /* just entering a room */
|
||||
if (pl_on(ISBLIND))
|
||||
ch = ' ';
|
||||
else
|
||||
ch = player.t_oldch;
|
||||
mvwaddch(cw, hero.y, hero.x, ch);
|
||||
mvwaddch(cw, nh.y, nh.x, PLAYER);
|
||||
hero = nh;
|
||||
player.t_room = rp;
|
||||
player.t_oldch = mvinch(hero.y, hero.x);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called to illuminate a room.
|
||||
* If it is dark, remove anything that might move.
|
||||
*/
|
||||
light(cp)
|
||||
struct coord *cp;
|
||||
{
|
||||
reg struct room *rp;
|
||||
reg int j, k, x, y;
|
||||
reg char ch, rch;
|
||||
reg struct linked_list *item;
|
||||
|
||||
rp = roomin(cp);
|
||||
if (rp == NULL)
|
||||
return;
|
||||
if (pl_on(ISBLIND)) {
|
||||
for (j = 0; j < rp->r_max.y; j += 1) {
|
||||
for (k = 0; k < rp->r_max.x; k += 1) {
|
||||
y = rp->r_pos.y + j;
|
||||
x = rp->r_pos.x + k;
|
||||
mvwaddch(cw, y, x, ' ');
|
||||
}
|
||||
}
|
||||
look(FALSE);
|
||||
return;
|
||||
}
|
||||
if (iswearing(R_LIGHT))
|
||||
rp->r_flags &= ~ISDARK;
|
||||
for (j = 0; j < rp->r_max.y; j += 1) {
|
||||
for (k = 0; k < rp->r_max.x; k += 1) {
|
||||
y = rp->r_pos.y + j;
|
||||
x = rp->r_pos.x + k;
|
||||
if (levtype == MAZELEV && !cansee(y, x))
|
||||
continue;
|
||||
ch = show(y, x);
|
||||
wmove(cw, y, x);
|
||||
/*
|
||||
* Figure out how to display a secret door
|
||||
*/
|
||||
if (ch == SECRETDOOR) {
|
||||
if (j == 0 || j == rp->r_max.y - 1)
|
||||
ch = '-';
|
||||
else
|
||||
ch = '|';
|
||||
}
|
||||
if (isalpha(ch)) {
|
||||
struct thing *mit;
|
||||
|
||||
item = wake_monster(y, x);
|
||||
if (item == NULL) {
|
||||
ch = FLOOR;
|
||||
mvaddch(y, x, ch);
|
||||
}
|
||||
else {
|
||||
mit = THINGPTR(item);
|
||||
if (mit->t_oldch == ' ')
|
||||
if (!rf_on(rp,ISDARK))
|
||||
mit->t_oldch = mvinch(y, x);
|
||||
if (levtype == MAZELEV)
|
||||
ch = mvinch(y, x);
|
||||
}
|
||||
}
|
||||
if (rf_on(rp,ISDARK)) {
|
||||
rch = mvwinch(cw, y, x);
|
||||
if (isatrap(rch)) {
|
||||
ch = rch; /* if its a trap */
|
||||
}
|
||||
else { /* try other things */
|
||||
switch (rch) {
|
||||
case DOOR: case STAIRS: case '|':
|
||||
case '-':
|
||||
ch = rch;
|
||||
otherwise:
|
||||
ch = ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
mvwaddch(cw, y, x, ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* show:
|
||||
* returns what a certain thing will display as to the un-initiated
|
||||
*/
|
||||
show(y, x)
|
||||
int y, x;
|
||||
{
|
||||
reg char ch = winat(y, x);
|
||||
reg struct linked_list *it;
|
||||
reg struct thing *tp;
|
||||
reg struct trap *ta;
|
||||
|
||||
if (isatrap(ch)) {
|
||||
if ((ta = trap_at(y, x)) == NULL)
|
||||
return FLOOR;
|
||||
if (iswearing(R_FTRAPS))
|
||||
ta->tr_flags |= ISFOUND;
|
||||
return ((ta->tr_flags & ISFOUND) ? ta->tr_type : FLOOR);
|
||||
}
|
||||
if (ch == SECRETDOOR && iswearing(R_FTRAPS)) {
|
||||
mvaddch(y,x,DOOR);
|
||||
return DOOR;
|
||||
}
|
||||
if ((it = find_mons(y, x)) != NULL) { /* maybe a monster */
|
||||
tp = THINGPTR(it);
|
||||
if (ch == 'M' || (tp->t_flags & ISINVIS)) {
|
||||
if (ch == 'M')
|
||||
ch = tp->t_disguise;
|
||||
else if (pl_off(CANSEE)) {
|
||||
if (ch == 's')
|
||||
ch = ' '; /* shadows show as a blank */
|
||||
else
|
||||
ch = mvinch(y, x); /* hide invisibles */
|
||||
}
|
||||
}
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
|
||||
/*
|
||||
* be_trapped:
|
||||
* Hero or monster stepped on a trap.
|
||||
*/
|
||||
be_trapped(tc, th)
|
||||
struct thing *th;
|
||||
struct coord *tc;
|
||||
{
|
||||
reg struct trap *trp;
|
||||
reg int ch, ishero;
|
||||
struct linked_list *mon;
|
||||
char stuckee[35], seeit, sayso;
|
||||
|
||||
if ((trp = trap_at(tc->y, tc->x)) == NULL)
|
||||
return;
|
||||
ishero = (th == &player);
|
||||
if (ishero) {
|
||||
strcpy(stuckee, "You");
|
||||
count = running = FALSE;
|
||||
}
|
||||
else {
|
||||
sprintf(stuckee, "The %s", monsters[th->t_indx].m_name);
|
||||
}
|
||||
seeit = cansee(tc->y, tc->x);
|
||||
if (seeit)
|
||||
mvwaddch(cw, tc->y, tc->x, trp->tr_type);
|
||||
trp->tr_flags |= ISFOUND;
|
||||
sayso = TRUE;
|
||||
switch (ch = trp->tr_type) {
|
||||
case POST:
|
||||
if (ishero) {
|
||||
nlmove = TRUE;
|
||||
new_level(POSTLEV);
|
||||
}
|
||||
else
|
||||
goto goner;
|
||||
when MAZETRAP:
|
||||
if (ishero) {
|
||||
nlmove = TRUE;
|
||||
level += 1;
|
||||
new_level(MAZELEV);
|
||||
msg("You are surrounded by twisty passages!");
|
||||
}
|
||||
else
|
||||
goto goner;
|
||||
when TELTRAP:
|
||||
nlmove = TRUE;
|
||||
teleport(trp->tr_goto, th);
|
||||
when TRAPDOOR:
|
||||
if (ishero) {
|
||||
level += 1;
|
||||
new_level(NORMLEV);
|
||||
}
|
||||
else { /* monsters get lost */
|
||||
goner:
|
||||
ch = GONER;
|
||||
}
|
||||
nlmove = TRUE;
|
||||
if (seeit && sayso)
|
||||
msg("%s fell into a trap!", stuckee);
|
||||
when BEARTRAP:
|
||||
th->t_nomove += BEARTIME;
|
||||
if (seeit) {
|
||||
strcat(stuckee, (ishero ? " are" : " is"));
|
||||
msg("%s caught in a bear trap.", stuckee);
|
||||
}
|
||||
when SLEEPTRAP:
|
||||
if (ishero && pl_on(ISINVINC))
|
||||
msg("You feel momentarily dizzy.");
|
||||
else {
|
||||
if (ishero)
|
||||
th->t_nocmd += SLEEPTIME;
|
||||
else
|
||||
th->t_nomove += SLEEPTIME;
|
||||
if (seeit)
|
||||
msg("%s fall%s asleep in a strange white mist.",
|
||||
stuckee, (ishero ? "":"s"));
|
||||
}
|
||||
when ARROWTRAP: {
|
||||
int resist, ac;
|
||||
struct stats *it;
|
||||
|
||||
stuckee[0] = tolower(stuckee[0]);
|
||||
it = &th->t_stats;
|
||||
if (ishero && cur_armor != NULL)
|
||||
ac = cur_armor->o_ac;
|
||||
else
|
||||
ac = it->s_arm;
|
||||
resist = ac + getpdex(it, FALSE);
|
||||
if (ishero && pl_on(ISINVINC))
|
||||
resist = -100; /* invincible is impossible to hit */
|
||||
if (swing(3 + (level / 4), resist, 1)) {
|
||||
if (seeit)
|
||||
msg("%sAn arrow shot %s.", (ishero ? "Oh no! " : ""),
|
||||
stuckee);
|
||||
if (ishero)
|
||||
chg_hpt(-roll(1,6),FALSE,K_ARROW);
|
||||
else {
|
||||
it->s_hpt -= roll(1,6);
|
||||
if (it->s_hpt < 1) {
|
||||
sayso = FALSE;
|
||||
goto goner;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
struct linked_list *item;
|
||||
struct object *arrow;
|
||||
|
||||
if (seeit)
|
||||
msg("An arrow shoots past %s.", stuckee);
|
||||
item = new_thing(FALSE, WEAPON, ARROW);
|
||||
arrow = OBJPTR(item);
|
||||
arrow->o_hplus = 3;
|
||||
arrow->o_dplus = rnd(2);
|
||||
arrow->o_count = 1;
|
||||
arrow->o_pos = th->t_pos;
|
||||
fall(item, FALSE);
|
||||
}
|
||||
}
|
||||
when DARTTRAP: {
|
||||
int resist, ac;
|
||||
struct stats *it;
|
||||
|
||||
stuckee[0] = tolower(stuckee[0]);
|
||||
it = &th->t_stats;
|
||||
if (ishero && cur_armor != NULL)
|
||||
ac = cur_armor->o_ac;
|
||||
else
|
||||
ac = it->s_arm;
|
||||
resist = ac + getpdex(it, FALSE);
|
||||
if (ishero && pl_on(ISINVINC))
|
||||
resist = -100; /* invincible is impossible to hit */
|
||||
if (swing(3 + (level / 4), resist, 0)) {
|
||||
if (seeit)
|
||||
msg("A small dart just hit %s.", stuckee);
|
||||
if (ishero) {
|
||||
if (!save(VS_POISON))
|
||||
chg_abil(CON,-1,TRUE);
|
||||
if (!iswearing(R_SUSTSTR))
|
||||
chg_abil(STR,-1,TRUE);
|
||||
chg_hpt(-roll(1, 4),FALSE,K_DART);
|
||||
}
|
||||
else {
|
||||
if (!save_throw(VS_POISON, th))
|
||||
it->s_ef.a_str -= 1;
|
||||
it->s_hpt -= roll(1, 4);
|
||||
if (it->s_hpt < 1) {
|
||||
sayso = FALSE;
|
||||
goto goner;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (seeit)
|
||||
msg("A small dart whizzes by %s.", stuckee);
|
||||
}
|
||||
when POOL:
|
||||
if (!ishero && rnd(100) < 10) {
|
||||
if (seeit)
|
||||
msg("The %s drowns !!", stuckee);
|
||||
goto goner;
|
||||
}
|
||||
if ((trp->tr_flags & ISGONE) && rnd(100) < 10) {
|
||||
nlmove = TRUE;
|
||||
if (rnd(100) < 15)
|
||||
teleport(rndspot); /* teleport away */
|
||||
else if(rnd(100) < 15 && level > 2) {
|
||||
level -= rnd(2) + 1;
|
||||
new_level(NORMLEV);
|
||||
msg("You here a faint groan from below.");
|
||||
}
|
||||
else if(rnd(100) < 40) {
|
||||
level += rnd(4);
|
||||
new_level(NORMLEV);
|
||||
msg("You find yourself in strange surroundings.");
|
||||
}
|
||||
else if(rnd(100) < 6 && pl_off(ISINVINC)) {
|
||||
msg("Oh no!!! You drown in the pool!!! --More--");
|
||||
wait_for(cw, ' ');
|
||||
death(K_POOL);
|
||||
}
|
||||
else
|
||||
nlmove = FALSE;
|
||||
}
|
||||
}
|
||||
flushinp(); /* flush typeahead */
|
||||
return ch;
|
||||
}
|
||||
|
||||
/*
|
||||
* dip_it:
|
||||
* Dip an object into a magic pool
|
||||
*/
|
||||
dip_it()
|
||||
{
|
||||
reg struct linked_list *what;
|
||||
reg struct object *ob;
|
||||
reg struct trap *tp;
|
||||
reg int wh;
|
||||
|
||||
tp = trap_at(hero.y,hero.x);
|
||||
if (tp == NULL || inpool == FALSE || (tp->tr_flags & ISGONE))
|
||||
return;
|
||||
|
||||
if ((what = get_item("dip",0)) == NULL)
|
||||
return;
|
||||
ob = OBJPTR(what);
|
||||
mpos = 0;
|
||||
/*
|
||||
* If hero is trying to dip an object OTHER than his
|
||||
* current weapon, make sure that he could drop his
|
||||
* current weapon
|
||||
*/
|
||||
if (ob != cur_weapon) {
|
||||
if (cur_weapon != NULL && o_on(cur_weapon, ISCURSED)) {
|
||||
msg("You are unable to release your weapon.");
|
||||
after = FALSE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (ob == cur_armor) {
|
||||
msg("You have to take off your armor before you can dip it.");
|
||||
after = FALSE;
|
||||
return;
|
||||
}
|
||||
else if (ob == cur_ring[LEFT] || ob == cur_ring[RIGHT]) {
|
||||
msg("You have to take that ring off before you can dip it.");
|
||||
after = FALSE;
|
||||
return;
|
||||
}
|
||||
wh = ob->o_which;
|
||||
tp->tr_flags |= ISGONE;
|
||||
if (ob != NULL && o_off(ob,ISPROT)) {
|
||||
setoflg(ob,ISKNOW);
|
||||
switch(ob->o_type) {
|
||||
case WEAPON:
|
||||
if(rnd(100) < 20) { /* enchant weapon here */
|
||||
if (o_off(ob,ISCURSED)) {
|
||||
ob->o_hplus += 1;
|
||||
ob->o_dplus += 1;
|
||||
}
|
||||
else { /* weapon was prev cursed here */
|
||||
ob->o_hplus = rnd(2);
|
||||
ob->o_dplus = rnd(2);
|
||||
}
|
||||
resoflg(ob,ISCURSED);
|
||||
}
|
||||
else if(rnd(100) < 10) { /* curse weapon here */
|
||||
if (o_off(ob,ISCURSED)) {
|
||||
ob->o_hplus = -(rnd(2)+1);
|
||||
ob->o_dplus = -(rnd(2)+1);
|
||||
}
|
||||
else { /* if already cursed */
|
||||
ob->o_hplus--;
|
||||
ob->o_dplus--;
|
||||
}
|
||||
setoflg(ob,ISCURSED);
|
||||
}
|
||||
msg("The %s glows for a moment.",w_magic[wh].mi_name);
|
||||
when ARMOR:
|
||||
if (rnd(100) < 30) { /* enchant armor */
|
||||
if(o_off(ob,ISCURSED))
|
||||
ob->o_ac -= rnd(2) + 1;
|
||||
else
|
||||
ob->o_ac = -rnd(3)+ armors[wh].a_class;
|
||||
resoflg(ob,ISCURSED);
|
||||
}
|
||||
else if(rnd(100) < 15){ /* curse armor */
|
||||
if (o_off(ob,ISCURSED))
|
||||
ob->o_ac = rnd(3)+ armors[wh].a_class;
|
||||
else
|
||||
ob->o_ac += rnd(2) + 1;
|
||||
setoflg(ob,ISCURSED);
|
||||
}
|
||||
msg("The %s glows for a moment.",a_magic[wh].mi_name);
|
||||
when STICK: {
|
||||
int i;
|
||||
struct rod *rd;
|
||||
|
||||
i = rnd(8) + 1;
|
||||
if(rnd(100) < 25) /* add charges */
|
||||
ob->o_charges += i;
|
||||
else if(rnd(100) < 10) { /* remove charges */
|
||||
if ((ob->o_charges -= i) < 0)
|
||||
ob->o_charges = 0;
|
||||
}
|
||||
ws_know[wh] = TRUE;
|
||||
rd = &ws_stuff[wh];
|
||||
msg("The %s %s glows for a moment.",rd->ws_made,rd->ws_type);
|
||||
}
|
||||
when SCROLL:
|
||||
s_know[wh] = TRUE;
|
||||
msg("The '%s' scroll unfurls.",s_names[wh]);
|
||||
when POTION:
|
||||
p_know[wh] = TRUE;
|
||||
msg("The %s potion bubbles for a moment.",p_colors[wh]);
|
||||
when RING:
|
||||
r_know[wh] = TRUE;
|
||||
if (magring(ob)) {
|
||||
if(rnd(100) < 25) { /* enchant ring */
|
||||
if (o_off(ob,ISCURSED))
|
||||
ob->o_ac += rnd(2) + 1;
|
||||
else
|
||||
ob->o_ac = rnd(2) + 1;
|
||||
resoflg(ob,ISCURSED);
|
||||
}
|
||||
else if(rnd(100) < 10) { /* curse ring */
|
||||
if (o_off(ob,ISCURSED))
|
||||
ob->o_ac = -(rnd(2) + 1);
|
||||
else
|
||||
ob->o_ac -= (rnd(2) + 1);
|
||||
setoflg(ob,ISCURSED);
|
||||
}
|
||||
}
|
||||
msg("The %s ring vibrates for a moment.",r_stones[wh]);
|
||||
otherwise:
|
||||
msg("The pool bubbles for a moment.");
|
||||
}
|
||||
}
|
||||
cur_weapon = ob; /* hero has to weild item to dip it */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* trap_at:
|
||||
* Find the trap at (y,x) on screen.
|
||||
*/
|
||||
struct trap *
|
||||
trap_at(y, x)
|
||||
int y, x;
|
||||
{
|
||||
reg struct trap *tp, *ep;
|
||||
|
||||
ep = &traps[ntraps];
|
||||
for (tp = traps; tp < ep; tp += 1)
|
||||
if (tp->tr_pos.y == y && tp->tr_pos.x == x)
|
||||
break;
|
||||
if (tp >= ep)
|
||||
tp = NULL;
|
||||
return tp;
|
||||
}
|
||||
|
||||
/*
|
||||
* rndmove:
|
||||
* move in a random direction if the monster/person is confused
|
||||
*/
|
||||
struct coord *
|
||||
rndmove(who)
|
||||
struct thing *who;
|
||||
{
|
||||
reg int x, y, ex, ey, ch;
|
||||
int nopen = 0;
|
||||
struct linked_list *item;
|
||||
static struct coord ret; /* what we will be returning */
|
||||
static struct coord dest;
|
||||
|
||||
ret = who->t_pos;
|
||||
/*
|
||||
* Now go through the spaces surrounding the player and
|
||||
* set that place in the array to true if the space can be
|
||||
* moved into
|
||||
*/
|
||||
ey = ret.y + 1;
|
||||
ex = ret.x + 1;
|
||||
for (y = who->t_pos.y - 1; y <= ey; y += 1) {
|
||||
for (x = who->t_pos.x - 1; x <= ex; x += 1) {
|
||||
if (!cordok(y, x))
|
||||
continue;
|
||||
ch = winat(y, x);
|
||||
if (step_ok(ch)) {
|
||||
dest.y = y;
|
||||
dest.x = x;
|
||||
if (!diag_ok(&who->t_pos, &dest))
|
||||
continue;
|
||||
if (ch == SCROLL && who != &player) {
|
||||
/*
|
||||
* check for scare monster scrolls
|
||||
*/
|
||||
item = find_obj(y, x);
|
||||
if (item != NULL && (OBJPTR(item))->o_which == S_SCARE)
|
||||
continue;
|
||||
}
|
||||
if (rnd(++nopen) == 0)
|
||||
ret = dest;
|
||||
}
|
||||
}
|
||||
}
|
||||
return &ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* isatrap:
|
||||
* Returns TRUE if this character is some kind of trap
|
||||
*/
|
||||
isatrap(ch)
|
||||
char ch;
|
||||
{
|
||||
switch(ch) {
|
||||
case POST:
|
||||
case DARTTRAP:
|
||||
case POOL:
|
||||
case TELTRAP:
|
||||
case TRAPDOOR:
|
||||
case ARROWTRAP:
|
||||
case SLEEPTRAP:
|
||||
case BEARTRAP:
|
||||
case MAZETRAP:
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
38
srogue/ncx.h
Normal file
38
srogue/ncx.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
/*
|
||||
# define CBREAK FALSE
|
||||
# define _IOSTRG 01
|
||||
*/
|
||||
|
||||
/*
|
||||
* mv functions
|
||||
*/
|
||||
#define mvwaddch(win,y,x,ch) VOID(wmove(win,y,x)==ERR?ERR:waddch(win,ch))
|
||||
#define mvwgetch(win,y,x,ch) VOID(wmove(win,y,x)==ERR?ERR:wgetch(win,ch))
|
||||
#define mvwaddstr(win,y,x,str) VOID(wmove(win,y,x)==ERR?ERR:waddstr(win,str))
|
||||
#define mvwgetstr(win,y,x,str) VOID(wmove(win,y,x)==ERR?ERR:wgetstr(win,str))
|
||||
#define mvwinch(win,y,x) VOID(wmove(win,y,x) == ERR ? ERR : winch(win))
|
||||
#define mvaddch(y,x,ch) mvwaddch(stdscr,y,x,ch)
|
||||
#define mvgetch(y,x,ch) mvwgetch(stdscr,y,x,ch)
|
||||
#define mvaddstr(y,x,str) mvwaddstr(stdscr,y,x,str)
|
||||
#define mvgetstr(y,x,str) mvwgetstr(stdscr,y,x,str)
|
||||
#define mvinch(y,x) mvwinch(stdscr,y,x)
|
||||
|
||||
/*
|
||||
* psuedo functions
|
||||
*/
|
||||
|
||||
#define clearok(win,bf) (win->_clear = bf)
|
||||
#define leaveok(win,bf) (win->_leave = bf)
|
||||
#define scrollok(win,bf) (win->_scroll = bf)
|
||||
#define getyx(win,y,x) y = win->_cury, x = win->_curx
|
||||
#define winch(win) (win->_y[win->_cury][win->_curx])
|
||||
|
||||
WINDOW *initscr(), *newwin();
|
||||
253
srogue/new_leve.c
Normal file
253
srogue/new_leve.c
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
/*
|
||||
* Do anything associated with a new dungeon level
|
||||
*
|
||||
* @(#)new_level.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "rogue.h"
|
||||
#include "rogue.ext"
|
||||
|
||||
/*
|
||||
* new_level:
|
||||
* Dig and draw a new level
|
||||
*/
|
||||
new_level(ltype)
|
||||
int ltype;
|
||||
{
|
||||
register i;
|
||||
register char ch;
|
||||
struct coord traploc;
|
||||
struct room *rp;
|
||||
|
||||
if (level > max_level)
|
||||
max_level = level;
|
||||
|
||||
wclear(cw);
|
||||
wclear(mw);
|
||||
clear();
|
||||
|
||||
isfight = FALSE;
|
||||
levtype = ltype;
|
||||
|
||||
free_list(mlist); /* free monster list */
|
||||
|
||||
if (levtype == POSTLEV)
|
||||
do_post();
|
||||
else {
|
||||
lev_mon(); /* fill in monster list */
|
||||
|
||||
if (levtype == MAZELEV)
|
||||
do_maze();
|
||||
else { /* normal levels */
|
||||
do_rooms(); /* Draw rooms */
|
||||
do_passages(); /* Draw passages */
|
||||
}
|
||||
no_food++;
|
||||
put_things(); /* Place objects (if any) */
|
||||
}
|
||||
/*
|
||||
* Place the staircase down.
|
||||
*/
|
||||
stairs = *rnd_pos(&rooms[rnd_room()]);
|
||||
mvaddch(stairs.y, stairs.x, STAIRS);
|
||||
ntraps = 0;
|
||||
|
||||
if (levtype == NORMLEV)
|
||||
{
|
||||
struct trap *trp, *maxtrp;
|
||||
|
||||
/* Place the traps for normal levels only */
|
||||
|
||||
if (rnd(10) < level)
|
||||
{
|
||||
ntraps = rnd(level / 4) + 1;
|
||||
|
||||
if (ntraps > MAXTRAPS)
|
||||
ntraps = MAXTRAPS;
|
||||
|
||||
maxtrp = &traps[ntraps];
|
||||
for (trp = &traps[0]; trp < maxtrp; trp++)
|
||||
{
|
||||
again:
|
||||
switch(rnd(TYPETRAPS + 1))
|
||||
{
|
||||
case 0:
|
||||
if (rnd(100) > 25)
|
||||
goto again;
|
||||
else
|
||||
ch = POST;
|
||||
|
||||
when 1: ch = TRAPDOOR;
|
||||
when 2: ch = BEARTRAP;
|
||||
when 3: ch = SLEEPTRAP;
|
||||
when 4: ch = ARROWTRAP;
|
||||
when 5: ch = TELTRAP;
|
||||
when 6: ch = DARTTRAP;
|
||||
when 7: ch = MAZETRAP;
|
||||
when 8:
|
||||
case 9:
|
||||
if (rnd(100) > 80)
|
||||
goto again;
|
||||
else
|
||||
ch = POOL;
|
||||
}
|
||||
trp->tr_flags = 0;
|
||||
traploc = *rnd_pos(&rooms[rnd_room()]);
|
||||
mvaddch(traploc.y,traploc.x,ch);
|
||||
trp->tr_type = ch;
|
||||
trp->tr_pos = traploc;
|
||||
|
||||
if (ch == POOL || ch == POST)
|
||||
trp->tr_flags |= ISFOUND;
|
||||
|
||||
if (ch==TELTRAP && rnd(100)<20 && trp<maxtrp-1)
|
||||
{
|
||||
struct coord newloc;
|
||||
|
||||
newloc = *rnd_pos(&rooms[rnd_room()]);
|
||||
trp->tr_goto = newloc;
|
||||
trp++;
|
||||
trp->tr_goto = traploc;
|
||||
trp->tr_type = TELTRAP;
|
||||
trp->tr_pos = newloc;
|
||||
mvaddch(newloc.y, newloc.x, TELTRAP);
|
||||
}
|
||||
else
|
||||
trp->tr_goto = rndspot;
|
||||
}
|
||||
}
|
||||
}
|
||||
do
|
||||
{
|
||||
rp = &rooms[rnd_room()];
|
||||
hero = *rnd_pos(rp);
|
||||
} while(levtype==MAZELEV&&DISTANCE(hero.y,hero.x,stairs.y,stairs.x)<10);
|
||||
|
||||
player.t_room = rp;
|
||||
player.t_oldch = mvinch(hero.y, hero.x);
|
||||
light(&hero);
|
||||
mvwaddch(cw,hero.y,hero.x,PLAYER);
|
||||
nochange = FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* rnd_room:
|
||||
* Pick a room that is really there
|
||||
*/
|
||||
rnd_room()
|
||||
{
|
||||
register rm;
|
||||
|
||||
if (levtype != NORMLEV)
|
||||
rm = 0;
|
||||
else
|
||||
{
|
||||
do {
|
||||
rm = rnd(MAXROOMS);
|
||||
} while (rf_on(&rooms[rm],ISGONE));
|
||||
}
|
||||
return rm;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* put_things:
|
||||
* put potions and scrolls on this level
|
||||
*/
|
||||
|
||||
put_things()
|
||||
{
|
||||
register i, cnt, rm;
|
||||
struct linked_list *item;
|
||||
struct object *cur;
|
||||
struct coord tp;
|
||||
|
||||
/* Throw away stuff left on the previous level (if anything) */
|
||||
|
||||
free_list(lvl_obj);
|
||||
|
||||
/* The only way to get new stuff is to go down into the dungeon. */
|
||||
|
||||
if (goingup())
|
||||
return;
|
||||
|
||||
/* Do MAXOBJ attempts to put things on a level */
|
||||
|
||||
for (i = 0; i < MAXOBJ; i++)
|
||||
{
|
||||
if (rnd(100) < 40)
|
||||
{
|
||||
item = new_thing(FALSE, ANYTHING);
|
||||
attach(lvl_obj, item);
|
||||
cur = OBJPTR(item);
|
||||
cnt = 0;
|
||||
do {
|
||||
/* skip treasure rooms */
|
||||
rm = rnd_room();
|
||||
if (++cnt > 500)
|
||||
break;
|
||||
} while(rf_on(&rooms[rm],ISTREAS) && levtype!=MAZELEV);
|
||||
|
||||
tp = *rnd_pos(&rooms[rm]);
|
||||
mvaddch(tp.y, tp.x, cur->o_type);
|
||||
cur->o_pos = tp;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If he is really deep in the dungeon and he hasn't found the
|
||||
* amulet yet, put it somewhere on the ground
|
||||
*/
|
||||
if (level >= AMLEVEL && !amulet && rnd(100) < 70)
|
||||
{
|
||||
item = new_thing(FALSE, AMULET, 0);
|
||||
attach(lvl_obj, item);
|
||||
cur = OBJPTR(item);
|
||||
rm = rnd_room();
|
||||
tp = *rnd_pos(&rooms[rm]);
|
||||
mvaddch(tp.y, tp.x, cur->o_type);
|
||||
cur->o_pos = tp;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXROOMS; i++) /* loop through all */
|
||||
{
|
||||
if (rf_on(&rooms[i],ISTREAS)) /* treasure rooms */
|
||||
{
|
||||
int numthgs, isfood;
|
||||
|
||||
numthgs = rnd(level / 3) + 6;
|
||||
while (numthgs-- >= 0)
|
||||
{
|
||||
isfood = TRUE;
|
||||
do {
|
||||
item = new_thing(TRUE, ANYTHING);
|
||||
cur = OBJPTR(item);
|
||||
|
||||
/* dont create food for */
|
||||
if (cur->o_type == FOOD)
|
||||
discard(item);
|
||||
|
||||
/* treasure rooms */
|
||||
else
|
||||
isfood = FALSE;
|
||||
|
||||
} while (isfood);
|
||||
|
||||
attach(lvl_obj, item);
|
||||
tp = *rnd_pos(&rooms[i]);
|
||||
mvaddch(tp.y, tp.x, cur->o_type);
|
||||
cur->o_pos = tp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
122
srogue/newterm.c
Normal file
122
srogue/newterm.c
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "rogue.h"
|
||||
|
||||
extern SGTTY _tty, _res_flg;
|
||||
extern bool NONL;
|
||||
|
||||
raw()
|
||||
{
|
||||
/*
|
||||
VERSION 5.0
|
||||
_tty.c_lflag &= ~ICANON;
|
||||
_tty.c_cc[VMIN] = 1;
|
||||
_tty.c_cc[VTIME] = 255;
|
||||
_tty.c_oflag &= ~OPOST;
|
||||
*/
|
||||
_rawmode = TRUE;
|
||||
_tty.sg_flags |= CBREAK;
|
||||
ioctl(_tty_ch, TIOCSETP, &_tty);
|
||||
}
|
||||
|
||||
|
||||
noraw()
|
||||
{
|
||||
/*
|
||||
VERSION 5.0
|
||||
_tty.c_lflag |= ICANON;
|
||||
_tty.c_cc[VMIN] = _res_flg.c_cc[VMIN];
|
||||
_tty.c_cc[VTIME] = _res_flg.c_cc[VTIME];
|
||||
_tty.c_oflag |= OPOST;
|
||||
*/
|
||||
_rawmode = FALSE;
|
||||
_tty.sg_flags &= ~CBREAK;
|
||||
ioctl(_tty_ch, TIOCSETP, &_tty);
|
||||
}
|
||||
|
||||
|
||||
crmode()
|
||||
{
|
||||
/*
|
||||
VERSION 5.0
|
||||
_tty.c_lflag &= ~ICANON;
|
||||
_tty.c_oflag |= ONLCR;
|
||||
_tty.c_cc[VMIN] = 1;
|
||||
_tty.c_cc[VTIME]=255;
|
||||
*/
|
||||
_rawmode = TRUE;
|
||||
_tty.sg_flags |= (CBREAK | CRMOD);
|
||||
ioctl(_tty_ch, TIOCSETP, &_tty);
|
||||
}
|
||||
|
||||
|
||||
nocrmode()
|
||||
{
|
||||
/*
|
||||
_tty.c_lflag |= ICANON;
|
||||
_tty.c_cc[VMIN]=_res_flg.c_cc[VMIN];
|
||||
_tty.c_cc[VTIME]=_res_flg.c_cc[VTIME];
|
||||
*/
|
||||
_rawmode = FALSE;
|
||||
_tty.sg_flags &= ~CBREAK;
|
||||
ioctl(_tty_ch, TIOCSETP, &_tty);
|
||||
}
|
||||
|
||||
|
||||
echo()
|
||||
{
|
||||
_tty.sg_flags |= ECHO;
|
||||
_echoit=TRUE;
|
||||
ioctl(_tty_ch, TIOCSETP, &_tty);
|
||||
}
|
||||
|
||||
noecho()
|
||||
{
|
||||
_tty.sg_flags &= ~ECHO;
|
||||
_echoit = FALSE;
|
||||
ioctl(_tty_ch, TIOCSETP, &_tty);
|
||||
}
|
||||
|
||||
|
||||
nl()
|
||||
{
|
||||
/*
|
||||
VERSION 5.0
|
||||
_tty.c_iflag |= ICRNL;
|
||||
_tty.c_oflag |= ONLCR;
|
||||
*/
|
||||
_tty.sg_flags |= CRMOD;
|
||||
NONL = TRUE;
|
||||
ioctl(_tty_ch, TIOCSETP, &_tty);
|
||||
}
|
||||
|
||||
|
||||
nonl()
|
||||
{
|
||||
/*
|
||||
VERSION 5.0
|
||||
_tty.c_iflag &= ~ICRNL;
|
||||
_tty.c_oflag &= ~ONLCR;
|
||||
*/
|
||||
_tty.sg_flags &= ~CRMOD;
|
||||
NONL = FALSE;
|
||||
ioctl(_tty_ch, TIOCSETP, &_tty);
|
||||
}
|
||||
|
||||
savetty()
|
||||
{
|
||||
ioctl(_tty_ch, TIOCGETP, &_tty);
|
||||
_res_flg = _tty;
|
||||
}
|
||||
|
||||
resetty()
|
||||
{
|
||||
_tty = _res_flg;
|
||||
ioctl(_tty_ch, TIOCSETP, &_tty);
|
||||
}
|
||||
230
srogue/options.c
Normal file
230
srogue/options.c
Normal file
|
|
@ -0,0 +1,230 @@
|
|||
/*
|
||||
* This file has all the code for the option command.
|
||||
*
|
||||
* @(#)options.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include <termios.h>
|
||||
#include <ctype.h>
|
||||
#include "rogue.h"
|
||||
#include "rogue.ext"
|
||||
|
||||
extern struct termios terminal;
|
||||
|
||||
/*
|
||||
* description of an option and what to do with it
|
||||
*/
|
||||
struct optstruct {
|
||||
char *o_name; /* option name */
|
||||
char *o_prompt; /* prompt for interactive entry */
|
||||
char *o_opt; /* pointer to thing to set */
|
||||
};
|
||||
|
||||
typedef struct optstruct OPTION;
|
||||
|
||||
int put_str(), get_str();
|
||||
|
||||
OPTION optlist[] = {
|
||||
{ "name", "Name: ", whoami },
|
||||
{ "fruit", "Fruit: ", fruit },
|
||||
{ "file", "Save file: ", file_name }
|
||||
};
|
||||
#define NUM_OPTS (sizeof optlist / sizeof (OPTION))
|
||||
|
||||
/*
|
||||
* print and then set options from the terminal
|
||||
*/
|
||||
option()
|
||||
{
|
||||
reg OPTION *op;
|
||||
reg int wh;
|
||||
|
||||
wclear(hw);
|
||||
touchwin(hw);
|
||||
/*
|
||||
* Display current values of options
|
||||
*/
|
||||
for (op = optlist; op < &optlist[NUM_OPTS]; op++) {
|
||||
wh = op - optlist;
|
||||
mvwaddstr(hw, wh, 0, op->o_prompt);
|
||||
mvwaddstr(hw, wh, 16, op->o_opt);
|
||||
}
|
||||
/*
|
||||
* Set values
|
||||
*/
|
||||
wmove(hw, 0, 0);
|
||||
for (op = optlist; op < &optlist[NUM_OPTS]; op++) {
|
||||
wmove(hw, op - optlist, 16);
|
||||
if ((wh = get_str(op->o_opt, hw))) {
|
||||
if (wh == QUIT)
|
||||
break;
|
||||
else if (op > optlist) {
|
||||
wmove(hw, op - optlist, 0);
|
||||
op -= 2;
|
||||
}
|
||||
else {
|
||||
putchar(7);
|
||||
wmove(hw, 0, 0);
|
||||
op -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Switch back to original screen
|
||||
*/
|
||||
dbotline(hw,spacemsg);
|
||||
restscr(cw);
|
||||
after = FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_str:
|
||||
* Set a string option
|
||||
*/
|
||||
#define CTRLB 2
|
||||
get_str(opt, awin)
|
||||
char *opt;
|
||||
WINDOW *awin;
|
||||
{
|
||||
reg char *sp;
|
||||
reg int c, oy, ox;
|
||||
char buf[LINLEN];
|
||||
|
||||
draw(awin);
|
||||
getyx(awin, oy, ox);
|
||||
/*
|
||||
* loop reading in the string, and put it in a temporary buffer
|
||||
*/
|
||||
for (sp = buf; (c=wgetch(awin)) != '\n' && c != '\r' && c != ESCAPE;
|
||||
wclrtoeol(awin), draw(awin)) {
|
||||
if (( (int)sp - (int)buf ) >= 50) {
|
||||
*sp = '\0'; /* line was too long */
|
||||
strucpy(opt,buf,strlen(buf));
|
||||
mvwaddstr(awin, 0, 0, "Name was truncated --More--");
|
||||
wclrtoeol(awin);
|
||||
draw(awin);
|
||||
wait_for(awin, ' ');
|
||||
mvwprintw(awin, 0, 0, "Called: %s",opt);
|
||||
draw(awin);
|
||||
return NORM;
|
||||
}
|
||||
if (c == -1)
|
||||
continue;
|
||||
else if(c == terminal.c_cc[VERASE]) { /* process erase char */
|
||||
if (sp > buf) {
|
||||
reg int i;
|
||||
|
||||
sp--;
|
||||
for (i = strlen(unctrl(*sp)); i; i--)
|
||||
waddch(awin, '\b');
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if (c == terminal.c_cc[VKILL]) { /* process kill character */
|
||||
sp = buf;
|
||||
wmove(awin, oy, ox);
|
||||
continue;
|
||||
}
|
||||
else if (sp == buf) {
|
||||
if (c == CTRLB) /* CTRL - B */
|
||||
break;
|
||||
if (c == '~') {
|
||||
strcpy(buf, home);
|
||||
waddstr(awin, home);
|
||||
sp += strlen(home);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
*sp++ = c;
|
||||
waddstr(awin, unctrl(c));
|
||||
}
|
||||
*sp = '\0';
|
||||
if (sp > buf) /* only change option if something was typed */
|
||||
strucpy(opt, buf, strlen(buf));
|
||||
wmove(awin, oy, ox);
|
||||
waddstr(awin, opt);
|
||||
waddstr(awin, "\n\r");
|
||||
draw(awin);
|
||||
if (awin == cw)
|
||||
mpos += sp - buf;
|
||||
if (c == CTRLB)
|
||||
return MINUS;
|
||||
if (c == ESCAPE)
|
||||
return QUIT;
|
||||
return NORM;
|
||||
}
|
||||
|
||||
/*
|
||||
* parse_opts:
|
||||
* Parse options from string, usually taken from the environment.
|
||||
* the string is a series of comma seperated values, with strings
|
||||
* being "name=....", with the string being defined up to a comma
|
||||
* or the end of the entire option string.
|
||||
*/
|
||||
|
||||
parse_opts(str)
|
||||
char *str;
|
||||
{
|
||||
reg char *sp;
|
||||
reg OPTION *op;
|
||||
reg int len;
|
||||
|
||||
while (*str) {
|
||||
for (sp = str; isalpha(*sp); sp++) /* get option name */
|
||||
continue;
|
||||
len = sp - str;
|
||||
for (op = optlist; op < &optlist[NUM_OPTS]; op++) {
|
||||
if (EQSTR(str, op->o_name, len)) {
|
||||
reg char *start;
|
||||
|
||||
for (str = sp + 1; *str == '='; str++)
|
||||
continue;
|
||||
if (*str == '~') {
|
||||
strcpy(op->o_opt, home);
|
||||
start = op->o_opt + strlen(home);
|
||||
while (*++str == '/')
|
||||
continue;
|
||||
}
|
||||
else
|
||||
start = (char *) op->o_opt;
|
||||
for (sp = str + 1; *sp && *sp != ','; sp++)
|
||||
continue;
|
||||
strucpy(start, str, sp - str);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* skip to start of next option name
|
||||
*/
|
||||
while (*sp && !isalpha(*sp))
|
||||
sp++;
|
||||
str = sp;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* copy string using unctrl for things
|
||||
*/
|
||||
strucpy(s1, s2, len)
|
||||
char *s1, *s2;
|
||||
int len;
|
||||
{
|
||||
reg char *sp;
|
||||
|
||||
while (len-- > 0) {
|
||||
strcpy(s1, (sp = unctrl(*s2)));
|
||||
s1 += strlen(sp);
|
||||
s2++;
|
||||
}
|
||||
*s1 = '\0';
|
||||
}
|
||||
475
srogue/pack.c
Normal file
475
srogue/pack.c
Normal file
|
|
@ -0,0 +1,475 @@
|
|||
/*
|
||||
* Routines to deal with the pack
|
||||
*
|
||||
* @(#)pack.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include "rogue.h"
|
||||
#include "rogue.ext"
|
||||
|
||||
/*
|
||||
* add_pack:
|
||||
* Pick up an object and add it to the pack. If the argument
|
||||
* is non-null use it as the linked_list pointer instead of
|
||||
* getting it off the ground.
|
||||
*/
|
||||
add_pack(item, silent)
|
||||
struct linked_list *item;
|
||||
bool silent;
|
||||
{
|
||||
reg struct linked_list *ip, *lp;
|
||||
reg struct object *obj, *op;
|
||||
bool from_floor;
|
||||
char delchar;
|
||||
|
||||
if (player.t_room == NULL)
|
||||
delchar = PASSAGE;
|
||||
else
|
||||
delchar = FLOOR;
|
||||
if (item == NULL) {
|
||||
from_floor = TRUE;
|
||||
if ((item = find_obj(hero.y, hero.x)) == NULL) {
|
||||
mpos = 0;
|
||||
msg("That object must have been an illusion.");
|
||||
mvaddch(hero.y, hero.x, delchar);
|
||||
return FALSE;
|
||||
}
|
||||
/*
|
||||
* Check for scare monster scrolls
|
||||
*/
|
||||
obj = OBJPTR(item);
|
||||
if (obj->o_type == SCROLL && obj->o_which == S_SCARE) {
|
||||
if (o_on(obj,ISFOUND)) {
|
||||
msg("The scroll turns to dust as you pick it up.");
|
||||
detach(lvl_obj, item);
|
||||
discard(item);
|
||||
mvaddch(hero.y, hero.x, delchar);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
from_floor = FALSE;
|
||||
obj = OBJPTR(item);
|
||||
/*
|
||||
* See if this guy can carry any more weight
|
||||
*/
|
||||
if (itemweight(obj) + him->s_pack > him->s_carry) {
|
||||
msg("You can't carry that %s.", obj->o_typname);
|
||||
return FALSE;
|
||||
}
|
||||
/*
|
||||
* Check if there is room
|
||||
*/
|
||||
if (packvol + obj->o_vol > V_PACK) {
|
||||
msg("That %s won't fit in your pack.", obj->o_typname);
|
||||
return FALSE;
|
||||
}
|
||||
if (from_floor) {
|
||||
detach(lvl_obj, item);
|
||||
mvaddch(hero.y, hero.x, delchar);
|
||||
}
|
||||
item->l_prev = NULL;
|
||||
item->l_next = NULL;
|
||||
setoflg(obj, ISFOUND);
|
||||
/*
|
||||
* start looking thru pack to find the start of items
|
||||
* with the same type.
|
||||
*/
|
||||
lp = pack;
|
||||
for (ip = pack; ip != NULL; ip = next(ip)) {
|
||||
op = OBJPTR(ip);
|
||||
/*
|
||||
* If we find a matching type then quit.
|
||||
*/
|
||||
if (op->o_type == obj->o_type)
|
||||
break;
|
||||
if (next(ip) != NULL)
|
||||
lp = next(lp); /* update "previous" entry */
|
||||
}
|
||||
/*
|
||||
* If the pack was empty, just stick the item in it.
|
||||
*/
|
||||
if (pack == NULL) {
|
||||
pack = item;
|
||||
item->l_prev = NULL;
|
||||
}
|
||||
/*
|
||||
* If we looked thru the pack, but could not find an
|
||||
* item of the same type, then stick it at the end,
|
||||
* unless it was food, then put it in front.
|
||||
*/
|
||||
else if (ip == NULL) {
|
||||
if (obj->o_type == FOOD) { /* insert food at front */
|
||||
item->l_next = pack;
|
||||
pack->l_prev = item;
|
||||
pack = item;
|
||||
item->l_prev = NULL;
|
||||
}
|
||||
else { /* insert other stuff at back */
|
||||
lp->l_next = item;
|
||||
item->l_prev = lp;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Here, we found at least one item of the same type.
|
||||
* Look thru these items to see if there is one of the
|
||||
* same group. If so, increment the count and throw the
|
||||
* new item away. If not, stick it at the end of the
|
||||
* items with the same type. Also keep all similar
|
||||
* objects near each other, like all identify scrolls, etc.
|
||||
*/
|
||||
else {
|
||||
struct linked_list **save;
|
||||
|
||||
while (ip != NULL && op->o_type == obj->o_type) {
|
||||
if (op->o_group == obj->o_group) {
|
||||
if (op->o_flags == obj->o_flags) {
|
||||
op->o_count++;
|
||||
discard(item);
|
||||
item = ip;
|
||||
goto picked_up;
|
||||
}
|
||||
else {
|
||||
goto around;
|
||||
}
|
||||
}
|
||||
if (op->o_which == obj->o_which) {
|
||||
if (obj->o_type == FOOD)
|
||||
ip = next(ip);
|
||||
break;
|
||||
}
|
||||
around:
|
||||
ip = next(ip);
|
||||
if (ip != NULL) {
|
||||
op = OBJPTR(ip);
|
||||
lp = next(lp);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* If inserting into last of group at end of pack,
|
||||
* just tack on the end.
|
||||
*/
|
||||
if (ip == NULL) {
|
||||
lp->l_next = item;
|
||||
item->l_prev = lp;
|
||||
}
|
||||
/*
|
||||
* Insert into the last of a group of objects
|
||||
* not at the end of the pack.
|
||||
*/
|
||||
else {
|
||||
save = &((ip->l_prev)->l_next);
|
||||
item->l_next = ip;
|
||||
item->l_prev = ip->l_prev;
|
||||
ip->l_prev = item;
|
||||
*save = item;
|
||||
}
|
||||
}
|
||||
picked_up:
|
||||
obj = OBJPTR(item);
|
||||
if (!silent)
|
||||
msg("%s (%c)",inv_name(obj,FALSE),pack_char(obj));
|
||||
if (obj->o_type == AMULET)
|
||||
amulet = TRUE;
|
||||
updpack(); /* new pack weight & volume */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* inventory:
|
||||
* Show what items are in a specific list
|
||||
*/
|
||||
inventory(list, type)
|
||||
struct linked_list *list;
|
||||
int type;
|
||||
{
|
||||
reg struct linked_list *pc;
|
||||
reg struct object *obj;
|
||||
reg char ch;
|
||||
reg int cnt;
|
||||
|
||||
if (list == NULL) { /* empty list */
|
||||
msg(type == 0 ? "Empty handed." : "Nothing appropriate.");
|
||||
return FALSE;
|
||||
}
|
||||
else if (next(list) == NULL) { /* only 1 item in list */
|
||||
obj = OBJPTR(list);
|
||||
msg("a) %s", inv_name(obj, FALSE));
|
||||
return TRUE;
|
||||
}
|
||||
cnt = 0;
|
||||
wclear(hw);
|
||||
for (ch = 'a', pc = list; pc != NULL; pc = next(pc), ch = npch(ch)) {
|
||||
obj = OBJPTR(pc);
|
||||
wprintw(hw,"%c) %s\n\r",ch,inv_name(obj, FALSE));
|
||||
if (++cnt > LINES - 2 && next(pc) != NULL) {
|
||||
dbotline(hw, morestr);
|
||||
cnt = 0;
|
||||
wclear(hw);
|
||||
}
|
||||
}
|
||||
dbotline(hw,spacemsg);
|
||||
restscr(cw);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* pick_up:
|
||||
* Add something to characters pack.
|
||||
*/
|
||||
pick_up(ch)
|
||||
char ch;
|
||||
{
|
||||
nochange = FALSE;
|
||||
switch(ch) {
|
||||
case GOLD:
|
||||
money();
|
||||
when ARMOR:
|
||||
case POTION:
|
||||
case FOOD:
|
||||
case WEAPON:
|
||||
case SCROLL:
|
||||
case AMULET:
|
||||
case RING:
|
||||
case STICK:
|
||||
add_pack(NULL, FALSE);
|
||||
otherwise:
|
||||
msg("That item is ethereal !!!");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* picky_inven:
|
||||
* Allow player to inventory a single item
|
||||
*/
|
||||
picky_inven()
|
||||
{
|
||||
reg struct linked_list *item;
|
||||
reg char ch, mch;
|
||||
|
||||
if (pack == NULL)
|
||||
msg("You aren't carrying anything.");
|
||||
else if (next(pack) == NULL)
|
||||
msg("a) %s", inv_name(OBJPTR(pack), FALSE));
|
||||
else {
|
||||
msg("Item: ");
|
||||
mpos = 0;
|
||||
if ((mch = readchar()) == ESCAPE) {
|
||||
msg("");
|
||||
return;
|
||||
}
|
||||
for (ch='a',item=pack; item != NULL; item=next(item),ch=npch(ch))
|
||||
if (ch == mch) {
|
||||
msg("%c) %s",ch,inv_name(OBJPTR(item), FALSE));
|
||||
return;
|
||||
}
|
||||
if (ch == 'A')
|
||||
ch = 'z';
|
||||
else
|
||||
ch -= 1;
|
||||
msg("Range is 'a' to '%c'", ch);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* get_item:
|
||||
* pick something out of a pack for a purpose
|
||||
*/
|
||||
struct linked_list *
|
||||
get_item(purpose, type)
|
||||
char *purpose;
|
||||
int type;
|
||||
{
|
||||
reg struct linked_list *obj, *pit, *savepit;
|
||||
struct object *pob;
|
||||
int ch, och, anr, cnt;
|
||||
|
||||
if (pack == NULL) {
|
||||
msg("You aren't carrying anything.");
|
||||
return NULL;
|
||||
}
|
||||
if (type != WEAPON && (type != 0 || next(pack) == NULL)) {
|
||||
/*
|
||||
* see if we have any of the type requested
|
||||
*/
|
||||
pit = pack;
|
||||
anr = 0;
|
||||
for (ch = 'a'; pit != NULL; pit = next(pit), ch = npch(ch)) {
|
||||
pob = OBJPTR(pit);
|
||||
if (type == pob->o_type || type == 0) {
|
||||
++anr;
|
||||
savepit = pit; /* save in case of only 1 */
|
||||
}
|
||||
}
|
||||
if (anr == 0) {
|
||||
msg("Nothing to %s",purpose);
|
||||
after = FALSE;
|
||||
return NULL;
|
||||
}
|
||||
else if (anr == 1) { /* only found one of 'em */
|
||||
do {
|
||||
struct object *opb;
|
||||
|
||||
opb = OBJPTR(savepit);
|
||||
msg("%s what (* for the item)?",purpose);
|
||||
och = readchar();
|
||||
if (och == '*') {
|
||||
mpos = 0;
|
||||
msg("%c) %s",pack_char(opb),inv_name(opb,FALSE));
|
||||
continue;
|
||||
}
|
||||
if (och == ESCAPE) {
|
||||
msg("");
|
||||
after = FALSE;
|
||||
return NULL;
|
||||
}
|
||||
if (isalpha(och) && och != pack_char(opb)) {
|
||||
mpos = 0;
|
||||
msg("You can't %s that !!", purpose);
|
||||
after = FALSE;
|
||||
return NULL;
|
||||
}
|
||||
} while(!isalpha(och));
|
||||
mpos = 0;
|
||||
return savepit; /* return this item */
|
||||
}
|
||||
}
|
||||
for (;;) {
|
||||
msg("%s what? (* for list): ",purpose);
|
||||
ch = readchar();
|
||||
mpos = 0;
|
||||
if (ch == ESCAPE) { /* abort if escape hit */
|
||||
after = FALSE;
|
||||
msg(""); /* clear display */
|
||||
return NULL;
|
||||
}
|
||||
if (ch == '*') {
|
||||
wclear(hw);
|
||||
pit = pack; /* point to pack */
|
||||
cnt = 0;
|
||||
for (ch='a'; pit != NULL; pit=next(pit), ch=npch(ch)) {
|
||||
pob = OBJPTR(pit);
|
||||
if (type == 0 || type == pob->o_type) {
|
||||
wprintw(hw,"%c) %s\n\r",ch,inv_name(pob,FALSE));
|
||||
if (++cnt > LINES - 2 && next(pit) != NULL) {
|
||||
cnt = 0;
|
||||
dbotline(hw, morestr);
|
||||
wclear(hw);
|
||||
}
|
||||
}
|
||||
}
|
||||
wmove(hw, LINES - 1,0);
|
||||
wprintw(hw,"%s what? ",purpose);
|
||||
draw(hw); /* write screen */
|
||||
anr = FALSE;
|
||||
do {
|
||||
ch = readchar();
|
||||
if (isalpha(ch) || ch == ESCAPE)
|
||||
anr = TRUE;
|
||||
} while(!anr); /* do till we got it right */
|
||||
restscr(cw); /* redraw orig screen */
|
||||
if (ch == ESCAPE) {
|
||||
after = FALSE;
|
||||
msg(""); /* clear top line */
|
||||
return NULL; /* all done if abort */
|
||||
}
|
||||
/* ch has item to get from pack */
|
||||
}
|
||||
for (obj=pack,och='a';obj!=NULL;obj=next(obj),och=npch(och))
|
||||
if (ch == och)
|
||||
break;
|
||||
if (obj == NULL) {
|
||||
if (och == 'A')
|
||||
och = 'z';
|
||||
else
|
||||
och -= 1;
|
||||
msg("Please specify a letter between 'a' and '%c'",och);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* pack_char:
|
||||
* Get the character of a particular item in the pack
|
||||
*/
|
||||
char
|
||||
pack_char(obj)
|
||||
struct object *obj;
|
||||
{
|
||||
reg struct linked_list *item;
|
||||
reg char c;
|
||||
|
||||
c = 'a';
|
||||
for (item = pack; item != NULL; item = next(item))
|
||||
if (OBJPTR(item) == obj)
|
||||
return c;
|
||||
else
|
||||
c = npch(c);
|
||||
return '%';
|
||||
}
|
||||
|
||||
/*
|
||||
* idenpack:
|
||||
* Identify all the items in the pack
|
||||
*/
|
||||
idenpack()
|
||||
{
|
||||
reg struct linked_list *pc;
|
||||
|
||||
for (pc = pack ; pc != NULL ; pc = next(pc))
|
||||
whatis(pc);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* del_pack:
|
||||
* Take something out of the hero's pack
|
||||
*/
|
||||
del_pack(what)
|
||||
struct linked_list *what;
|
||||
{
|
||||
reg struct object *op;
|
||||
|
||||
op = OBJPTR(what);
|
||||
cur_null(op); /* check for current stuff */
|
||||
if (op->o_count > 1) {
|
||||
op->o_count--;
|
||||
}
|
||||
else {
|
||||
detach(pack,what);
|
||||
discard(what);
|
||||
}
|
||||
updpack();
|
||||
}
|
||||
|
||||
/*
|
||||
* cur_null:
|
||||
* This updates cur_weapon etc for dropping things
|
||||
*/
|
||||
cur_null(op)
|
||||
struct object *op;
|
||||
{
|
||||
if (op == cur_weapon)
|
||||
cur_weapon = NULL;
|
||||
else if (op == cur_armor)
|
||||
cur_armor = NULL;
|
||||
else if (op == cur_ring[LEFT])
|
||||
cur_ring[LEFT] = NULL;
|
||||
else if (op == cur_ring[RIGHT])
|
||||
cur_ring[RIGHT] = NULL;
|
||||
}
|
||||
281
srogue/passages.c
Normal file
281
srogue/passages.c
Normal file
|
|
@ -0,0 +1,281 @@
|
|||
/*
|
||||
* Draw the connecting passages
|
||||
*
|
||||
* @(#)passages.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "rogue.h"
|
||||
#include "rogue.ext"
|
||||
|
||||
/*
|
||||
* do_passages:
|
||||
* Draw all the passages on a level.
|
||||
*/
|
||||
|
||||
do_passages()
|
||||
{
|
||||
reg struct rdes *r1, *r2;
|
||||
reg int i, j;
|
||||
reg int roomcount;
|
||||
static struct rdes {
|
||||
bool conn[MAXROOMS]; /* possible to connect to room i */
|
||||
bool isconn[MAXROOMS]; /* connection was 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]; 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 = r1 - rdes;
|
||||
j = 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 = r1 - rdes;
|
||||
j = r2 - rdes;
|
||||
conn(i, j);
|
||||
r1->isconn[j] = TRUE;
|
||||
r2->isconn[i] = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* conn:
|
||||
* Cconnect two rooms.
|
||||
*/
|
||||
|
||||
conn(r1, r2)
|
||||
int r1, r2;
|
||||
{
|
||||
reg struct room *rpf, *rpt;
|
||||
reg char rmt, direc;
|
||||
reg int distance, turn_spot, turn_distance, rm;
|
||||
struct coord curr, turn_delta, spos, epos;
|
||||
|
||||
if (r1 < r2) {
|
||||
rm = r1;
|
||||
if (r1 + 1 == r2)
|
||||
direc = 'r';
|
||||
else
|
||||
direc = 'd';
|
||||
}
|
||||
else {
|
||||
rm = r2;
|
||||
if (r2 + 1 == r1)
|
||||
direc = 'r';
|
||||
else
|
||||
direc = 'd';
|
||||
}
|
||||
rpf = &rooms[rm];
|
||||
/*
|
||||
* Set up the movement variables, in two cases:
|
||||
* first drawing one down.
|
||||
*/
|
||||
if (direc == 'd') {
|
||||
rmt = rm + 3; /* room # of dest */
|
||||
rpt = &rooms[rmt]; /* room pointer of dest */
|
||||
delta.x = 0; /* direction of move */
|
||||
delta.y = 1;
|
||||
spos.x = rpf->r_pos.x; /* start of move */
|
||||
spos.y = rpf->r_pos.y;
|
||||
epos.x = rpt->r_pos.x; /* end of move */
|
||||
epos.y = rpt->r_pos.y;
|
||||
if (!rf_on(rpf,ISGONE)) { /* if not gone pick door pos */
|
||||
spos.x += rnd(rpf->r_max.x-2)+1;
|
||||
spos.y += rpf->r_max.y-1;
|
||||
}
|
||||
if (!rf_on(rpt,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 (!rf_on(rpf,ISGONE)) {
|
||||
spos.x += rpf->r_max.x-1;
|
||||
spos.y += rnd(rpf->r_max.y-2)+1;
|
||||
}
|
||||
if (!rf_on(rpt,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 {
|
||||
msg("Error in connection tables.");
|
||||
}
|
||||
/*
|
||||
* Draw in the doors on either side of the passage
|
||||
* or just put #'s if the rooms are gone. Set up
|
||||
* pointers to the connected room.
|
||||
*/
|
||||
rpf->r_ptr[rpf->r_nexits] = rpt;
|
||||
if (rf_on(rpf,ISGONE)) {
|
||||
cmov(spos);
|
||||
addch('#'); /* gone "from" room */
|
||||
}
|
||||
else
|
||||
door(rpf, &spos); /* add the door */
|
||||
rpt->r_ptr[rpt->r_nexits] = rpf;
|
||||
if (rf_on(rpt,ISGONE)) {
|
||||
cmov(epos);
|
||||
addch('#'); /* gone "to" room */
|
||||
}
|
||||
else
|
||||
door(rpt, &epos); /* add door */
|
||||
/*
|
||||
* Get ready to move...
|
||||
*/
|
||||
curr.x = spos.x;
|
||||
curr.y = spos.y;
|
||||
while(distance > 0) {
|
||||
/*
|
||||
* 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-- > 0) {
|
||||
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)
|
||||
struct room *rm;
|
||||
struct coord *cp;
|
||||
{
|
||||
cmov(*cp);
|
||||
addch(rnd(10) < level - 1 && rnd(100) < 20 ? SECRETDOOR : DOOR);
|
||||
rm->r_exit[rm->r_nexits++] = *cp;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* add_pass:
|
||||
* add the passages to the current window (wizard command)
|
||||
*/
|
||||
add_pass()
|
||||
{
|
||||
reg int y, x, ch;
|
||||
|
||||
for (y = 1; y < LINES - 3; y++)
|
||||
for (x = 0; x < COLS; x++)
|
||||
if ((ch = mvinch(y, x)) == PASSAGE || ch == DOOR ||
|
||||
ch == SECRETDOOR)
|
||||
mvwaddch(cw, y, x, ch);
|
||||
}
|
||||
323
srogue/potions.c
Normal file
323
srogue/potions.c
Normal file
|
|
@ -0,0 +1,323 @@
|
|||
/*
|
||||
* Functions for dealing with potions
|
||||
*
|
||||
* @(#)potions.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "rogue.h"
|
||||
#include "rogue.ext"
|
||||
|
||||
/*
|
||||
* quaff:
|
||||
* Let the hero drink a potion
|
||||
*/
|
||||
quaff()
|
||||
{
|
||||
reg struct object *obj;
|
||||
reg struct linked_list *item, *titem;
|
||||
reg struct thing *th;
|
||||
reg int wh;
|
||||
char buf[LINLEN];
|
||||
bool bless, curse;
|
||||
|
||||
/*
|
||||
* Make certain that it is somethings that we want to drink
|
||||
*/
|
||||
if ((item = get_item("quaff", POTION)) == NULL)
|
||||
return;
|
||||
obj = OBJPTR(item);
|
||||
if (obj->o_type != POTION) {
|
||||
msg("That's undrinkable!");
|
||||
after = FALSE;
|
||||
return;
|
||||
}
|
||||
wh = obj->o_which;
|
||||
bless = o_on(obj, ISBLESS);
|
||||
curse = o_on(obj, ISCURSED);
|
||||
del_pack(item); /* get rid of it */
|
||||
|
||||
/*
|
||||
* Calculate the effect it has on the poor guy.
|
||||
*/
|
||||
switch(wh) {
|
||||
case P_CONFUSE:
|
||||
if (!bless) {
|
||||
if (pl_on(ISINVINC))
|
||||
msg("You remain level-headed.");
|
||||
else {
|
||||
chg_abil(WIS,-1,TRUE); /* confuse his mind */
|
||||
if (pl_off(ISHUH)) {
|
||||
msg("Wait, what's going on here. Huh? What? Who?");
|
||||
if (pl_on(ISHUH))
|
||||
lengthen(unconfuse,rnd(8)+HUHDURATION);
|
||||
else
|
||||
fuse(unconfuse,TRUE,rnd(8)+HUHDURATION);
|
||||
player.t_flags |= ISHUH;
|
||||
}
|
||||
}
|
||||
p_know[P_CONFUSE] = TRUE;
|
||||
}
|
||||
when P_POISON:
|
||||
if (!bless) {
|
||||
if (pl_off(ISINVINC) && !iswearing(R_SUSTSTR) &&
|
||||
!iswearing(R_SUSAB)) {
|
||||
chg_abil(CON,-1,TRUE);
|
||||
chg_abil(STR,-(rnd(3)+1),TRUE);
|
||||
msg("You feel very sick now.");
|
||||
}
|
||||
else
|
||||
msg("You feel momentarily sick.");
|
||||
p_know[P_POISON] = TRUE;
|
||||
}
|
||||
when P_HEALING:
|
||||
if (!curse) {
|
||||
heal_self(4, TRUE);
|
||||
msg("You begin to feel better.");
|
||||
if (!iswearing(R_SLOW))
|
||||
notslow(FALSE);
|
||||
sight(FALSE);
|
||||
p_know[P_HEALING] = TRUE;
|
||||
}
|
||||
when P_STRENGTH:
|
||||
if (!curse) {
|
||||
msg("You feel stronger, now. What bulging muscles!");
|
||||
chg_abil(STR,1,TRUE);
|
||||
p_know[P_STRENGTH] = TRUE;
|
||||
}
|
||||
when P_MFIND:
|
||||
/*
|
||||
* Potion of monster detection - find all monsters
|
||||
*/
|
||||
if (mlist != NULL && !curse) {
|
||||
dispmons();
|
||||
mpos = 0;
|
||||
msg("You begin to sense the presence of monsters--More--");
|
||||
p_know[P_MFIND] = TRUE;
|
||||
wait_for(cw,' ');
|
||||
msg(""); /* clear line */
|
||||
}
|
||||
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 && !curse) {
|
||||
struct linked_list *mobj;
|
||||
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)) {
|
||||
show = TRUE;
|
||||
mvwaddch(hw, tp->o_pos.y, tp->o_pos.x, MAGIC);
|
||||
}
|
||||
}
|
||||
for(titem = mlist; titem != NULL; titem = next(titem)) {
|
||||
reg struct linked_list *pitem;
|
||||
|
||||
th = THINGPTR(titem);
|
||||
for(pitem=th->t_pack;pitem!=NULL;pitem=next(pitem)) {
|
||||
if (is_magic(ldata(pitem))) {
|
||||
show = TRUE;
|
||||
mvwaddch(hw,th->t_pos.y, th->t_pos.x, MAGIC);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (show) {
|
||||
msg("You begin to sense the presence of magic.");
|
||||
overlay(hw,cw);
|
||||
p_know[P_TFIND] = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
msg("You have a strange feeling for a moment, then it passes.");
|
||||
when P_PARALYZE:
|
||||
if (!bless) {
|
||||
if (pl_on(ISINVINC))
|
||||
msg("You feel numb for a moment.");
|
||||
else {
|
||||
msg("You can't move.");
|
||||
player.t_nocmd = HOLDTIME;
|
||||
}
|
||||
p_know[P_PARALYZE] = TRUE;
|
||||
}
|
||||
when P_SEEINVIS:
|
||||
if (!curse) {
|
||||
int invlen = roll(40,20);
|
||||
|
||||
msg("This potion tastes like %s juice.", fruit);
|
||||
if (pl_off(CANSEE)) {
|
||||
player.t_flags |= CANSEE;
|
||||
fuse(unsee, TRUE, invlen);
|
||||
light(&hero);
|
||||
}
|
||||
else
|
||||
lengthen(unsee, invlen);
|
||||
sight(FALSE);
|
||||
}
|
||||
when P_RAISE:
|
||||
if (!curse) {
|
||||
msg("You suddenly feel much more skillful.");
|
||||
p_know[P_RAISE] = TRUE;
|
||||
chg_abil(DEX,1,TRUE);
|
||||
chg_abil(WIS,1,TRUE);
|
||||
chg_abil(CON,1,TRUE);
|
||||
raise_level();
|
||||
}
|
||||
when P_XHEAL:
|
||||
if (!curse) {
|
||||
heal_self(8, TRUE);
|
||||
if (rnd(100) < 50)
|
||||
chg_abil(CON,1,TRUE);
|
||||
msg("You begin to feel much better.");
|
||||
p_know[P_XHEAL] = TRUE;
|
||||
if (!iswearing(R_SLOW))
|
||||
notslow(FALSE);
|
||||
unconfuse();
|
||||
extinguish(unconfuse);
|
||||
sight(FALSE);
|
||||
}
|
||||
when P_HASTE:
|
||||
if (!curse) {
|
||||
add_haste(TRUE);
|
||||
msg("You feel yourself moving much faster.");
|
||||
p_know[P_HASTE] = TRUE;
|
||||
}
|
||||
when P_INVINC:
|
||||
if (!curse) {
|
||||
int time = rnd(400) + 350;
|
||||
|
||||
msg("You feel invincible.");
|
||||
if (player.t_flags & ISINVINC)
|
||||
lengthen(notinvinc,time);
|
||||
else
|
||||
fuse(notinvinc,TRUE,time);
|
||||
player.t_flags |= ISINVINC;
|
||||
p_know[P_INVINC] = TRUE;
|
||||
}
|
||||
when P_SMART:
|
||||
if (!curse) {
|
||||
msg("You feel more perceptive.");
|
||||
p_know[P_SMART] = TRUE;
|
||||
chg_abil(WIS,1,TRUE);
|
||||
}
|
||||
when P_RESTORE:
|
||||
if (!curse) {
|
||||
msg("Hey, this tastes great. You feel warm all over.");
|
||||
him->s_re = max_stats.s_re;
|
||||
him->s_ef = max_stats.s_re;
|
||||
ringabil(); /* add in rings */
|
||||
updpack(); /* update weight */
|
||||
p_know[P_RESTORE] = TRUE;
|
||||
extinguish(rchg_str); /* kill restore in from ulodyte */
|
||||
}
|
||||
when P_BLIND:
|
||||
if (!bless) {
|
||||
if (pl_on(ISINVINC))
|
||||
msg("The light dims for a moment.");
|
||||
else {
|
||||
chg_abil(WIS,-1,TRUE);
|
||||
msg("A cloak of darkness falls around you.");
|
||||
if (pl_off(ISBLIND)) {
|
||||
player.t_flags |= ISBLIND;
|
||||
fuse(sight, TRUE, rnd(400) + 450);
|
||||
light(&hero);
|
||||
}
|
||||
}
|
||||
p_know[P_BLIND] = TRUE;
|
||||
}
|
||||
when P_ETH:
|
||||
if (!curse) {
|
||||
int ethlen = roll(40,20);
|
||||
|
||||
msg("You feel more vaporous.");
|
||||
if (pl_on(ISETHER))
|
||||
lengthen(noteth,ethlen);
|
||||
else
|
||||
fuse(noteth,TRUE,ethlen);
|
||||
player.t_flags |= ISETHER;
|
||||
p_know[P_ETH] = TRUE;
|
||||
}
|
||||
when P_NOP:
|
||||
msg("This potion tastes extremely dull.");
|
||||
when P_DEX:
|
||||
if (!curse) {
|
||||
chg_abil(DEX,1,TRUE); /* increase dexterity */
|
||||
p_know[P_DEX] = TRUE;
|
||||
msg("You feel much more agile.");
|
||||
}
|
||||
when P_REGEN:
|
||||
if (!curse) {
|
||||
int reglen = rnd(450) + 450;
|
||||
|
||||
if (pl_on(ISREGEN))
|
||||
lengthen(notregen, reglen);
|
||||
else
|
||||
fuse(notregen, TRUE, reglen);
|
||||
player.t_flags |= ISREGEN;
|
||||
msg("You feel yourself improved.");
|
||||
p_know[P_REGEN] = TRUE;
|
||||
}
|
||||
when P_DECREP:
|
||||
case P_SUPHERO: {
|
||||
int howmuch = rnd(3) + 1;
|
||||
|
||||
if (wh == P_DECREP) {
|
||||
if (!bless) {
|
||||
if (iswearing(R_SUSAB) || pl_on(ISINVINC)) {
|
||||
msg("You feel momentarily woozy.");
|
||||
howmuch = 0;
|
||||
}
|
||||
else {
|
||||
msg("You feel crippled.");
|
||||
howmuch = -howmuch;
|
||||
if (!iswearing(R_SUSTSTR))
|
||||
chg_abil(STR,howmuch,TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
howmuch = 0;
|
||||
}
|
||||
else { /* potion of superhero */
|
||||
if (curse)
|
||||
howmuch = 0;
|
||||
msg("You feel invigorated.");
|
||||
chg_abil(STR,howmuch,TRUE);
|
||||
}
|
||||
chg_abil(CON,howmuch,TRUE);
|
||||
chg_abil(DEX,howmuch,TRUE);
|
||||
chg_abil(WIS,howmuch,TRUE); /* change abilities */
|
||||
p_know[wh] = TRUE;
|
||||
}
|
||||
otherwise:
|
||||
msg("What an odd tasting potion!");
|
||||
return;
|
||||
}
|
||||
nochange = FALSE;
|
||||
if (p_know[wh] && p_guess[wh]) {
|
||||
free(p_guess[wh]);
|
||||
p_guess[wh] = NULL;
|
||||
}
|
||||
else if(!p_know[wh] && p_guess[wh] == NULL) {
|
||||
strcpy(buf, p_colors[wh]);
|
||||
msg(callit);
|
||||
if (get_str(buf, cw) == NORM) {
|
||||
p_guess[wh] = new(strlen(buf) + 1);
|
||||
strcpy(p_guess[wh], buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
377
srogue/pstats.c
Normal file
377
srogue/pstats.c
Normal file
|
|
@ -0,0 +1,377 @@
|
|||
/*
|
||||
* Players status routines
|
||||
*
|
||||
* @(#)pstats.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "rogue.h"
|
||||
#include "rogue.ext"
|
||||
|
||||
|
||||
/*
|
||||
* chg_hpt:
|
||||
* Changes players hit points
|
||||
*/
|
||||
chg_hpt(howmany, alsomax, what)
|
||||
int howmany;
|
||||
bool alsomax;
|
||||
char what;
|
||||
{
|
||||
nochange = FALSE;
|
||||
if(alsomax)
|
||||
him->s_maxhp += howmany;
|
||||
him->s_hpt += howmany;
|
||||
if (him->s_hpt < 1) {
|
||||
msg(" ");
|
||||
death(what);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* rchg_str:
|
||||
* Update the players real strength
|
||||
*/
|
||||
rchg_str(amt)
|
||||
int amt;
|
||||
{
|
||||
chg_abil(STR,amt,TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* chg_abil:
|
||||
* Used to modify the hero's abilities
|
||||
*/
|
||||
chg_abil(what,amt,how)
|
||||
int amt, what, how;
|
||||
{
|
||||
if (amt == 0)
|
||||
return;
|
||||
if (how == TRUE) { /* real (must be 1st) */
|
||||
updabil(what,amt,&pstats.s_re,TRUE);
|
||||
how = FALSE;
|
||||
}
|
||||
updabil(what,amt,&pstats.s_ef,how); /* effective */
|
||||
updpack();
|
||||
wghtchk(FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* updabil:
|
||||
* Do the actual abilities updating
|
||||
*/
|
||||
updabil(what, amt, pst, how)
|
||||
struct real *pst;
|
||||
int what, amt, how;
|
||||
{
|
||||
register int *wh, *mx, *mr;
|
||||
struct real *mst, *msr;
|
||||
bool is_str = FALSE;
|
||||
int rtype;
|
||||
|
||||
msr = &him->s_re;
|
||||
if (how == TRUE) /* max real abilities */
|
||||
mst = &max_stats.s_re;
|
||||
else /* max effective abil */
|
||||
mst = &max_stats.s_ef;
|
||||
switch (what) {
|
||||
case STR:
|
||||
is_str = TRUE;
|
||||
wh = &pst->a_str;
|
||||
mx = &mst->a_str;
|
||||
mr = &msr->a_str;
|
||||
rtype = R_ADDSTR;
|
||||
when DEX:
|
||||
wh = &pst->a_dex;
|
||||
mx = &mst->a_dex;
|
||||
mr = &msr->a_dex;
|
||||
rtype = R_DEX;
|
||||
when CON:
|
||||
wh = &pst->a_con;
|
||||
mx = &mst->a_con;
|
||||
mr = &msr->a_con;
|
||||
rtype = R_CONST;
|
||||
when WIS:
|
||||
wh = &pst->a_wis;
|
||||
mx = &mst->a_wis;
|
||||
mr = &msr->a_wis;
|
||||
rtype = R_KNOW;
|
||||
otherwise:
|
||||
return;
|
||||
}
|
||||
*wh += amt; /* update by amt */
|
||||
if (amt < 0) { /* if decrement */
|
||||
if (*wh < MINABIL) /* minimum = 3 */
|
||||
*wh = MINABIL;
|
||||
if (how == FALSE) {
|
||||
if (*wh < *mr) /* if less than real abil */
|
||||
*wh = *mr; /* make equal to real */
|
||||
}
|
||||
}
|
||||
else { /* increment */
|
||||
int themax;
|
||||
|
||||
themax = MAXOTHER; /* default maximum */
|
||||
if (is_str)
|
||||
themax = MAXSTR; /* strength maximum */
|
||||
if (how != TRUE)
|
||||
themax += ringex(rtype); /* get ring extra */
|
||||
if (*wh > themax) { /* see if > max (if real) */
|
||||
*wh = themax; /* max = 18 (24 if str) */
|
||||
}
|
||||
/*
|
||||
* Check for updating the max player stats.
|
||||
*/
|
||||
if (*wh > *mx)
|
||||
*mx = *wh;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* add_haste:
|
||||
* add a haste to the player
|
||||
*/
|
||||
add_haste(potion)
|
||||
bool potion;
|
||||
{
|
||||
if (pl_on(ISHASTE)) {
|
||||
msg("You faint from exhaustion.");
|
||||
player.t_nocmd += rnd(8);
|
||||
player.t_flags &= ~ISHASTE;
|
||||
extinguish(nohaste);
|
||||
}
|
||||
else {
|
||||
player.t_flags |= ISHASTE;
|
||||
if (potion)
|
||||
fuse(nohaste, TRUE, roll(10,10));
|
||||
else
|
||||
fuse(nohaste, TRUE, roll(40,20));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* getpdex:
|
||||
* Gets players added dexterity for fighting
|
||||
*/
|
||||
getpdex(who, heave)
|
||||
struct stats *who;
|
||||
bool heave;
|
||||
{
|
||||
reg int edex;
|
||||
|
||||
edex = who->s_ef.a_dex;
|
||||
if (heave) { /* an object was thrown here */
|
||||
if (edex > 18)
|
||||
return (edex - 15);
|
||||
switch(edex) {
|
||||
case 18: return 3;
|
||||
case 17: return 2;
|
||||
case 16: return 1;
|
||||
case 15:
|
||||
case 14:
|
||||
case 13:
|
||||
case 12:
|
||||
case 11:
|
||||
case 10:
|
||||
case 9:
|
||||
case 8:
|
||||
case 7:
|
||||
case 6: return 0;
|
||||
case 5: return -1;
|
||||
case 4: return -2;
|
||||
default: return -3;
|
||||
}
|
||||
}
|
||||
else { /* object NOT thrown here (affects armor class) */
|
||||
if (edex > 18)
|
||||
return (14 - edex);
|
||||
switch(edex) {
|
||||
case 18: return -4;
|
||||
case 17: return -3;
|
||||
case 16: return -2;
|
||||
case 15: return -1;
|
||||
case 14:
|
||||
case 13:
|
||||
case 12:
|
||||
case 11:
|
||||
case 10:
|
||||
case 9:
|
||||
case 8:
|
||||
case 7: return 0;
|
||||
case 6: return 1;
|
||||
case 5: return 2;
|
||||
case 4: return 3;
|
||||
default: return 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* getpwis:
|
||||
* Get a players wisdom for fighting
|
||||
*/
|
||||
getpwis(who)
|
||||
struct stats *who;
|
||||
{
|
||||
reg int ewis;
|
||||
|
||||
ewis = who->s_ef.a_wis;
|
||||
if (ewis > 18)
|
||||
return (ewis - 14);
|
||||
switch(ewis) {
|
||||
case 18: return 4;
|
||||
case 17: return 3;
|
||||
case 16: return 2;
|
||||
case 15: return 1;
|
||||
case 14:
|
||||
case 13:
|
||||
case 12:
|
||||
case 11:
|
||||
case 10:
|
||||
case 9:
|
||||
case 8: return 0;
|
||||
case 7:
|
||||
case 6: return -1;
|
||||
case 5:
|
||||
case 4: return -2;
|
||||
default: return -3;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* getpcon:
|
||||
* Get added hit points from players constitution
|
||||
*/
|
||||
getpcon(who)
|
||||
struct stats *who;
|
||||
{
|
||||
reg int econ;
|
||||
|
||||
econ = who->s_ef.a_con;
|
||||
if (econ > 18)
|
||||
return (econ - 14);
|
||||
switch(econ) {
|
||||
case 18: return 4;
|
||||
case 17: return 3;
|
||||
case 16: return 2;
|
||||
case 15: return 1;
|
||||
case 14:
|
||||
case 13:
|
||||
case 12:
|
||||
case 11:
|
||||
case 10:
|
||||
case 9:
|
||||
case 8:
|
||||
case 7: return 0;
|
||||
case 6:
|
||||
case 5:
|
||||
case 4: return -1;
|
||||
default: return -2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* str_plus:
|
||||
* compute bonus/penalties for strength on the "to hit" roll
|
||||
*/
|
||||
str_plus(who)
|
||||
struct stats *who;
|
||||
{
|
||||
reg int hitplus, str;
|
||||
|
||||
hitplus = 0;
|
||||
str = who->s_ef.a_str;
|
||||
if (str > 24) /* > 24 */
|
||||
hitplus = str - 21;
|
||||
else if (str == 24) /* 24 */
|
||||
hitplus = 3;
|
||||
else if (str > 20) /* 21 to 23 */
|
||||
hitplus = 2;
|
||||
else if(str >= 17) /* 17 to 20 */
|
||||
hitplus = 1;
|
||||
else if(str > 7) /* 8 to 16 */
|
||||
hitplus = 0;
|
||||
else if(str > 5) /* 6 to 7 */
|
||||
hitplus = -1;
|
||||
else if(str > 3) /* 4 to 5 */
|
||||
hitplus = -2;
|
||||
else
|
||||
hitplus = -3; /* < 4 */
|
||||
if (who == him) /* add pack weight if hero */
|
||||
hitplus += hitweight();
|
||||
return hitplus;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* add_dam:
|
||||
* Compute additional damage done depending on strength
|
||||
*/
|
||||
add_dam(who)
|
||||
struct stats *who;
|
||||
{
|
||||
reg int exdam, str;
|
||||
|
||||
exdam = 0;
|
||||
str = who->s_ef.a_str;
|
||||
if (str > 24) /* > 24 */
|
||||
exdam = str - 18;
|
||||
else if (str == 24) /* 24 */
|
||||
exdam = 6;
|
||||
else if (str == 23) /* 23 */
|
||||
exdam = 5;
|
||||
else if (str > 20) /* 21 to 22 */
|
||||
exdam = 4;
|
||||
else if (str > 18) /* 19 to 20 */
|
||||
exdam = 3;
|
||||
else if (str == 18) /* 18 */
|
||||
exdam = 2;
|
||||
else if (str > 15) /* 16 to 17 */
|
||||
exdam = 1;
|
||||
else if (str > 6) /* 7 to 14 */
|
||||
exdam = 0;
|
||||
else
|
||||
exdam = -1; /* 3 to 6 */
|
||||
if (who == him)
|
||||
exdam += hungdam(); /* add hungry state if hero */
|
||||
return exdam;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* hungdam:
|
||||
* Calculate damage depending on players hungry state
|
||||
*/
|
||||
hungdam()
|
||||
{
|
||||
switch (hungry_state) {
|
||||
case F_OKAY:
|
||||
case F_HUNGRY: return 0;
|
||||
when F_WEAK: return -1;
|
||||
when F_FAINT: return -2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* heal_self:
|
||||
* Heal the hero.
|
||||
*/
|
||||
heal_self(factor, updmaxhp)
|
||||
int factor;
|
||||
bool updmaxhp;
|
||||
{
|
||||
him->s_hpt += roll(him->s_lvl + getpcon(him), factor);
|
||||
if (updmaxhp)
|
||||
him->s_maxhp += 1;
|
||||
if (him->s_hpt > him->s_maxhp)
|
||||
him->s_hpt = him->s_maxhp;
|
||||
nochange = FALSE;
|
||||
}
|
||||
10
srogue/rdk.h
Normal file
10
srogue/rdk.h
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
extern bool My_term, /* user specied terminal */
|
||||
extern int _tty_ch; /* channel with tty on it */
|
||||
229
srogue/rgdata.c
Normal file
229
srogue/rgdata.c
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "global.c"
|
||||
|
||||
main(argc,argv)
|
||||
char **argv;
|
||||
int argc;
|
||||
{
|
||||
char *ptr;
|
||||
int i, j, k;
|
||||
struct magic_item *mi;
|
||||
struct init_weps *wp;
|
||||
struct init_armor *ar;
|
||||
struct monster *mo;
|
||||
FILE *fo;
|
||||
|
||||
/*
|
||||
* write to desired output file
|
||||
*/
|
||||
if (argc > 1) {
|
||||
fo = fopen(argv[1], "w");
|
||||
if (fo == NULL) {
|
||||
printf("%s: %s not writable\n",argv[0],argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
fo = stdout;
|
||||
|
||||
/*
|
||||
* print total chances for armor, weapons, food, scrolls, etc
|
||||
*/
|
||||
fprintf(fo,"\n\n\n\n\n\n");
|
||||
fprintf(fo,"\t ITEM GENERAL INFO\n\n\n");
|
||||
fprintf(fo,"NAME\t\tCHANCE\t\tWEIGHT\n\n");
|
||||
for (mi = &things[0]; mi < &things[NUMTHINGS]; mi++) {
|
||||
fprintf(fo,"%s\t\t",mi->mi_name);
|
||||
i = mi->mi_prob / 10;
|
||||
j = mi->mi_prob % 10;
|
||||
fprintf(fo,"%2d.%1d %%\t\t",i,j);
|
||||
i = mi->mi_wght / 10;
|
||||
j = mi->mi_wght % 10;
|
||||
if (i == 0 && j == 0)
|
||||
fprintf(fo,"%3s\n","*");
|
||||
else
|
||||
fprintf(fo,"%3d.%1d lbs\n",i,j);
|
||||
}
|
||||
fprintf(fo,"\n\n\n\n\n\n\nNOTES - * means that weight depends on which one of that item type\n");
|
||||
fprintf(fo," - All items weigh 20%% more when cursed\n");
|
||||
|
||||
/*
|
||||
* print stuff about potions
|
||||
*/
|
||||
fprintf(fo,"\n\n\n\n\n\n");
|
||||
fprintf(fo,"\t\t POTION INFO\n\n\n");
|
||||
fprintf(fo,"NAME\t\t\t\tCHANCE\t\tWORTH\n\n");
|
||||
for (mi = &p_magic[0]; mi < &p_magic[MAXPOTIONS]; mi++) {
|
||||
fprintf(fo,"%s\t",mi->mi_name);
|
||||
k = strlen(mi->mi_name);
|
||||
if (k < 8)
|
||||
ptr = "\t\t\t";
|
||||
else if (k >= 16)
|
||||
ptr = "\t";
|
||||
else
|
||||
ptr = "\t\t";
|
||||
fprintf(fo,"%s", ptr);
|
||||
i = mi->mi_prob / 10;
|
||||
j = mi->mi_prob % 10;
|
||||
fprintf(fo,"%2d.%1d %%\t\t",i,j);
|
||||
fprintf(fo,"%3d\n",mi->mi_worth);
|
||||
}
|
||||
fprintf(fo,"\n\n\n\n\nNOTE - All potions weigh 0.5 lbs\n");
|
||||
|
||||
|
||||
/*
|
||||
* print stuff about scrolls
|
||||
*/
|
||||
fprintf(fo,"\n\n\n\n\n\n");
|
||||
fprintf(fo,"\t\t SCROLL INFO\n\n\n");
|
||||
fprintf(fo,"NAME\t\t\t\tCHANCE\t\tWORTH\n\n");
|
||||
for (mi = &s_magic[0]; mi < &s_magic[MAXSCROLLS]; mi++) {
|
||||
fprintf(fo,"%s\t",mi->mi_name);
|
||||
k = strlen(mi->mi_name);
|
||||
if (k < 8)
|
||||
ptr = "\t\t\t";
|
||||
else if (k >= 16)
|
||||
ptr = "\t";
|
||||
else
|
||||
ptr = "\t\t";
|
||||
fprintf(fo,"%s", ptr);
|
||||
i = mi->mi_prob / 10;
|
||||
j = mi->mi_prob % 10;
|
||||
fprintf(fo,"%2d.%1d %%\t\t",i,j);
|
||||
fprintf(fo,"%3d\n",mi->mi_worth);
|
||||
}
|
||||
fprintf(fo,"\n\n\n\n\nNOTE - All scrolls weigh 3.0 lbs\n");
|
||||
|
||||
|
||||
/*
|
||||
* print stuff about rings
|
||||
*/
|
||||
fprintf(fo,"\n\n\n\n\n\n");
|
||||
fprintf(fo,"\t\t RING INFO\n\n\n");
|
||||
fprintf(fo,"NAME\t\t\t\tCHANCE\t\tWORTH\n\n");
|
||||
for (mi = &r_magic[0]; mi < &r_magic[MAXRINGS]; mi++) {
|
||||
fprintf(fo,"%s\t",mi->mi_name);
|
||||
k = strlen(mi->mi_name);
|
||||
if (k < 8)
|
||||
ptr = "\t\t\t";
|
||||
else if (k >= 16)
|
||||
ptr = "\t";
|
||||
else
|
||||
ptr = "\t\t";
|
||||
fprintf(fo,"%s", ptr);
|
||||
i = mi->mi_prob / 10;
|
||||
j = mi->mi_prob % 10;
|
||||
fprintf(fo,"%2d.%1d %%\t\t",i,j);
|
||||
fprintf(fo,"%3d\n",mi->mi_worth);
|
||||
}
|
||||
fprintf(fo,"\n\n\n\n\nNOTE - All rings weigh 0.5 lbs\n");
|
||||
|
||||
|
||||
/*
|
||||
* print stuff about sticks
|
||||
*/
|
||||
fprintf(fo,"\n\n\n\n\n\n");
|
||||
fprintf(fo,"\t\t STAFF/WAND INFO\n\n\n");
|
||||
fprintf(fo,"NAME\t\t\t\tCHANCE\t\tWORTH\n\n");
|
||||
for (mi = &ws_magic[0]; mi < &ws_magic[MAXSTICKS]; mi++) {
|
||||
fprintf(fo,"%s\t",mi->mi_name);
|
||||
k = strlen(mi->mi_name);
|
||||
if (k < 8)
|
||||
ptr = "\t\t\t";
|
||||
else if (k >= 16)
|
||||
ptr = "\t";
|
||||
else
|
||||
ptr = "\t\t";
|
||||
fprintf(fo,"%s", ptr);
|
||||
i = mi->mi_prob / 10;
|
||||
j = mi->mi_prob % 10;
|
||||
fprintf(fo,"%2d.%1d %%\t\t",i,j);
|
||||
fprintf(fo,"%3d\n",mi->mi_worth);
|
||||
}
|
||||
fprintf(fo,"\n\n\n\n\nNOTES - All wands weigh 6.0 lbs\n");
|
||||
fprintf(fo," - All staffs weigh 10.0 lbs\n");
|
||||
fprintf(fo," - Wands contain from 4 to 8 charges\n");
|
||||
fprintf(fo," - Staffs contain from 5 to 12 charges\n");
|
||||
fprintf(fo," - Sticks of light have an additional 7 to 15 charges\n");
|
||||
|
||||
|
||||
/*
|
||||
* print armor info
|
||||
*/
|
||||
fprintf(fo,"\n\n\n\n\n\n");
|
||||
fprintf(fo,"\t\t\t\tARMOR INFO\n\n\n");
|
||||
fprintf(fo,"NAME\t\t\t\tAC\tCHANCE\t\tWORTH\t\tWEIGHT\n\n");
|
||||
for (ar = &armors[0]; ar < &armors[MAXARMORS]; ar++) {
|
||||
fprintf(fo,"%s\t",ar->a_name);
|
||||
k = strlen(ar->a_name);
|
||||
if (k < 8)
|
||||
ptr = "\t\t\t";
|
||||
else if (k >= 16)
|
||||
ptr = "\t";
|
||||
else
|
||||
ptr = "\t\t";
|
||||
fprintf(fo,"%s", ptr);
|
||||
fprintf(fo,"%2d\t",ar->a_class);
|
||||
fprintf(fo,"%2d %%\t\t",ar->a_prob);
|
||||
fprintf(fo,"%3d\t\t",ar->a_worth);
|
||||
fprintf(fo,"%2d lbs\n",ar->a_wght / 10);
|
||||
}
|
||||
fprintf(fo,"\n\n\n\n\nNOTE - All armor becomes 50%% lighter when blessed\n");
|
||||
|
||||
|
||||
/*
|
||||
* print stuff about weapons
|
||||
*/
|
||||
fprintf(fo,"\n\n\n\n\n\n");
|
||||
fprintf(fo,"\t\t\t\t\tWEAPON INFO\n\n\n");
|
||||
fprintf(fo,
|
||||
"NAME\t\t\tHIT DAMAGE\tHURL DAMAGE\tWORTH\t\tWEIGHT\n\n");
|
||||
for (wp = &weaps[0]; wp < &weaps[MAXWEAPONS]; wp++) {
|
||||
fprintf(fo,"%s\t",wp->w_name);
|
||||
k = strlen(wp->w_name);
|
||||
if (k < 8)
|
||||
ptr = "\t\t";
|
||||
else if (k >= 16)
|
||||
ptr = "";
|
||||
else
|
||||
ptr = "\t";
|
||||
fprintf(fo,"%s", ptr);
|
||||
ptr = wp->w_dam;
|
||||
i = *ptr - '0';
|
||||
j = 0;
|
||||
ptr += 2;
|
||||
while (*ptr != NULL) {
|
||||
j = j * 10 + (*ptr - '0');
|
||||
++ptr;
|
||||
}
|
||||
j *= i;
|
||||
fprintf(fo," %d to %d\t",i,j);
|
||||
ptr = wp->w_hrl;
|
||||
i = *ptr - '0';
|
||||
j = 0;
|
||||
ptr += 2;
|
||||
while (*ptr != NULL) {
|
||||
j = j * 10 + (*ptr - '0');
|
||||
++ptr;
|
||||
}
|
||||
j *= i;
|
||||
fprintf(fo," %d to %d\t",i,j);
|
||||
fprintf(fo,"%4d\t\t",wp->w_worth);
|
||||
i = wp->w_wght / 10;
|
||||
j = wp->w_wght % 10;
|
||||
fprintf(fo,"%2d.%1d lbs\n",i,j);
|
||||
}
|
||||
fprintf(fo,"\n\n\n\n\nNOTE - All weapons become 50%% lighter when blessed\n");
|
||||
|
||||
|
||||
/*
|
||||
* print stuff about the monsters
|
||||
*/
|
||||
}
|
||||
492
srogue/rings.c
Normal file
492
srogue/rings.c
Normal file
|
|
@ -0,0 +1,492 @@
|
|||
/*
|
||||
* routines dealing specifically with rings
|
||||
*
|
||||
* @(#)rings.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "rogue.h"
|
||||
#include "rogue.ext"
|
||||
|
||||
/*
|
||||
* ring_on:
|
||||
* Put on a ring
|
||||
*/
|
||||
ring_on()
|
||||
{
|
||||
reg struct object *obj;
|
||||
reg struct linked_list *item;
|
||||
reg int ring, wh;
|
||||
char buf[LINLEN];
|
||||
bool okring;
|
||||
|
||||
if (cur_ring[LEFT] != NULL && cur_ring[RIGHT] != NULL) {
|
||||
msg("Already wearing two rings.");
|
||||
after = FALSE;
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* Make certain that it is somethings that we want to wear
|
||||
*/
|
||||
if ((item = get_item("put on", RING)) == NULL)
|
||||
return;
|
||||
obj = OBJPTR(item);
|
||||
if (obj->o_type != RING) {
|
||||
msg("That won't fit on your finger.");
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* find out which hand to put it on
|
||||
*/
|
||||
if (is_current(obj))
|
||||
return;
|
||||
if (cur_ring[LEFT] == NULL && cur_ring[RIGHT] == NULL) {
|
||||
if ((ring = gethand(FALSE)) < 0)
|
||||
return;
|
||||
}
|
||||
else if (cur_ring[LEFT] == NULL)
|
||||
ring = LEFT;
|
||||
else
|
||||
ring = RIGHT;
|
||||
cur_ring[ring] = obj;
|
||||
wh = obj->o_which;
|
||||
/*
|
||||
* okring = FALSE when:
|
||||
* 1) ring is cursed and benefit = plus
|
||||
* 2) ring is blessed and benefit = minus
|
||||
*/
|
||||
okring = !((obj->o_ac > 0 && o_on(obj, ISCURSED)) ||
|
||||
(obj->o_ac < 0 && o_on(obj, ISBLESS)));
|
||||
/*
|
||||
* Calculate the effect it has on the poor guy (if possible).
|
||||
*/
|
||||
if (okring) {
|
||||
switch (wh) {
|
||||
case R_SPEED:
|
||||
if (--obj->o_ac < 0) {
|
||||
obj->o_ac = 0;
|
||||
setoflg(obj,ISCURSED);
|
||||
}
|
||||
else {
|
||||
add_haste(FALSE);
|
||||
msg("You find yourself moving must faster.");
|
||||
}
|
||||
when R_GIANT: /* to 24 */
|
||||
him->s_ef.a_str = MAXSTR;
|
||||
when R_ADDSTR:
|
||||
chg_abil(STR,obj->o_ac,FROMRING);
|
||||
when R_KNOW:
|
||||
chg_abil(WIS,obj->o_ac,FROMRING);
|
||||
when R_DEX:
|
||||
chg_abil(DEX,obj->o_ac,FROMRING);
|
||||
when R_CONST:
|
||||
chg_abil(CON,obj->o_ac,FROMRING);
|
||||
when R_SEEINVIS:
|
||||
player.t_flags |= CANSEE;
|
||||
light(&hero);
|
||||
mvwaddch(cw, hero.y, hero.x, PLAYER);
|
||||
when R_AGGR:
|
||||
aggravate();
|
||||
when R_HEAVY:
|
||||
updpack(); /* new pack weight */
|
||||
when R_BLIND:
|
||||
r_know[R_BLIND] = TRUE;
|
||||
player.t_flags |= ISBLIND;
|
||||
look(FALSE);
|
||||
when R_SLOW:
|
||||
player.t_flags |= ISSLOW;
|
||||
when R_SAPEM:
|
||||
fuse(sapem,TRUE,150);
|
||||
when R_LIGHT: {
|
||||
struct room *rop;
|
||||
|
||||
r_know[R_LIGHT] = TRUE;
|
||||
if ((rop = player.t_room) != NULL) {
|
||||
rop->r_flags &= ~ISDARK;
|
||||
light(&hero);
|
||||
mvwaddch(cw, hero.y, hero.x, PLAYER);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (r_know[wh] && r_guess[wh]) {
|
||||
free(r_guess[wh]);
|
||||
r_guess[wh] = NULL;
|
||||
}
|
||||
else if(!r_know[wh] && r_guess[wh] == NULL) {
|
||||
mpos = 0;
|
||||
strcpy(buf, r_stones[wh]);
|
||||
msg(callit);
|
||||
if (get_str(buf, cw) == NORM) {
|
||||
r_guess[wh] = new(strlen(buf) + 1);
|
||||
strcpy(r_guess[wh], buf);
|
||||
}
|
||||
}
|
||||
mpos = 0;
|
||||
msg("Now wearing %s",inv_name(obj,TRUE));
|
||||
ringfood = ring_eat();
|
||||
nochange = FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ring_off:
|
||||
* Take off some ring
|
||||
*/
|
||||
ring_off()
|
||||
{
|
||||
reg int ring;
|
||||
reg struct object *obj;
|
||||
|
||||
if (cur_ring[LEFT] == NULL && cur_ring[RIGHT] == NULL) {
|
||||
msg("You're not wearing any rings.");
|
||||
return;
|
||||
}
|
||||
else if (cur_ring[LEFT] == NULL)
|
||||
ring = RIGHT;
|
||||
else if (cur_ring[RIGHT] == NULL)
|
||||
ring = LEFT;
|
||||
else
|
||||
if ((ring = gethand(TRUE)) < 0)
|
||||
return;
|
||||
mpos = 0;
|
||||
obj = cur_ring[ring];
|
||||
if (obj == NULL) {
|
||||
msg("Not wearing such a ring.");
|
||||
return;
|
||||
}
|
||||
if (dropcheck(obj)) {
|
||||
msg("Was wearing %s", inv_name(obj, TRUE));
|
||||
nochange = FALSE;
|
||||
ringfood = ring_eat();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* toss_ring:
|
||||
* Remove a ring and stop its effects
|
||||
*/
|
||||
toss_ring(what)
|
||||
struct object *what;
|
||||
{
|
||||
bool okring;
|
||||
|
||||
/*
|
||||
* okring = FALSE when:
|
||||
* 1) ring is cursed and benefit = plus
|
||||
* 2) ring is blessed and benefit = minus
|
||||
*/
|
||||
okring = !((what->o_ac > 0 && o_on(what, ISCURSED)) ||
|
||||
(what->o_ac < 0 && o_on(what, ISBLESS)));
|
||||
|
||||
cur_ring[what == cur_ring[LEFT] ? LEFT : RIGHT] = NULL;
|
||||
if (okring) {
|
||||
switch (what->o_which) {
|
||||
case R_SPEED:
|
||||
extinguish(nohaste);
|
||||
nohaste(FALSE);
|
||||
when R_BLIND:
|
||||
sight(FALSE);
|
||||
when R_SLOW:
|
||||
player.t_flags &= ~ISSLOW;
|
||||
when R_SAPEM:
|
||||
extinguish(sapem);
|
||||
when R_GIANT:
|
||||
him->s_ef = him->s_re;
|
||||
ringabil();
|
||||
when R_ADDSTR:
|
||||
chg_abil(STR,-what->o_ac,FALSE);
|
||||
when R_KNOW:
|
||||
chg_abil(WIS,-what->o_ac,FALSE);
|
||||
when R_DEX:
|
||||
chg_abil(DEX,-what->o_ac,FALSE);
|
||||
when R_CONST:
|
||||
chg_abil(CON,-what->o_ac,FALSE);
|
||||
when R_SEEINVIS:
|
||||
player.t_flags &= ~CANSEE;
|
||||
extinguish(unsee);
|
||||
light(&hero);
|
||||
mvwaddch(cw, hero.y, hero.x, PLAYER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* gethand:
|
||||
* Get a hand to wear a ring
|
||||
*/
|
||||
gethand(isrmv)
|
||||
bool isrmv;
|
||||
{
|
||||
reg int c;
|
||||
char *ptr;
|
||||
struct object *obj;
|
||||
|
||||
while(1) {
|
||||
addmsg("Left or Right ring");
|
||||
if (isrmv)
|
||||
addmsg(starlist);
|
||||
addmsg("? ");
|
||||
endmsg();
|
||||
c = readchar();
|
||||
if (isupper(c))
|
||||
c = tolower(c);
|
||||
if (c == '*' && isrmv) {
|
||||
wclear(hw);
|
||||
obj = cur_ring[LEFT];
|
||||
if (obj != NULL)
|
||||
ptr = inv_name(obj, TRUE);
|
||||
else
|
||||
ptr = "none";
|
||||
wprintw(hw, "L) %s\n\r",ptr);
|
||||
obj = cur_ring[RIGHT];
|
||||
if (obj != NULL)
|
||||
ptr = inv_name(obj, TRUE);
|
||||
else
|
||||
ptr = "none";
|
||||
wprintw(hw, "R) %s\n\r", ptr);
|
||||
wprintw(hw, "\n\r\nWhich hand? ");
|
||||
draw(hw);
|
||||
c = readchar();
|
||||
if (isupper(c))
|
||||
c = tolower(c);
|
||||
restscr(cw);
|
||||
}
|
||||
if (c == 'l')
|
||||
return LEFT;
|
||||
else if (c == 'r')
|
||||
return RIGHT;
|
||||
else if (c == ESCAPE)
|
||||
return -1;
|
||||
mpos = 0;
|
||||
msg("L or R");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ring_eat:
|
||||
* How much food do the hero's rings use up?
|
||||
*/
|
||||
ring_eat()
|
||||
{
|
||||
reg struct object *lb;
|
||||
reg int hand, i, howmuch;
|
||||
bool addit;
|
||||
|
||||
howmuch = 0;
|
||||
addit = TRUE;
|
||||
for (i = LEFT; i <= RIGHT ; i += 1) {
|
||||
lb = cur_ring[i];
|
||||
if (lb != NULL) {
|
||||
switch (lb->o_which) {
|
||||
case R_REGEN:
|
||||
case R_GIANT:
|
||||
howmuch += 2;
|
||||
when R_SPEED:
|
||||
case R_SUSTSTR:
|
||||
case R_SUSAB:
|
||||
howmuch += 1;
|
||||
when R_SEARCH:
|
||||
howmuch += (rnd(100) < 33);
|
||||
when R_DIGEST:
|
||||
switch(lb->o_ac) {
|
||||
case -3: if (rnd(100) < 25)
|
||||
howmuch += 3;
|
||||
when -2: if (rnd(100) < 50)
|
||||
howmuch += 2;
|
||||
when -1: howmuch += 1;
|
||||
when 0: howmuch -= (rnd(100) < 50);
|
||||
when 3: if (rnd(100) < 25)
|
||||
howmuch -= 3;
|
||||
when 2: if (rnd(100) < 50)
|
||||
howmuch -= 2;
|
||||
default: howmuch -= 1;
|
||||
}
|
||||
otherwise:
|
||||
addit = FALSE;
|
||||
}
|
||||
if (addit) {
|
||||
if (o_on(lb, ISBLESS))
|
||||
howmuch -= 1;
|
||||
else if (o_on(lb, ISCURSED))
|
||||
howmuch += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return howmuch;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ring_num:
|
||||
* Print ring bonuses
|
||||
*/
|
||||
char *
|
||||
ring_num(what)
|
||||
struct object *what;
|
||||
{
|
||||
static char number[5];
|
||||
|
||||
number[0] = '\0';
|
||||
if (o_on(what,ISKNOW) || o_on(what,ISPOST)) {
|
||||
if (magring(what)) { /* only rings with numbers */
|
||||
number[0] = ' ';
|
||||
strcpy(&number[1], num(what->o_ac, 0));
|
||||
}
|
||||
}
|
||||
return number;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* magring:
|
||||
* Returns TRUE if a ring has a number, i.e. +2
|
||||
*/
|
||||
magring(what)
|
||||
struct object *what;
|
||||
{
|
||||
switch(what->o_which) {
|
||||
case R_SPEED:
|
||||
case R_ADDSTR:
|
||||
case R_PROTECT:
|
||||
case R_ADDHIT:
|
||||
case R_ADDDAM:
|
||||
case R_DIGEST:
|
||||
case R_CONST:
|
||||
case R_KNOW:
|
||||
case R_DEX:
|
||||
return TRUE;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ringabil:
|
||||
* Compute effective abilities due to rings
|
||||
*/
|
||||
ringabil()
|
||||
{
|
||||
reg struct object *rptr;
|
||||
reg int i;
|
||||
|
||||
for(i = LEFT; i <= RIGHT; i++) {
|
||||
rptr = cur_ring[i];
|
||||
if (rptr != NULL) {
|
||||
switch(rptr->o_which) {
|
||||
case R_ADDSTR:
|
||||
chg_abil(STR,rptr->o_ac,FROMRING);
|
||||
when R_DEX:
|
||||
chg_abil(DEX,rptr->o_ac,FROMRING);
|
||||
when R_KNOW:
|
||||
chg_abil(WIS,rptr->o_ac,FROMRING);
|
||||
when R_CONST:
|
||||
chg_abil(CON,rptr->o_ac,FROMRING);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* init_ring:
|
||||
* Initialize a ring
|
||||
*/
|
||||
init_ring(what,fromwiz)
|
||||
struct object *what;
|
||||
bool fromwiz; /* TRUE when from wizards */
|
||||
{
|
||||
reg int much;
|
||||
|
||||
switch (what->o_which) {
|
||||
case R_DIGEST: /* -3 to +3 rings */
|
||||
case R_ADDSTR:
|
||||
case R_PROTECT:
|
||||
case R_ADDHIT:
|
||||
case R_ADDDAM:
|
||||
case R_DEX:
|
||||
case R_KNOW:
|
||||
case R_CONST:
|
||||
if (fromwiz) {
|
||||
much = getbless(); /* get wizards response */
|
||||
}
|
||||
else { /* normal users */
|
||||
if (rnd(100) < 25)
|
||||
much = -rnd(3) - 1;
|
||||
else
|
||||
much = rnd(3) + 1;
|
||||
}
|
||||
what->o_ac = much;
|
||||
if (much < 0)
|
||||
setoflg(what,ISCURSED);
|
||||
when R_SPEED:
|
||||
what->o_ac = rnd(4) + 1;
|
||||
when R_AGGR:
|
||||
case R_DELUS:
|
||||
case R_HEAVY:
|
||||
case R_BLIND:
|
||||
case R_SLOW:
|
||||
case R_SAPEM:
|
||||
case R_TELEPORT:
|
||||
what->o_ac = 0;
|
||||
setoflg(what,ISCURSED);
|
||||
when R_GIANT:
|
||||
what->o_ac = 25; /* lots !! of STR */
|
||||
otherwise:
|
||||
what->o_ac = 1;
|
||||
}
|
||||
what->o_type = RING;
|
||||
what->o_weight = things[TYP_RING].mi_wght;
|
||||
what->o_typname = things[TYP_RING].mi_name;
|
||||
what->o_vol = itemvol(what);
|
||||
}
|
||||
|
||||
/*
|
||||
* ringex:
|
||||
* Get extra gains from rings
|
||||
*/
|
||||
ringex(rtype)
|
||||
int rtype;
|
||||
{
|
||||
reg int howmuch = 0;
|
||||
|
||||
if (isring(LEFT, rtype))
|
||||
howmuch += cur_ring[LEFT]->o_ac;
|
||||
if (isring(RIGHT, rtype))
|
||||
howmuch += cur_ring[RIGHT]->o_ac;
|
||||
return howmuch;
|
||||
}
|
||||
|
||||
/*
|
||||
* iswearing:
|
||||
* Returns TRUE when the hero is wearing a certain type of ring
|
||||
*/
|
||||
iswearing(ring)
|
||||
int ring;
|
||||
{
|
||||
return (isring(LEFT,ring) || isring(RIGHT,ring));
|
||||
}
|
||||
|
||||
/*
|
||||
* isring:
|
||||
* Returns TRUE if a ring is on a hand
|
||||
*/
|
||||
isring(hand,ring)
|
||||
int hand, ring;
|
||||
{
|
||||
if (cur_ring[hand] != NULL && cur_ring[hand]->o_which == ring)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
371
srogue/rip.c
Normal file
371
srogue/rip.c
Normal file
|
|
@ -0,0 +1,371 @@
|
|||
/*
|
||||
* File for the fun, ends in death or a total win
|
||||
*
|
||||
* @(#)rip.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#include <fcntl.h>
|
||||
#include "rogue.h"
|
||||
#include "rogue.ext"
|
||||
|
||||
static char scoreline[100];
|
||||
|
||||
static char *rip[] = {
|
||||
" ____________________",
|
||||
" / \\",
|
||||
" / Bob Kindelberger's \\",
|
||||
" / Graveyard \\",
|
||||
" / \\",
|
||||
" / REST IN PEACE \\",
|
||||
" / \\",
|
||||
" | |",
|
||||
" | |",
|
||||
" | Destroyed by a |",
|
||||
" | |",
|
||||
" | |",
|
||||
" | |",
|
||||
" | |",
|
||||
" | |",
|
||||
" | |",
|
||||
" | |",
|
||||
" *| * * * * |*",
|
||||
" ________)\\\\//\\//\\)/\\//\\)/\\//\\)/\\//\\)/\\//\\//(________",
|
||||
};
|
||||
|
||||
#define RIP_LINES (sizeof rip / (sizeof (char *)))
|
||||
|
||||
char *killname();
|
||||
|
||||
/*
|
||||
* death:
|
||||
* Do something really fun when he dies
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
death(monst)
|
||||
char monst;
|
||||
{
|
||||
reg char dp, *killer;
|
||||
struct tm *lt;
|
||||
time_t date;
|
||||
char buf[LINLEN];
|
||||
struct tm *localtime();
|
||||
|
||||
time(&date);
|
||||
lt = localtime(&date);
|
||||
clear();
|
||||
move(3, 0);
|
||||
for (dp = 0; dp < RIP_LINES; dp++)
|
||||
printw("%s\n", rip[dp]);
|
||||
mvaddstr(10, 36 - ((strlen(whoami) + 1) / 2), whoami);
|
||||
killer = killname(monst);
|
||||
mvaddstr(12, 43, vowelstr(killer));
|
||||
mvaddstr(14, 36 - ((strlen(killer) + 1) / 2), killer);
|
||||
purse -= purse/10;
|
||||
sprintf(buf, "%d Gold Pieces", purse);
|
||||
mvaddstr(16, 36 - ((strlen(buf) + 1) / 2), buf);
|
||||
sprintf(prbuf, "%d/%d/%d", lt->tm_mon + 1, lt->tm_mday, 1900+lt->tm_year);
|
||||
mvaddstr(18, 32, prbuf);
|
||||
move(LINES-1, 0);
|
||||
refresh();
|
||||
score(purse, KILLED, monst);
|
||||
byebye(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* top ten entry structure
|
||||
*/
|
||||
static struct sc_ent {
|
||||
int sc_score; /* gold */
|
||||
char sc_name[LINLEN]; /* players name */
|
||||
int sc_flags; /* reason for being here */
|
||||
int sc_level; /* dungeon level */
|
||||
int sc_uid; /* user ID */
|
||||
unsigned char sc_monster; /* killer */
|
||||
int sc_explvl; /* experience level */
|
||||
long int sc_exppts; /* experience points */
|
||||
time_t sc_date; /* time this score was posted */
|
||||
} top_ten[10];
|
||||
|
||||
char *reason[] = {
|
||||
"Killed",
|
||||
"Chickened out",
|
||||
"A Total Winner"
|
||||
};
|
||||
int oldpurse;
|
||||
|
||||
/*
|
||||
* score:
|
||||
* Figure score and post it.
|
||||
*/
|
||||
score(amount, aflag, monst)
|
||||
char monst;
|
||||
int amount, aflag;
|
||||
{
|
||||
reg struct sc_ent *scp, *sc2;
|
||||
reg int i, fd, prflags = 0;
|
||||
reg FILE *outf;
|
||||
char *packend;
|
||||
|
||||
signal(SIGINT, byebye);
|
||||
signal(SIGQUIT, byebye);
|
||||
if (aflag != WINNER) {
|
||||
if (aflag == CHICKEN)
|
||||
packend = "when you chickened out";
|
||||
else
|
||||
packend = "at your untimely demise";
|
||||
mvaddstr(LINES - 1, 0, retstr);
|
||||
refresh();
|
||||
wgetnstr(stdscr,prbuf,80);
|
||||
oldpurse = purse;
|
||||
showpack(FALSE, packend);
|
||||
}
|
||||
/*
|
||||
* Open file and read list
|
||||
*/
|
||||
if ((fd = open(scorefile, O_RDWR | O_CREAT, 0666)) < 0)
|
||||
return;
|
||||
outf = (FILE *) fdopen(fd, "w");
|
||||
for (scp = top_ten; scp <= &top_ten[9]; scp++) {
|
||||
scp->sc_score = 0;
|
||||
for (i = 0; i < 80; i++)
|
||||
scp->sc_name[i] = rnd(255);
|
||||
scp->sc_flags = rnd(255);
|
||||
scp->sc_level = rnd(255);
|
||||
scp->sc_monster = rnd(255);
|
||||
scp->sc_uid = rnd(255);
|
||||
scp->sc_date = rnd(255);
|
||||
}
|
||||
mvaddstr(LINES - 1, 0, retstr);
|
||||
refresh();
|
||||
wgetnstr(stdscr,prbuf,80);
|
||||
if (author() || wizard)
|
||||
if (strcmp(prbuf, "names") == 0)
|
||||
prflags = 1;
|
||||
for(i = 0; i < 10; i++)
|
||||
{
|
||||
unsigned int mon;
|
||||
|
||||
encread((char *) &top_ten[i].sc_name, LINLEN, fd);
|
||||
encread((char *) scoreline, 100, fd);
|
||||
sscanf(scoreline, " %d %d %d %d %u %d %ld %lx \n",
|
||||
&top_ten[i].sc_score, &top_ten[i].sc_flags,
|
||||
&top_ten[i].sc_level, &top_ten[i].sc_uid,
|
||||
&mon, &top_ten[i].sc_explvl,
|
||||
&top_ten[i].sc_exppts, &top_ten[i].sc_date);
|
||||
top_ten[i].sc_monster = mon;
|
||||
}
|
||||
/*
|
||||
* Insert it in list if need be
|
||||
*/
|
||||
if (!waswizard) {
|
||||
for (scp = top_ten; scp <= &top_ten[9]; scp++)
|
||||
if (amount > scp->sc_score)
|
||||
break;
|
||||
if (scp <= &top_ten[9]) {
|
||||
for (sc2 = &top_ten[9]; sc2 > scp; sc2--)
|
||||
*sc2 = *(sc2-1);
|
||||
scp->sc_score = amount;
|
||||
strcpy(scp->sc_name, whoami);
|
||||
scp->sc_flags = aflag;
|
||||
if (aflag == WINNER)
|
||||
scp->sc_level = max_level;
|
||||
else
|
||||
scp->sc_level = level;
|
||||
scp->sc_monster = monst;
|
||||
scp->sc_uid = playuid;
|
||||
scp->sc_explvl = him->s_lvl;
|
||||
scp->sc_exppts = him->s_exp;
|
||||
time(&scp->sc_date);
|
||||
}
|
||||
}
|
||||
ignore();
|
||||
fseek(outf, 0L, 0);
|
||||
for(i = 0; i < 10; i++)
|
||||
{
|
||||
memset(scoreline,0,100);
|
||||
encwrite((char *) top_ten[i].sc_name, LINLEN, outf);
|
||||
sprintf(scoreline, " %d %d %d %d %u %d %ld %lx \n",
|
||||
top_ten[i].sc_score, top_ten[i].sc_flags,
|
||||
top_ten[i].sc_level, top_ten[i].sc_uid,
|
||||
top_ten[i].sc_monster, top_ten[i].sc_explvl,
|
||||
top_ten[i].sc_exppts, top_ten[i].sc_date);
|
||||
encwrite((char *) scoreline, 100, outf);
|
||||
}
|
||||
fclose(outf);
|
||||
signal(SIGINT, byebye);
|
||||
signal(SIGQUIT, byebye);
|
||||
clear();
|
||||
refresh();
|
||||
endwin();
|
||||
showtop(prflags); /* print top ten list */
|
||||
}
|
||||
|
||||
/*
|
||||
* showtop:
|
||||
* Display the top ten on the screen
|
||||
*/
|
||||
showtop(showname)
|
||||
int showname;
|
||||
{
|
||||
reg int fd, i;
|
||||
char *killer;
|
||||
struct sc_ent *scp;
|
||||
|
||||
if ((fd = open(scorefile, O_RDONLY)) < 0)
|
||||
return FALSE;
|
||||
|
||||
for(i = 0; i < 10; i++)
|
||||
{
|
||||
unsigned int mon;
|
||||
encread((char *) &top_ten[i].sc_name, LINLEN, fd);
|
||||
encread((char *) scoreline, 100, fd);
|
||||
sscanf(scoreline, " %d %d %d %d %u %d %ld %lx \n",
|
||||
&top_ten[i].sc_score, &top_ten[i].sc_flags,
|
||||
&top_ten[i].sc_level, &top_ten[i].sc_uid,
|
||||
&mon, &top_ten[i].sc_explvl,
|
||||
&top_ten[i].sc_exppts, &top_ten[i].sc_date);
|
||||
top_ten[i].sc_monster = mon;
|
||||
}
|
||||
close(fd);
|
||||
printf("Top Ten Adventurers:\nRank\tScore\tName\n");
|
||||
for (scp = top_ten; scp <= &top_ten[9]; scp++) {
|
||||
if (scp->sc_score > 0) {
|
||||
printf("%d\t%d\t%s: %s\t\t--> %s on level %d",
|
||||
scp - top_ten + 1, scp->sc_score, scp->sc_name,
|
||||
ctime(&scp->sc_date), reason[scp->sc_flags],
|
||||
scp->sc_level);
|
||||
if (scp->sc_flags == KILLED) {
|
||||
killer = killname(scp->sc_monster);
|
||||
printf(" by a%s %s",vowelstr(killer), killer);
|
||||
}
|
||||
printf(" [Exp: %d/%ld]",scp->sc_explvl,scp->sc_exppts);
|
||||
if (showname) {
|
||||
struct passwd *pp, *getpwuid();
|
||||
|
||||
if ((pp = getpwuid(scp->sc_uid)) == NULL)
|
||||
printf(" (%d)\n", scp->sc_uid);
|
||||
else
|
||||
printf(" (%s)\n", pp->pw_name);
|
||||
}
|
||||
else
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* total_winner:
|
||||
* The hero made it back out alive
|
||||
*/
|
||||
total_winner()
|
||||
{
|
||||
clear();
|
||||
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");
|
||||
addstr("\nYou have joined the elite ranks of those who have escaped the\n");
|
||||
addstr("Dungeons of Doom alive. You journey home and sell all your loot at\n");
|
||||
addstr("a great profit and are admitted to the fighters guild.\n");
|
||||
|
||||
mvaddstr(LINES - 1, 0,spacemsg);
|
||||
refresh();
|
||||
wait_for(stdscr, ' ');
|
||||
clear();
|
||||
oldpurse = purse;
|
||||
showpack(TRUE, NULL);
|
||||
score(purse, WINNER, 0);
|
||||
byebye(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* showpack:
|
||||
* Display the contents of the hero's pack
|
||||
*/
|
||||
showpack(winner, howso)
|
||||
bool winner;
|
||||
char *howso;
|
||||
{
|
||||
reg char *iname;
|
||||
reg int cnt, worth, ch;
|
||||
reg struct linked_list *item;
|
||||
reg struct object *obj;
|
||||
|
||||
idenpack();
|
||||
cnt = 1;
|
||||
clear();
|
||||
if (winner)
|
||||
mvaddstr(0, 0, " Worth Item");
|
||||
else
|
||||
mvprintw(0, 0, "Contents of your pack %s:\n",howso);
|
||||
ch = 'a';
|
||||
for (item = pack; item != NULL; item = next(item)) {
|
||||
obj = OBJPTR(item);
|
||||
iname = inv_name(obj, FALSE);
|
||||
if (winner) {
|
||||
worth = get_worth(obj);
|
||||
worth *= obj->o_count;
|
||||
mvprintw(cnt, 0, " %6d %s",worth,iname);
|
||||
purse += worth;
|
||||
}
|
||||
else {
|
||||
mvprintw(cnt, 0, "%c) %s\n",ch,iname);
|
||||
ch = npch(ch);
|
||||
}
|
||||
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 ---",oldpurse);
|
||||
refresh();
|
||||
}
|
||||
|
||||
/*
|
||||
* killname:
|
||||
* Returns what the hero was killed by.
|
||||
*/
|
||||
char *
|
||||
killname(monst)
|
||||
unsigned char monst;
|
||||
{
|
||||
if (monst < MAXMONS + 1)
|
||||
return monsters[monst].m_name;
|
||||
else /* things other than monsters */
|
||||
switch (monst) {
|
||||
case K_ARROW: return "crooked arrow";
|
||||
case K_DART: return "sharp dart";
|
||||
case K_BOLT: return "jagged bolt";
|
||||
case K_POOL: return "magic pool";
|
||||
case K_ROD: return "exploding rod";
|
||||
case K_SCROLL: return "burning scroll";
|
||||
case K_STONE: return "transmogrification to stone";
|
||||
case K_STARVE: return "starvation";
|
||||
}
|
||||
return "Bob Kindelberger";
|
||||
}
|
||||
48
srogue/rogue.ext
Normal file
48
srogue/rogue.ext
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
EXTTHG player;
|
||||
EXTWEP weaps[];
|
||||
EXTARM armors[];
|
||||
EXTMON monsters[], *mtlev[];
|
||||
EXTTRAP *trap_at(), traps[];
|
||||
EXTROOM *roomin(), *oldrp, rooms[];
|
||||
EXTCORD *rndmove(), *rnd_pos(), delta, stairs, oldpos, rndspot;
|
||||
EXTLKL *mlist, *lvl_obj, *new_item(), *new_thing(), *new_monster();
|
||||
EXTLKL *find_mons(), *wake_monster(), *find_obj(), *get_item();
|
||||
EXTOBJ *cur_armor, *cur_weapon, *cur_ring[];
|
||||
EXTMAG r_magic[], s_magic[], ws_magic[], p_magic[];
|
||||
EXTMAG things[], a_magic[], w_magic[];
|
||||
EXTINT max_hp, quiet, food_left, hungry_state, level, max_level;
|
||||
EXTINT foodlev, total, count, demoncnt, fung_hit, ntraps;
|
||||
EXTINT lastscore, purse, mpos, seed, dnum, no_food, packvol, playuid;
|
||||
EXTINT curprice, trader, group, levcount, levtype, ringfood, playgid;
|
||||
EXTINT chkstairs(), rollwand(), swander(), notslow(), notfight(), rnd();
|
||||
EXTINT rchg_str(), wghtchk(), stomach(), doctor(), runners(), status(), sight();
|
||||
extern void quit(), auto_save(), endit(), byebye(), game_err();
|
||||
EXTINT prntfile(), unconfuse(), sapem();
|
||||
EXTINT noteth(), notregen(), notinvinc(), unsee(), nohaste(), npch();
|
||||
EXTBOOL running, nochange, after, inwhgt, isfight, firstmove, nlmove;
|
||||
EXTBOOL wizard, waswizard, in_shell, amulet, door_stop, playing;
|
||||
EXTBOOL notify, ws_know[], p_know[], s_know[], r_know[], inpool;
|
||||
EXTCHAR home[], file_name[], whoami[], fruit[], curpurch[], scorefile[];
|
||||
EXTCHAR *r_stones[], *p_colors[], *s_names[], *ws_type[], *ws_made[];
|
||||
EXTCHAR *ws_guess[], *s_guess[], *r_guess[], *p_guess[];/*, *unctrl();*/
|
||||
EXTCHAR morestr[], prbuf[], huh[], *identify(), *vowelstr();
|
||||
EXTCHAR *new(), *strcpy(), *strcat(), *inv_name(), pack_char(), *prname();
|
||||
EXTCHAR *num(), *getenv(), *tr_name(), *release, take, runch;
|
||||
EXTCHAR retstr[], wizstr[], spacemsg[], illegal[], callit[], starlist[];
|
||||
EXTSTAT max_stats, *him;
|
||||
extern struct magic_info thnginfo[];
|
||||
extern struct real re_stats;
|
||||
extern long e_levels[];
|
||||
extern struct rod ws_stuff[];
|
||||
extern struct sgttyb _tty;
|
||||
|
||||
extern struct coord nh;
|
||||
extern struct delayed_action d_list[MAXDAEMONS];
|
||||
extern int between;
|
||||
|
||||
extern char *rainbow[NCOLORS];
|
||||
extern char *sylls[NSYLS];
|
||||
extern char *stones[NSTONES];
|
||||
extern char *wood[NWOOD];
|
||||
extern char *metal[NMETAL];
|
||||
|
||||
701
srogue/rogue.h
Normal file
701
srogue/rogue.h
Normal file
|
|
@ -0,0 +1,701 @@
|
|||
/*
|
||||
* Rogue definitions and variable declarations
|
||||
*
|
||||
* @(#)rogue.h 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#ifdef BSD
|
||||
#include "cx.h"
|
||||
#endif
|
||||
|
||||
|
||||
#include <ctype.h>
|
||||
#include <curses.h>
|
||||
|
||||
#ifdef ATT
|
||||
#define CBREAK FALSE
|
||||
#define _IOSTRG 01
|
||||
#endif
|
||||
|
||||
#define reg register /* register abbr. */
|
||||
|
||||
/*
|
||||
* Maximum number of different things
|
||||
*/
|
||||
|
||||
#define NCOLORS 32
|
||||
#define NSYLS 159
|
||||
#define NSTONES 35
|
||||
#define NWOOD 24
|
||||
#define NMETAL 15
|
||||
|
||||
#define MAXDAEMONS 20
|
||||
|
||||
#define TYPETRAPS 9 /* max types of traps */
|
||||
#define MAXROOMS 9 /* max rooms per level */
|
||||
#define MAXTHINGS 9 /* max things on each level */
|
||||
#define MAXOBJ 9 /* max goodies on each level */
|
||||
#define MAXPACK 23 /* max things this hero can carry */
|
||||
#define MAXTRAPS 10 /* max traps per level */
|
||||
#define MAXMONS 52 /* max available monsters */
|
||||
#define MONRANGE 20 /* max # of monsters avail each level */
|
||||
#define AMLEVEL 35 /* earliest level that amulet can appear */
|
||||
#define MAXPURCH 4 /* max purchases in trading post */
|
||||
#define MINABIL 3 /* minimum for any ability */
|
||||
#define MAXSTR 24 /* maximum strength */
|
||||
#define MAXOTHER 18 /* maximum wis, dex, con */
|
||||
#define NORMAC 10 /* normal hero armor class (no armor) */
|
||||
#define MONWIS 10 /* monsters standard wisdom */
|
||||
|
||||
#define NORMLEV 0 /* normal level */
|
||||
#define POSTLEV 1 /* trading post level */
|
||||
#define MAZELEV 2 /* maze level */
|
||||
|
||||
#define NORMFOOD 0 /* normal food's group no. */
|
||||
#define FRUITFOOD 1 /* fruit's group no. */
|
||||
#define NEWGROUP 2 /* start of group no. other than food */
|
||||
|
||||
#define NUMTHINGS 8 /* types of goodies for hero */
|
||||
#define TYP_POTION 0
|
||||
#define TYP_SCROLL 1
|
||||
#define TYP_FOOD 2
|
||||
#define TYP_WEAPON 3
|
||||
#define TYP_ARMOR 4
|
||||
#define TYP_RING 5
|
||||
#define TYP_STICK 6
|
||||
#define TYP_AMULET 7
|
||||
|
||||
#define V_PACK 3600 /* max volume in pack */
|
||||
#define V_POTION 50 /* volume of potion */
|
||||
#define V_SCROLL 80 /* volume of scroll */
|
||||
#define V_FOOD 35 /* volume of food */
|
||||
#define V_WEAPON 0 /* volume of weapon (depends on wep) */
|
||||
#define V_ARMOR 0 /* volume of armor (depends on armor) */
|
||||
#define V_RING 20 /* volume of ring */
|
||||
#define V_STICK 0 /* volume of stick (depends on staff/wand) */
|
||||
#define V_AMULET 30 /* volume of amulet */
|
||||
|
||||
#define V_WS_STAFF 200 /* volume of a staff */
|
||||
#define V_WS_WAND 110 /* volume of a wand */
|
||||
#define W_WS_STAFF 100 /* weight of a staff */
|
||||
#define W_WS_WAND 60 /* weight of a wand */
|
||||
|
||||
#define FROMRING 2
|
||||
#define DONTCARE -1
|
||||
#define ANYTHING -1,-1 /* DONTCARE, DONTCARE */
|
||||
|
||||
#define K_ARROW 240 /* killed by an arrow */
|
||||
#define K_DART 241 /* killed by a dart */
|
||||
#define K_BOLT 242 /* killed by a bolt */
|
||||
#define K_POOL 243 /* killed by drowning */
|
||||
#define K_ROD 244 /* killed by an exploding rod */
|
||||
#define K_SCROLL 245 /* killed by a burning scroll */
|
||||
#define K_STONE 246 /* killed by materializing in rock */
|
||||
#define K_STARVE 247 /* killed by starvation */
|
||||
/*
|
||||
* return values for get functions
|
||||
*/
|
||||
|
||||
#define NORM 0 /* normal exit */
|
||||
#define QUIT 1 /* quit option setting */
|
||||
#define MINUS 2 /* back up one option */
|
||||
|
||||
/*
|
||||
* Return values for games end
|
||||
*/
|
||||
#define KILLED 0 /* hero was killed */
|
||||
#define CHICKEN 1 /* hero chickened out (quit) */
|
||||
#define WINNER 2 /* hero was a total winner */
|
||||
|
||||
/*
|
||||
* return values for chase routines
|
||||
*/
|
||||
#define CHASE 0 /* continue chasing hero */
|
||||
#define FIGHT 1 /* fight the hero */
|
||||
#define GONER 2 /* chaser fell into a trap */
|
||||
|
||||
/*
|
||||
* All the fun defines
|
||||
*/
|
||||
#define next(ptr) (*ptr).l_next
|
||||
#define prev(ptr) (*ptr).l_prev
|
||||
#define ldata(ptr) (*ptr).l_data
|
||||
#define OBJPTR(what) (struct object *)((*what).l_data)
|
||||
#define THINGPTR(what) (struct thing *)((*what).l_data)
|
||||
|
||||
#define inroom(rp, cp) (\
|
||||
(cp)->x <= (rp)->r_pos.x + ((rp)->r_max.x - 1) && \
|
||||
(rp)->r_pos.x <= (cp)->x && (cp)->y <= (rp)->r_pos.y + \
|
||||
((rp)->r_max.y - 1) && (rp)->r_pos.y <= (cp)->y)
|
||||
|
||||
#define unc(cp) (cp).y, (cp).x
|
||||
#define cmov(xy) move((xy).y, (xy).x)
|
||||
#define DISTANCE(y1,x1,y2,x2) ((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1))
|
||||
#define when break;case
|
||||
#define otherwise break;default
|
||||
#define until(expr) while(!(expr))
|
||||
|
||||
#define ce(a, b) ((a).x == (b).x && (a).y == (b).y)
|
||||
#define draw(window) wrefresh(window)
|
||||
|
||||
#define hero player.t_pos
|
||||
#define pstats player.t_stats
|
||||
#define pack player.t_pack
|
||||
|
||||
#define herowis() (getpwis(him))
|
||||
#define herodex() (getpdex(him,FALSE))
|
||||
#define herostr() (pstats.s_ef.a_str)
|
||||
#define herocon() (pstats.s_ef.a_con)
|
||||
|
||||
#define attach(a,b) _attach(&a,b)
|
||||
#define detach(a,b) _detach(&a,b)
|
||||
#define free_list(a) _free_list(&a)
|
||||
#ifndef max
|
||||
#define max(a, b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
#define goingup() (level < max_level)
|
||||
|
||||
#define on(thing, flag) (((thing).t_flags & flag) != 0)
|
||||
#define off(thing, flag) (((thing).t_flags & flag) == 0)
|
||||
#undef CTRL
|
||||
#define CTRL(ch) (ch & 0x1F)
|
||||
|
||||
#define ALLOC(x) malloc((unsigned int) x)
|
||||
#define FREE(x) free((char *) x)
|
||||
#define EQSTR(a, b, c) (strncmp(a, b, c) == 0)
|
||||
#define GOLDCALC (rnd(50 + 10 * level) + 2)
|
||||
#define ISMULT(type) (type == POTION || type == SCROLL || type == FOOD)
|
||||
|
||||
#define newgrp() ++group
|
||||
#define o_charges o_ac
|
||||
|
||||
|
||||
/*
|
||||
* Things that appear on the screens
|
||||
*/
|
||||
#define PASSAGE '#'
|
||||
#define DOOR '+'
|
||||
#define FLOOR '.'
|
||||
#define PLAYER '@'
|
||||
#define POST '^'
|
||||
#define MAZETRAP '\\'
|
||||
#define TRAPDOOR '>'
|
||||
#define ARROWTRAP '{'
|
||||
#define SLEEPTRAP '$'
|
||||
#define BEARTRAP '}'
|
||||
#define TELTRAP '~'
|
||||
#define DARTTRAP '`'
|
||||
#define POOL '"'
|
||||
#define SECRETDOOR '&'
|
||||
#define STAIRS '%'
|
||||
#define GOLD '*'
|
||||
#define POTION '!'
|
||||
#define SCROLL '?'
|
||||
#define MAGIC '$'
|
||||
#define FOOD ':'
|
||||
#define WEAPON ')'
|
||||
#define ARMOR ']'
|
||||
#define AMULET ','
|
||||
#define RING '='
|
||||
#define STICK '/'
|
||||
#define CALLABLE -1
|
||||
|
||||
|
||||
/*
|
||||
* stuff to do with encumberence
|
||||
*/
|
||||
#define NORMENCB 1500 /* normal encumberence */
|
||||
#define SOMTHERE 5 /* something is in the way for dropping */
|
||||
#define CANTDROP 6 /* cant drop it cause its cursed */
|
||||
#define F_OKAY 0 /* have plenty of food in stomach */
|
||||
#define F_HUNGRY 1 /* player is hungry */
|
||||
#define F_WEAK 2 /* weak from lack of food */
|
||||
#define F_FAINT 3 /* fainting from lack of food */
|
||||
|
||||
|
||||
/*
|
||||
* Various constants
|
||||
*/
|
||||
#define PASSWD "mTuZ7WUV9RWkQ"
|
||||
#define BEARTIME 3
|
||||
#define SLEEPTIME 5
|
||||
#define HEALTIME 30
|
||||
#define HOLDTIME 2
|
||||
#define STPOS 0
|
||||
#define WANDERTIME 70
|
||||
#define BEFORE 1
|
||||
#define AFTER 2
|
||||
#define HUHDURATION 20
|
||||
#define SEEDURATION 850
|
||||
#define HUNGERTIME 1300
|
||||
#define WEAKTIME 150
|
||||
#define HUNGTIME 300 /* 2 * WEAKTIME */
|
||||
#define STOMACHSIZE 2000
|
||||
#define ESCAPE 27
|
||||
#define LEFT 0
|
||||
#define RIGHT 1
|
||||
#define BOLT_LENGTH 6
|
||||
|
||||
#define STR 1
|
||||
#define DEX 2
|
||||
#define CON 3
|
||||
#define WIS 4
|
||||
|
||||
/*
|
||||
* Save against things
|
||||
*/
|
||||
#define VS_POISON 00
|
||||
#define VS_PARALYZATION 00
|
||||
#define VS_DEATH 00
|
||||
#define VS_PETRIFICATION 01
|
||||
#define VS_BREATH 02
|
||||
#define VS_MAGIC 03
|
||||
|
||||
|
||||
/*
|
||||
* Various flag bits
|
||||
*/
|
||||
#define ISSTUCK 0000001 /* monster can't run (violet fungi) */
|
||||
#define ISDARK 0000001 /* room is dark */
|
||||
#define ISCURSED 000001 /* object is cursed */
|
||||
#define ISBLIND 0000001 /* hero is blind */
|
||||
#define ISPARA 0000002 /* monster is paralyzed */
|
||||
#define ISGONE 0000002 /* room is gone */
|
||||
#define ISKNOW 0000002 /* object is known */
|
||||
#define ISRUN 0000004 /* Hero & monsters are running */
|
||||
#define ISTREAS 0000004 /* room is a treasure room */
|
||||
#define ISPOST 0000004 /* object is in a trading post */
|
||||
#define ISFOUND 0000010 /* trap is found */
|
||||
#define ISINVINC 000010 /* player is invincible */
|
||||
#define ISINVIS 0000020 /* monster is invisible */
|
||||
#define ISPROT 0000020 /* object is protected somehow */
|
||||
#define ISMEAN 0000040 /* monster is mean */
|
||||
#define ISBLESS 0000040 /* object is blessed */
|
||||
#define ISGREED 0000100 /* monster is greedy */
|
||||
#define ISWOUND 0000200 /* monster is wounded */
|
||||
#define ISHELD 0000400 /* hero is held fast */
|
||||
#define ISHUH 0001000 /* hero | monster is confused */
|
||||
#define ISREGEN 0002000 /* monster is regenerative */
|
||||
#define CANHUH 0004000 /* hero can confuse monsters */
|
||||
#define CANSEE 0010000 /* hero can see invisible monsters */
|
||||
#define WASHIT 0010000 /* hero has hit monster at least once */
|
||||
#define ISMISL 0020000 /* object is normally thrown in attacks */
|
||||
#define ISCANC 0020000 /* monsters special attacks are canceled */
|
||||
#define ISMANY 0040000 /* objects are found in a group (> 1) */
|
||||
#define ISSLOW 0040000 /* hero | monster is slow */
|
||||
#define ISHASTE 0100000 /* hero | monster is fast */
|
||||
#define ISETHER 0200000 /* hero is thin as air */
|
||||
#define NONE 100 /* equal to 'd' (used for weaps) */
|
||||
|
||||
|
||||
/*
|
||||
* Potion types
|
||||
*/
|
||||
#define P_CONFUSE 0 /* confusion */
|
||||
#define P_PARALYZE 1 /* paralysis */
|
||||
#define P_POISON 2 /* poison */
|
||||
#define P_STRENGTH 3 /* gain strength */
|
||||
#define P_SEEINVIS 4 /* see invisible */
|
||||
#define P_HEALING 5 /* healing */
|
||||
#define P_MFIND 6 /* monster detection */
|
||||
#define P_TFIND 7 /* magic detection */
|
||||
#define P_RAISE 8 /* raise level */
|
||||
#define P_XHEAL 9 /* extra healing */
|
||||
#define P_HASTE 10 /* haste self */
|
||||
#define P_RESTORE 11 /* restore strength */
|
||||
#define P_BLIND 12 /* blindness */
|
||||
#define P_NOP 13 /* thirst quenching */
|
||||
#define P_DEX 14 /* increase dexterity */
|
||||
#define P_ETH 15 /* etherealness */
|
||||
#define P_SMART 16 /* wisdom */
|
||||
#define P_REGEN 17 /* regeneration */
|
||||
#define P_SUPHERO 18 /* super ability */
|
||||
#define P_DECREP 19 /* decrepedness */
|
||||
#define P_INVINC 20 /* invicibility */
|
||||
#define MAXPOTIONS 21 /* types of potions */
|
||||
|
||||
|
||||
/*
|
||||
* Scroll types
|
||||
*/
|
||||
#define S_CONFUSE 0 /* monster confusion */
|
||||
#define S_MAP 1 /* magic mapping */
|
||||
#define S_LIGHT 2 /* light */
|
||||
#define S_HOLD 3 /* hold monster */
|
||||
#define S_SLEEP 4 /* sleep */
|
||||
#define S_ARMOR 5 /* enchant armor */
|
||||
#define S_IDENT 6 /* identify */
|
||||
#define S_SCARE 7 /* scare monster */
|
||||
#define S_GFIND 8 /* gold detection */
|
||||
#define S_TELEP 9 /* teleportation */
|
||||
#define S_ENCH 10 /* enchant weapon */
|
||||
#define S_CREATE 11 /* create monster */
|
||||
#define S_REMOVE 12 /* remove curse */
|
||||
#define S_AGGR 13 /* aggravate monster */
|
||||
#define S_NOP 14 /* blank paper */
|
||||
#define S_GENOCIDE 15 /* genocide */
|
||||
#define S_KNOWALL 16 /* item knowledge */
|
||||
#define S_PROTECT 17 /* item protection */
|
||||
#define S_DCURSE 18 /* demons curse */
|
||||
#define S_DLEVEL 19 /* transport */
|
||||
#define S_ALLENCH 20 /* enchantment */
|
||||
#define S_BLESS 21 /* gods blessing */
|
||||
#define S_MAKEIT 22 /* aquirement */
|
||||
#define S_BAN 23 /* banishment */
|
||||
#define S_CWAND 24 /* charge wands */
|
||||
#define S_LOCTRAP 25 /* locate traps */
|
||||
#define MAXSCROLLS 26 /* types of scrolls */
|
||||
|
||||
|
||||
/*
|
||||
* Weapon types
|
||||
*/
|
||||
#define MACE 0 /* mace */
|
||||
#define SWORD 1 /* long sword */
|
||||
#define BOW 2 /* short bow */
|
||||
#define ARROW 3 /* arrow */
|
||||
#define DAGGER 4 /* dagger */
|
||||
#define ROCK 5 /* rocks */
|
||||
#define TWOSWORD 6 /* two-handed sword */
|
||||
#define SLING 7 /* sling */
|
||||
#define DART 8 /* darts */
|
||||
#define CROSSBOW 9 /* crossbow */
|
||||
#define BOLT 10 /* crossbow bolt */
|
||||
#define SPEAR 11 /* spear */
|
||||
#define TRIDENT 12 /* trident */
|
||||
#define SPETUM 13 /* spetum */
|
||||
#define BARDICHE 14 /* bardiche */
|
||||
#define PIKE 15 /* pike */
|
||||
#define BASWORD 16 /* bastard sword */
|
||||
#define HALBERD 17 /* halberd */
|
||||
#define MAXWEAPONS 18 /* types of weapons */
|
||||
|
||||
|
||||
/*
|
||||
* Armor types
|
||||
*/
|
||||
#define LEATHER 0 /* leather */
|
||||
#define RINGMAIL 1 /* ring */
|
||||
#define STUDDED 2 /* studded leather */
|
||||
#define SCALE 3 /* scale */
|
||||
#define PADDED 4 /* padded */
|
||||
#define CHAIN 5 /* chain */
|
||||
#define SPLINT 6 /* splint */
|
||||
#define BANDED 7 /* banded */
|
||||
#define PLATEMAIL 8 /* plate mail */
|
||||
#define PLATEARMOR 9 /* plate armor */
|
||||
#define MAXARMORS 10 /* types of armor */
|
||||
|
||||
|
||||
/*
|
||||
* Ring types
|
||||
*/
|
||||
#define R_PROTECT 0 /* protection */
|
||||
#define R_ADDSTR 1 /* add strength */
|
||||
#define R_SUSTSTR 2 /* sustain strength */
|
||||
#define R_SEARCH 3 /* searching */
|
||||
#define R_SEEINVIS 4 /* see invisible */
|
||||
#define R_CONST 5 /* constitution */
|
||||
#define R_AGGR 6 /* aggravate monster */
|
||||
#define R_ADDHIT 7 /* agility */
|
||||
#define R_ADDDAM 8 /* increase damage */
|
||||
#define R_REGEN 9 /* regeneration */
|
||||
#define R_DIGEST 10 /* slow digestion */
|
||||
#define R_TELEPORT 11 /* teleportation */
|
||||
#define R_STEALTH 12 /* stealth */
|
||||
#define R_SPEED 13 /* speed */
|
||||
#define R_FTRAPS 14 /* find traps */
|
||||
#define R_DELUS 15 /* delusion */
|
||||
#define R_SUSAB 16 /* sustain ability */
|
||||
#define R_BLIND 17 /* blindness */
|
||||
#define R_SLOW 18 /* lethargy */
|
||||
#define R_GIANT 19 /* ogre strength */
|
||||
#define R_SAPEM 20 /* enfeeblement */
|
||||
#define R_HEAVY 21 /* burden */
|
||||
#define R_LIGHT 22 /* illumination */
|
||||
#define R_BREATH 23 /* fire protection */
|
||||
#define R_KNOW 24 /* wisdom */
|
||||
#define R_DEX 25 /* dexterity */
|
||||
#define MAXRINGS 26 /* types of rings */
|
||||
|
||||
|
||||
/*
|
||||
* Rod/Wand/Staff types
|
||||
*/
|
||||
|
||||
#define WS_LIGHT 0 /* light */
|
||||
#define WS_HIT 1 /* striking */
|
||||
#define WS_ELECT 2 /* lightning */
|
||||
#define WS_FIRE 3 /* fire */
|
||||
#define WS_COLD 4 /* cold */
|
||||
#define WS_POLYM 5 /* polymorph */
|
||||
#define WS_MISSILE 6 /* magic missile */
|
||||
#define WS_HASTE_M 7 /* haste monster */
|
||||
#define WS_SLOW_M 8 /* slow monster */
|
||||
#define WS_DRAIN 9 /* drain life */
|
||||
#define WS_NOP 10 /* nothing */
|
||||
#define WS_TELAWAY 11 /* teleport away */
|
||||
#define WS_TELTO 12 /* teleport to */
|
||||
#define WS_CANCEL 13 /* cancellation */
|
||||
#define WS_SAPLIFE 14 /* sap life */
|
||||
#define WS_CURE 15 /* curing */
|
||||
#define WS_PYRO 16 /* pyromania */
|
||||
#define WS_ANNIH 17 /* annihilate monster */
|
||||
#define WS_PARZ 18 /* paralyze monster */
|
||||
#define WS_HUNGER 19 /* food absorption */
|
||||
#define WS_MREG 20 /* regenerate monster */
|
||||
#define WS_MINVIS 21 /* hide monster */
|
||||
#define WS_ANTIM 22 /* anti-matter */
|
||||
#define WS_MOREMON 23 /* clone monster */
|
||||
#define WS_CONFMON 24 /* confuse monster */
|
||||
#define WS_MDEG 25 /* degenerate monster */
|
||||
#define MAXSTICKS 26 /* max types of sticks */
|
||||
|
||||
#define MAXAMULETS 1 /* types of amulets */
|
||||
#define MAXFOODS 1 /* types of food */
|
||||
|
||||
|
||||
/*
|
||||
* Now we define the structures and types
|
||||
*/
|
||||
|
||||
struct delayed_action {
|
||||
int d_type;
|
||||
int (*d_func)();
|
||||
int d_arg;
|
||||
int d_time;
|
||||
};
|
||||
|
||||
/*
|
||||
* Help list
|
||||
*/
|
||||
struct h_list {
|
||||
char h_ch;
|
||||
char *h_desc;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Coordinate data type
|
||||
*/
|
||||
struct coord {
|
||||
int x; /* column position */
|
||||
int y; /* row position */
|
||||
};
|
||||
|
||||
struct monlev {
|
||||
int l_lev; /* lowest level for a monster */
|
||||
int h_lev; /* highest level for a monster */
|
||||
bool d_wand; /* TRUE if monster wanders */
|
||||
};
|
||||
|
||||
/*
|
||||
* Linked list data type
|
||||
*/
|
||||
struct linked_list {
|
||||
struct linked_list *l_next;
|
||||
struct linked_list *l_prev;
|
||||
char *l_data; /* Various structure pointers */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Stuff about magic items
|
||||
*/
|
||||
#define mi_wght mi_worth
|
||||
struct magic_item {
|
||||
char *mi_name; /* name of item */
|
||||
int mi_prob; /* probability of getting item */
|
||||
int mi_worth; /* worth of item */
|
||||
};
|
||||
|
||||
struct magic_info {
|
||||
int mf_max; /* max # of this type */
|
||||
int mf_vol; /* volume of this item */
|
||||
char mf_show; /* appearance on screen */
|
||||
struct magic_item *mf_magic; /* pointer to magic tables */
|
||||
};
|
||||
|
||||
/*
|
||||
* staff/wand stuff
|
||||
*/
|
||||
struct rod {
|
||||
char *ws_type; /* either "staff" or "wand" */
|
||||
char *ws_made; /* "mahogany", etc */
|
||||
int ws_vol; /* volume of this type stick */
|
||||
int ws_wght; /* weight of this type stick */
|
||||
};
|
||||
|
||||
/*
|
||||
* armor structure
|
||||
*/
|
||||
struct init_armor {
|
||||
int a_class; /* normal armor class */
|
||||
int a_wght; /* weight of armor */
|
||||
int a_vol; /* volume of armor */
|
||||
};
|
||||
|
||||
/*
|
||||
* weapon structure
|
||||
*/
|
||||
struct init_weps {
|
||||
char *w_dam; /* hit damage */
|
||||
char *w_hrl; /* hurl damage */
|
||||
int w_flags; /* flags */
|
||||
int w_wght; /* weight of weapon */
|
||||
int w_vol; /* volume of weapon */
|
||||
char w_launch; /* need to launch it */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Room structure
|
||||
*/
|
||||
struct room {
|
||||
struct coord r_pos; /* Upper left corner */
|
||||
struct coord r_max; /* Size of room */
|
||||
struct coord r_gold; /* Where the gold is */
|
||||
struct coord r_exit[4]; /* Where the exits are */
|
||||
struct room *r_ptr[4]; /* this exits' link to next rm */
|
||||
int r_goldval; /* How much the gold is worth */
|
||||
int r_flags; /* Info about the room */
|
||||
int r_nexits; /* Number of exits */
|
||||
};
|
||||
|
||||
/*
|
||||
* Array of all traps on this level
|
||||
*/
|
||||
struct trap {
|
||||
struct coord tr_pos; /* Where trap is */
|
||||
struct coord tr_goto; /* where trap tranports to (if any) */
|
||||
int tr_flags; /* Info about trap */
|
||||
char tr_type; /* What kind of trap */
|
||||
};
|
||||
|
||||
/*
|
||||
* structure for describing true abilities
|
||||
*/
|
||||
struct real {
|
||||
int a_str; /* strength (3-24) */
|
||||
int a_dex; /* dexterity (3-18) */
|
||||
int a_wis; /* wisdom (3-18) */
|
||||
int a_con; /* constitution (3-18) */
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure describing a fighting being
|
||||
*/
|
||||
struct stats {
|
||||
struct real s_re; /* True ability */
|
||||
struct real s_ef; /* Effective ability */
|
||||
long s_exp; /* Experience */
|
||||
int s_lvl; /* Level of mastery */
|
||||
int s_arm; /* Armor class */
|
||||
int s_hpt; /* Hit points */
|
||||
int s_maxhp; /* max value of hit points */
|
||||
int s_pack; /* current weight of his pack */
|
||||
int s_carry; /* max weight he can carry */
|
||||
char s_dmg[16]; /* String describing damage done */
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure for monsters and player
|
||||
*/
|
||||
struct thing {
|
||||
struct stats t_stats; /* Physical description */
|
||||
struct coord t_pos; /* Position */
|
||||
struct coord t_oldpos; /* last spot of it */
|
||||
struct coord *t_dest; /* Where it is running to */
|
||||
struct linked_list *t_pack; /* What the thing is carrying */
|
||||
struct room *t_room; /* Room this thing is in */
|
||||
long t_flags; /* State word */
|
||||
int t_indx; /* Index into monster structure */
|
||||
int t_nomove; /* # turns you cant move */
|
||||
int t_nocmd; /* # turns you cant do anything */
|
||||
bool t_turn; /* If slow, is it a turn to move */
|
||||
char t_type; /* What it is */
|
||||
char t_disguise; /* What mimic looks like */
|
||||
char t_oldch; /* Char that was where it was */
|
||||
char t_reserved;
|
||||
};
|
||||
|
||||
/*
|
||||
* Array containing information on all the various types of mosnters
|
||||
*/
|
||||
struct monster {
|
||||
char *m_name; /* What to call the monster */
|
||||
char m_show; /* char that monster shows */
|
||||
short m_carry; /* Probability of having an item */
|
||||
struct monlev m_lev; /* level stuff */
|
||||
long m_flags; /* Things about the monster */
|
||||
struct stats m_stats; /* Initial stats */
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure for a thing that the rogue can carry
|
||||
*/
|
||||
struct object {
|
||||
struct coord o_pos; /* Where it lives on the screen */
|
||||
char o_damage[8]; /* Damage if used like sword */
|
||||
char o_hurldmg[8]; /* Damage if thrown */
|
||||
char *o_typname; /* name this thing is called */
|
||||
int o_type; /* What kind of object it is */
|
||||
int o_count; /* Count for plural objects */
|
||||
int o_which; /* Which object of a type it is */
|
||||
int o_hplus; /* Plusses to hit */
|
||||
int o_dplus; /* Plusses to damage */
|
||||
int o_ac; /* Armor class or charges */
|
||||
int o_flags; /* Information about objects */
|
||||
int o_group; /* Group number for this object */
|
||||
int o_weight; /* weight of this object */
|
||||
int o_vol; /* volume of this object */
|
||||
char o_launch; /* What you need to launch it */
|
||||
};
|
||||
|
||||
extern WINDOW *cw, *hw, *mw;
|
||||
|
||||
#define LINLEN 80 /* length of buffers */
|
||||
|
||||
#define EXTLKL extern struct linked_list
|
||||
#define EXTTHG extern struct thing
|
||||
#define EXTOBJ extern struct object
|
||||
#define EXTSTAT extern struct stats
|
||||
#define EXTCORD extern struct coord
|
||||
#define EXTMON extern struct monster
|
||||
#define EXTARM extern struct init_armor
|
||||
#define EXTWEP extern struct init_weps
|
||||
#define EXTMAG extern struct magic_item
|
||||
#define EXTROOM extern struct room
|
||||
#define EXTTRAP extern struct trap
|
||||
#define EXTINT extern int
|
||||
#define EXTBOOL extern bool
|
||||
#define EXTCHAR extern char
|
||||
|
||||
#ifdef BSD
|
||||
#define flushout() ioctl(_tty_ch, TIOCFLUSH, 0)
|
||||
#endif
|
||||
|
||||
#ifdef ATT
|
||||
|
||||
struct sgttyb {
|
||||
char sg_ispeed; /* input speed */
|
||||
char sg_ospeed; /* output speed */
|
||||
char sg_erase; /* erase character */
|
||||
char sg_kill; /* kill character */
|
||||
int sg_flags; /* mode flags */
|
||||
};
|
||||
|
||||
struct sgttyb _tty;
|
||||
#define flushout() ioctl(2, TCFLSH, 0)
|
||||
|
||||
#endif
|
||||
636
srogue/rogue.nr
Normal file
636
srogue/rogue.nr
Normal file
|
|
@ -0,0 +1,636 @@
|
|||
.PH
|
||||
.fp 9 CR
|
||||
.nr Hu 1
|
||||
.nr Pt 0
|
||||
.SA 1
|
||||
.S +4 C
|
||||
.ad c
|
||||
.B "Super-Rogue Version 9.0"
|
||||
.br
|
||||
.ad b
|
||||
.SP 0.45
|
||||
.S -4 C
|
||||
.ad c
|
||||
.I "Robert D. Kindelberger"
|
||||
.br
|
||||
.ad b
|
||||
.SP 2.6
|
||||
.ad c
|
||||
.I "A Tutorial on the Visual Game of Rogue - Version 9.0"
|
||||
.br
|
||||
.ad b
|
||||
.SP 2
|
||||
.P
|
||||
Rogue is a visual CRT based fantasy game which runs
|
||||
under the UNIX\*F
|
||||
.FS
|
||||
UNIX is a trademark of AT&T Bell Laboratories.
|
||||
.FE
|
||||
timesharing system. This paper describes
|
||||
how to play rogue and gives a few hints for those who might
|
||||
otherwise get lost (or killed) in the Dungeons of Doom.
|
||||
.SP 5
|
||||
.PH "''- % -''"
|
||||
.H 1 INTRODUCTION
|
||||
.P
|
||||
You have just finished your years as a student
|
||||
at the local fighter's guild.
|
||||
After much practice and sweat you have finally completed your training and
|
||||
are ready to embark upon a perilous adventure. As a test of your skills,
|
||||
the local guildmasters have sent you into the Dungeons of Doom. Your
|
||||
task is to return with the Amulet of Yendor.
|
||||
Your reward for the completion
|
||||
of this task will be a full membership in the local guild.
|
||||
In addition, you are
|
||||
allowed to keep all the loot you bring back from the dungeons.
|
||||
.P
|
||||
In preparation for your journey, you are given an enchanted weapon, taken
|
||||
from a dragon's hoard in the far off Dark Mountains.
|
||||
You are also outfitted
|
||||
with elf-crafted armor and given enough food to reach the dungeons. You
|
||||
say good-bye to family and friends for what may be the last time and head
|
||||
up the road.
|
||||
.P
|
||||
You set out on your way to the dungeons and after
|
||||
several days of uneventful
|
||||
travel, you see the ancient ruins that mark the entrance to the Dungeons
|
||||
of Doom. It is late at night so you make camp at the entrance and spend
|
||||
the night sleeping under the open skies. In the morning you gather
|
||||
your weapon, put on your armor, eat what is almost your last food and enter
|
||||
the dungeons.
|
||||
.H 1 "WHAT IS GOING ON HERE?"
|
||||
.P
|
||||
You have just begun a game of rogue.
|
||||
Your goal is to grab as much treasure
|
||||
as you can, find the \f3Amulet of Yendor\f1, and get out of the Dungeons
|
||||
of Doom alive.
|
||||
On the screen, a map of where you have been and what you have seen on
|
||||
the current dungeon level is kept. As you explore more of the level,
|
||||
it appears on the screen in front of you.
|
||||
.P
|
||||
Rogue differs from most computer fantasy games in that it is screen
|
||||
oriented. Commands are all one or two keystrokes\*F
|
||||
.FS
|
||||
As opposed to pseudo English sentences.
|
||||
.FE
|
||||
and the results of your commands are displayed
|
||||
graphically on the screen rather than being explained in words.
|
||||
.P
|
||||
Another major difference between rogue and other computer fantasy games
|
||||
is that once you have solved all the puzzles in a standard fantasy game,
|
||||
it has lost most of its excitement and it ceases to be fun. Rogue on the
|
||||
other hand generates a new dungeon every time you play it and
|
||||
even the author finds it an entertaining and exciting game.
|
||||
.H 1 "WHAT DO ALL THOSE THINGS ON THE SCREEN MEAN?"
|
||||
.P
|
||||
In order to understand what is going on in rogue you have to first get
|
||||
some grasp of what rogue is doing with the screen.
|
||||
The rogue screen is intended to replace the \f3You can see ...\f1 descriptions
|
||||
of standard fantasy games. Here is a sample of what a rogue screen might
|
||||
look like:
|
||||
.SP
|
||||
.DS
|
||||
\f9
|
||||
---------------------
|
||||
|...................+###########+
|
||||
|...@...........[...|
|
||||
|........H..........|
|
||||
|...................|
|
||||
--------+------------
|
||||
####
|
||||
+
|
||||
|
||||
Level: 1 Gold: 0 Hp:12(12) Ac: 6 Exp:1/0 Vol:36%
|
||||
Str:16(16) Exp:12(12) Dex:11(11) Wis:14(14) Con:18(18) Carry:50/170
|
||||
\f1
|
||||
.DE
|
||||
.H 1 "THE BOTTOM LINES"
|
||||
At the bottom line of the screen is a few pieces of cryptic information,
|
||||
describing your current status. Here is an explanation of what these
|
||||
things mean:
|
||||
.SP
|
||||
.H 2 "LEVEL"
|
||||
.SP
|
||||
This number indicates how deep you have gone in the dungeon. It starts
|
||||
at one and goes up forever.\*F
|
||||
.FS
|
||||
Or until you get killed or decide to quit. Level 500 is really the
|
||||
maximum, but almost impossible.
|
||||
.FE
|
||||
.SP
|
||||
.H 2 "GOLD"
|
||||
.SP
|
||||
The number of gold pieces you have managed to attain.
|
||||
.SP
|
||||
.H 2 "HP"
|
||||
.SP
|
||||
Your current and maximum hit points. Hit points indicate how much
|
||||
damage you can take before you die. The more you get hit in a
|
||||
fight, the lower they
|
||||
get. You can regain hit points by moving around. The number in
|
||||
parentheses is the maximum number of hit points you can regain.
|
||||
.SP
|
||||
.H 2 "AC"
|
||||
.SP
|
||||
Your current armor class. This number indicates how effective
|
||||
your armor is in stopping blows from unfriendly creatures. The lower
|
||||
this number is, the more effective the armor. Armor class can get
|
||||
lower than zero.
|
||||
.SP
|
||||
.H 2 "EXP"
|
||||
.SP
|
||||
These two numbers give your current experience level and experience points.
|
||||
As you kill monsters, you gain experience points. At certain experience
|
||||
point totals, you gain an experience level. The more experienced you are,
|
||||
the better you are able to fight and to withstand magical attacks. You
|
||||
must gain 10 experience points to advance to the 2nd experience level.
|
||||
Now you must double the previous experience point total to advance
|
||||
to the next experience level. (i.e. 20 to get to level 3, 40 to 4...)
|
||||
Every time you advance to a new experience level, your hit points
|
||||
will increase. This is random, so don't expect a lot every time.
|
||||
.SP
|
||||
.H 2 "VOL"
|
||||
.SP
|
||||
This is the percentage of what your pack contains. \f3100%\f1
|
||||
means that your pack is full.
|
||||
.SP
|
||||
.H 2 "STR"
|
||||
.SP
|
||||
Your current strength. This can be any integer from 0 to 24.
|
||||
The larger the number, the stronger you are.
|
||||
.SP
|
||||
.H 2 "DEX"
|
||||
.SP
|
||||
This is your dexterity. Dexterity gives you the ability to dodge arrow
|
||||
and dart traps more effectively. It also gives you the ability to dodge
|
||||
attacks from monters (maximum of 18).
|
||||
.SP
|
||||
.H 2 "WIS"
|
||||
.SP
|
||||
This is your wisdom. If you are smarter than the monsters,
|
||||
then you have a better chance of defeating them (maximum of 18).
|
||||
.SP
|
||||
.H 2 "CON"
|
||||
.SP
|
||||
This is your constitution. Constitution makes up your ability to
|
||||
regain your hit points, once you have been battered. The higher
|
||||
your constitution (maximum of 18), the faster you will gain back
|
||||
the hit points you have lost.
|
||||
.SP
|
||||
.H 2 "CARRY"
|
||||
.SP
|
||||
This is similar to your volume, but tells you the maximum of what
|
||||
you can carry and what you are currently carrying in weight.
|
||||
.H 1 "THE TOP LINE"
|
||||
.P
|
||||
The top line of the screen is reserved for printing messages that describe
|
||||
things that are impossible to represent visually. If you see a
|
||||
\f3-- More --\f1 on the top line, this means that rogue wants to print another
|
||||
message on the screen, but it wants to make certain that you have read
|
||||
the one that is there first. To read the next message, just press a
|
||||
space.
|
||||
.H 1 "THE REST OF THE SCREEN"
|
||||
.P
|
||||
The rest of the screen is the map of the level
|
||||
as you have explored it so far.
|
||||
Each symbol on the screen represents something. Here is a list of what
|
||||
the various symbols mean:
|
||||
.bp
|
||||
.DS
|
||||
.B "@ " "This symbol represents you, the adventurer."
|
||||
|
||||
.B "| " "A wall running north/south."
|
||||
|
||||
.B "- " "A wall running east/west."
|
||||
|
||||
.B "+ " "A door to/from a room."
|
||||
|
||||
.B "\. " "The floor of a room."
|
||||
|
||||
.B "# " "The floor of a passage between rooms."
|
||||
|
||||
.B "* " "A pile or pot of gold."
|
||||
|
||||
.B ") " "A weapon of some sort."
|
||||
|
||||
.B "] " "A suit of armor."
|
||||
|
||||
.B "! " "A flask containing a magic potion."
|
||||
|
||||
.B "? " "A piece of paper, usually a magic scroll."
|
||||
|
||||
.B "/ " "A wand or staff of magic."
|
||||
|
||||
.B "= " "A magical ring. Can be good or bad."
|
||||
|
||||
.B "{ " "An arrow trap. Loss of hit points."
|
||||
|
||||
.B "} " "A bear trap. Holds you for awhile."
|
||||
|
||||
.B "~ " "A teleportation trap. Teleports you to a random room."
|
||||
|
||||
.B "` " "A dart trap. Loss of strength."
|
||||
|
||||
.B "$ " "A sleeping gas trap, watch out for these."
|
||||
|
||||
.B "> " "A trap door leading down to the next level."
|
||||
|
||||
.B "^ " "A flee market to exchange gold for objects, or vice-versa."
|
||||
|
||||
.B "\e " "A trap door that leads down to an invisible maze."
|
||||
|
||||
\f3"\f1 A magical pool that does strange things to wielded objects.
|
||||
|
||||
.B "% " "The staircase leading down to the next level."
|
||||
|
||||
.B ": " "A piece of food or zany fruit."
|
||||
|
||||
.B ", AMULET OF YENDOR."
|
||||
|
||||
.B "a-Z " "There are 52 inhabitants of the Dungeons of Doom."
|
||||
.DE
|
||||
.bp
|
||||
.H 1 COMMANDS
|
||||
.P
|
||||
Commands are given to rogue by pressing single letters. Some commands can
|
||||
be preceded by a count to repeat them
|
||||
(i.e. typing \f310s\f1 will do ten searches)
|
||||
The list of commands is rather long, but it can be read at any time during
|
||||
the game with the \f3?\f1 command. Here it is for reference, with a short
|
||||
explanation of each command:
|
||||
.SP
|
||||
.DS
|
||||
\f3?\f1 The help command. Asks for a character to give help on.
|
||||
If you type a \f3*\f1, it will list all the commands, otherwise
|
||||
it will explain what the character you type does.
|
||||
|
||||
\f3/\f1 This is the \f3What is that on the screen\f1? command.
|
||||
A \f3/\f1 followed by any character that you see on the level,
|
||||
will tell you what that character is. For instance, typing
|
||||
\f3/@\f1 will tell you that the \f3@\f1 symbol represents you,
|
||||
the player.
|
||||
|
||||
\f3h, H\f1 Move left. You move one space to the left. If you use
|
||||
upper case, \f3H,\f1 you will continue to move left until you
|
||||
run into something. This works for all movement commands.
|
||||
(i.e. \f3L\f1 means run in direction \f3l\f1)
|
||||
|
||||
.B "j, J " "Move down."
|
||||
|
||||
.B "k, K " "Move up."
|
||||
|
||||
.B "l, L " "Move right."
|
||||
|
||||
.B "y, Y " "Move diagonally up and left."
|
||||
|
||||
.B "u, U " "Move diagonally up and right."
|
||||
|
||||
.B "b, B " "Move diagonally down and left."
|
||||
|
||||
.B "n, N " "Move diagonally down and right."
|
||||
|
||||
\f3f\f1 Find prefix. When followed by a direction it means to
|
||||
continue moving in the specified direction until you pass
|
||||
something interesting or run into a wall.
|
||||
|
||||
\f3t\f1 Throw an object. This is a prefix command. Follow it
|
||||
with a direction and you throw an object in the specified
|
||||
direction. (i.e. type \f3th\f1 to throw something left.)
|
||||
|
||||
\f3p\f1 Zap an object with a staff or wand. This is a prefix
|
||||
command. Follow it with a direction and you will zap in the
|
||||
specified direction. (i.e. type \f3ph\f1 to zap something left.)
|
||||
.DE
|
||||
.bp
|
||||
.DS
|
||||
\f3z\f1 Zap an object with no direction. This means that you
|
||||
could be zapped with it as well.
|
||||
|
||||
.B "D " "Dip an object in the magic pool."
|
||||
|
||||
\f3>\f1 If you are standing over the passage down to the next
|
||||
level, this command means to climb down.
|
||||
|
||||
\f3<\f1 If you have found the \f3Amulet of Yendor\f1, then
|
||||
you have the ability to climb back up a level, hopefully on
|
||||
your way out.
|
||||
|
||||
\f3s\f1 Search for traps and secret doors. Examine each space
|
||||
immediately adjacent to you for the existence of a trap or
|
||||
secret door. There is a large chance that even if there is
|
||||
something there, you won't find it so you might have to
|
||||
search a while before you find something.
|
||||
|
||||
.B "\. " "Rest. This is the \f3do nothing\f1 command. This is
|
||||
good for waiting and healing."
|
||||
|
||||
.B "i " "Inventory. List what you are carrying in your pack."
|
||||
|
||||
\f3I\f1 Selective inventory. Tells you what a single item in
|
||||
your pack is.
|
||||
|
||||
.B "q " "Quaff. Drink one of the potions you are carrying."
|
||||
|
||||
.B "r " "Read. Read one of the scrolls in your pack."
|
||||
|
||||
.B "e " "Eat food. Take some food out of your pack and eat it."
|
||||
|
||||
\f3w\f1 Wield a weapon. Take a weapon out of your pack and carry
|
||||
it. You must be wielding a weapon to use it (except to
|
||||
throw things). To fire an arrow, you must wield the bow.
|
||||
You can only wield one weapon at a time.
|
||||
|
||||
\f3W\f1 Wear armor. Take a piece of armor out of your pack and
|
||||
put it on. You can only wear one suit of armor at a time.
|
||||
|
||||
.B "T " "Take armor off. You can't remove armor that is cursed."
|
||||
|
||||
\f3P\f1 Put a ring on your finger. You can only wear two rings
|
||||
at a time.
|
||||
|
||||
\f3R\f1 Remove a ring from your finger. Cursed rings are hard
|
||||
to remove.
|
||||
|
||||
\f3d\f1 Drop an object. Take something out of your pack and
|
||||
leave it lying on the floor. Only one object can occupy
|
||||
each space.
|
||||
.DE
|
||||
.bp
|
||||
.DS
|
||||
\f3O\f1 Examine and set options. This command is further
|
||||
explained in the section on options.
|
||||
|
||||
\f3^l\f1 Redraws the screen. Useful if spurious messages or
|
||||
transmission errors have messed up the display.
|
||||
|
||||
\f3^r\f1 Repeat last message. Useful when a message disappears
|
||||
before you can read it.
|
||||
|
||||
.B "^[ " "This is the escape key. This will cancel the last command."
|
||||
|
||||
\f3a\f1 Reports your encumbrance. This is the weight factor of
|
||||
your pack. The heavier your pack is weighted down with
|
||||
objects, the less effective you are in an attack and the
|
||||
more food you'll eat.
|
||||
|
||||
.B "c " "Call an object. You can call an object anything you like."
|
||||
|
||||
.B "v " "Prints the program version number."
|
||||
|
||||
.B "Q " "Quit. Leave the game. This is the chicken-way out."
|
||||
|
||||
\f3!\f1 This is the shell escape key. Use this to get back to
|
||||
shell level. To get back to the game, just hit \f3^d\f1.
|
||||
|
||||
\f3S\f1 Save the current game in a file. Rogue won't let
|
||||
you start up a copy of a saved game, and it removes the
|
||||
save file as soon as you start up a restored game. This
|
||||
is to prevent people from saving a game just before a
|
||||
dangerous position and then restarting it, if they die.
|
||||
Sorry no linking, copying, moving, or anything.
|
||||
.DE
|
||||
.bp
|
||||
.H 1 "DEALING WITH OBJECTS"
|
||||
.P
|
||||
When you find something in the dungeon, it is common to want to pick the
|
||||
object up. This is accomplished in rogue by walking over the object.
|
||||
If you are carrying too many things, you won't be able to pick the
|
||||
object up. Otherwise, the object will be added to your pack and you
|
||||
will be notified of what you just picked up.
|
||||
.P
|
||||
Many of the commands that operate on objects must prompt you to find
|
||||
out which object you want to use.
|
||||
If you change your mind and don't want to
|
||||
do that command after all, just press an \f3escape\f1 key and the command
|
||||
will be aborted.
|
||||
.H 1 ROOMS
|
||||
.P
|
||||
Rooms in the dungeons are either lit or dark.
|
||||
If you walk into a lit room,
|
||||
the entire room will be drawn on the screen as soon as you enter. If you
|
||||
walk into a dark room, you will only be able to see the spaces immediately
|
||||
next to you.
|
||||
Upon leaving a dark room, all objects inside the room are
|
||||
removed from the screen.
|
||||
.H 1 FIGHTING
|
||||
.P
|
||||
If you see a monster and you wish to fight it, just attempt to run into it.
|
||||
You also may throw things at it or zap it with a wand or staff.
|
||||
Many times a monster you find will mind its own business unless you attack
|
||||
it. It is often the case that discretion is the better part of valor.
|
||||
.P
|
||||
Smart monsters have the ability to run when they realize that their
|
||||
lives are endangered. This will be denoted that you have wounded
|
||||
the monster.
|
||||
.P
|
||||
Monsters will avoid lit traps. You can use this to your
|
||||
advantage, if you figure out how. If the traps are not lit, they can
|
||||
fall through them as you would. The hard part is trying to get them to
|
||||
fall through a trap that you don't know is there.
|
||||
.bp
|
||||
.H 1 ARMOR
|
||||
.P
|
||||
There are various sorts of armor lying around in the dungeon. Some of it
|
||||
is enchanted, some is cursed and some is just normal. Different armor
|
||||
types have different armor classes. The lower the armor class, the
|
||||
more protection the armor affords against the blows of monsters.
|
||||
If a piece of armor is enchanted or
|
||||
cursed, its armor class will be higher or lower than normal. Here is
|
||||
a list of the various armor types and their normal armor class:
|
||||
.DS 3
|
||||
.TS
|
||||
box;
|
||||
c|c
|
||||
l|l.
|
||||
TYPE CLASS
|
||||
=
|
||||
LEATHER ARMOR 8
|
||||
RING MAIL 7
|
||||
STUDDED LEATHER ARMOR 7
|
||||
SCALE MAIL 6
|
||||
PADDED ARMOR 6
|
||||
CHAIN MAIL 5
|
||||
SPLINT MAIL 4
|
||||
BANDED MAIL 4
|
||||
PLATE MAIL 3
|
||||
PLATE ARMOR 2
|
||||
.TE
|
||||
.DE
|
||||
.H 1 WEAPONS
|
||||
.P
|
||||
There may be many different types of weapons lying around in the dungeon,
|
||||
probably left there when their previous owners ran into a monster they
|
||||
couldn't handle. In order to fire arrows and crossbow bolts you must be
|
||||
wielding the bow or the crossbow. Rocks are effective when thrown but
|
||||
can be even more dangerous when hurled with a sling. Daggers can be used
|
||||
as stabbing weapons or they can be thrown. Beware of cursed weapons,
|
||||
they will not work as well as normal or enchanted weapons and once you
|
||||
wield them, you will be stuck with them until you can get the curse
|
||||
removed. Staffs and wands are special weapons. They need not be
|
||||
wielded for you to use them.
|
||||
.bp
|
||||
.H 1 "POTIONS AND SCROLLS"
|
||||
.P
|
||||
Left by the wizard Yendor, the potions and scrolls found in the dungeon
|
||||
constitute a mixed blessing. By drinking or reading these magical items,
|
||||
the intelligent adventurer can greatly increase his chances of survival.
|
||||
A few of them can backfire on the unwary rogue, causing everything from
|
||||
a weakening sickness to the creation of an angry monster.
|
||||
.H 1 OPTIONS
|
||||
.P
|
||||
Due to variations in personal tastes and conceptions of the way rogue
|
||||
should do things, there are a set of options you can set that cause
|
||||
rogue to behave in various different ways.
|
||||
.H 2 "SETTING THE OPTIONS"
|
||||
.P
|
||||
There are basically two ways to set the options. The first is with the
|
||||
\f3O\f1 command of rogue, the second is with the \f3ROGUEOPTS\f1 environment
|
||||
variable.
|
||||
.H 2 "USING THE O COMMAND"
|
||||
.P
|
||||
When you press \f3O\f1 in rogue, it clears the screen and displays the
|
||||
current settings for all the options.
|
||||
It then places the cursor by the value of the
|
||||
first option and waits for you to type.
|
||||
You can type a \f3RETURN\f1 which means to
|
||||
go to the next option, a \f3-\f1 which means to go to the previous option,
|
||||
an escape which means to return to the game, or you can give the option a
|
||||
value. For string options, type the new value followed by a return.
|
||||
.H 2 "USING THE ROGUEOPTS VARIABLE"
|
||||
.P
|
||||
The \f3ROGUEOPTS\f1 variable is a string containing a comma
|
||||
separated list of initial values for the various options.
|
||||
Thus to set up an environment variable so that the name is
|
||||
set to \f3Rapid Robert\f1, the fruit is \f3cherry\f1,
|
||||
and your save file is \f3fun\f1, use the command:
|
||||
.SP 2
|
||||
.DS
|
||||
ROGUEOPTS="name=Rapid Robert,fruit=cherry,file=fun"
|
||||
export ROGUEOPTS
|
||||
.DE
|
||||
.bp
|
||||
.H 2 "OPTION LIST"
|
||||
.P
|
||||
Here is a list of the options and an explanation for each one.
|
||||
The default value for each is enclosed in square brackets:
|
||||
.BL
|
||||
.LI
|
||||
.B "NAME [LOGIN NAME]"
|
||||
This is the name of your character. It is used if you get on the top ten
|
||||
scorer's list. It should be less than eighty characters long.
|
||||
.LI
|
||||
.B "FRUIT [JUICY-FRUIT]"
|
||||
This should hold the name of a
|
||||
fruit that you enjoy eating. It is basically
|
||||
a whimsy that the program uses in a couple of places.
|
||||
.LI
|
||||
.B "FILE [.ROGUE.SAVE]"
|
||||
The default file name for saving the game. If your phone is hung up by
|
||||
accident, rogue will automatically save the game in this file. The
|
||||
file name may contain the special character \f3~\f1 which expands to be
|
||||
your home directory.
|
||||
.LE
|
||||
.H 1 "SAVED GAMES"
|
||||
.P
|
||||
This is how one would restore a saved game:
|
||||
.SP
|
||||
.DS 1
|
||||
.B "rogue .rogue.save"
|
||||
.DE
|
||||
.SP
|
||||
This is how one would read the top ten score list of rogue:
|
||||
.SP
|
||||
.DS 1
|
||||
.B "rogue -s"
|
||||
.DE
|
||||
.SP
|
||||
.bp
|
||||
.H 1 SYNOPSIS
|
||||
.B Rogue
|
||||
is a video oriented game with the object being to survive the attacks
|
||||
of various monsters and gather a lot of gold.
|
||||
To get started, you really only need to know two commands. The command
|
||||
.B ?
|
||||
will give you a list of the available commands and the command
|
||||
.B /
|
||||
will identify the things you see on the screen.
|
||||
.P
|
||||
To win the game (as opposed to merely playing to beat other people high
|
||||
scores) you must locate the
|
||||
.B "Amulet of Yendor"
|
||||
which is somewhere below
|
||||
the \f335th\f1 level of the dungeon and get it out.
|
||||
.P
|
||||
When the game ends, either by your death, when you chicken-out by
|
||||
quitting, or if you (by some miracle) manage to win,
|
||||
.B rogue
|
||||
will give you a list of what was in your pack and
|
||||
will give you a list of the top ten scorers. The scoring is based
|
||||
upon how much gold you get.
|
||||
If for some reason you manage to win, then the stuff in your
|
||||
pack is also worth points. The better the stuff, the more points you'll
|
||||
get. There is a \f310%\f1 penalty for getting yourself killed.
|
||||
.H 1 ACKNOWLEDGEMENTS
|
||||
Rogue was originally conceived of by Glenn Wichman and Michael Toy. The
|
||||
version of Super-Rogue 9.0 has been established
|
||||
through the persistence of a co-worker, who would like to remain nameless.
|
||||
He conceived the idea of 52 monsters, magic pools, the Flea Market,
|
||||
and mazes. Many bug fixes and joys of Super-Rogue 9.0 wouldn't
|
||||
be here without the savage attack that he has put on this game.
|
||||
.H 1 FILES
|
||||
.BL
|
||||
.LI
|
||||
\f3srogue:\f1 Rogue game (object)
|
||||
.LI
|
||||
\f3Rogue score file search for as follows:\f1
|
||||
\f3$ROGUEHOME/srogue.scr \f1
|
||||
.br
|
||||
\f3/var/games/roguelike/srogue.scr \f1
|
||||
.br
|
||||
\f3/var/lib/roguelike/srogue.scr \f1
|
||||
.br
|
||||
\f3/var/roguelike/srogue.scr \f1
|
||||
.br .br
|
||||
\f3/usr/games/lib/srogue.scr \f1
|
||||
.br
|
||||
\f3/games/roguelik/srogue.scr \f1
|
||||
.br
|
||||
\f3srogue.scr:\f1
|
||||
.LI
|
||||
\f3srogue.sav (user defineable):\f1 Rogue save file
|
||||
.LE
|
||||
.H 1 BUGS
|
||||
As of the release of this memo, there are no known bugs.
|
||||
Going past level 500 would be suicidal.
|
||||
.bp
|
||||
.H 1 "SHORT REFERENCE OF COMMANDS"
|
||||
.DS
|
||||
\f9
|
||||
? prints help / identify object
|
||||
h left H run left
|
||||
j down J run down
|
||||
k up K run up
|
||||
l right L run right
|
||||
y up & left Y run up & left
|
||||
u up & right U run up & right
|
||||
b down & left B run down & left
|
||||
n down & right N run down & right
|
||||
i inventory pack I one item inventory
|
||||
w wield a weapon W wear armor
|
||||
a encumbrance O examine/set options
|
||||
c call object R remove ring
|
||||
d drop object P put on ring
|
||||
e eat food T take armor off
|
||||
q quaff potion Q quit game
|
||||
r read a scroll S save game
|
||||
v program version number D dip object in magic pool
|
||||
z zap a wand or staff s search for traps
|
||||
t <dir> throw something f <dir> forward until find
|
||||
p <dir> directional zap \. rest for a while
|
||||
> go down a staircase < go up a staircase
|
||||
^r repeat last message ^l redraw screen
|
||||
^[ cancel last command ^d return from shell
|
||||
! escape to shell
|
||||
\f1
|
||||
.DE
|
||||
|
||||
257
srogue/rooms.c
Normal file
257
srogue/rooms.c
Normal file
|
|
@ -0,0 +1,257 @@
|
|||
/*
|
||||
* Draw the nine rooms on the screen
|
||||
*
|
||||
* @(#)rooms.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include "rogue.h"
|
||||
#include "rogue.ext"
|
||||
|
||||
/*
|
||||
* do_rooms:
|
||||
* Place the rooms in the dungeon
|
||||
*/
|
||||
do_rooms()
|
||||
{
|
||||
int mloops, mchance, nummons, left_out, roomtries;
|
||||
bool treas = FALSE;
|
||||
reg int i;
|
||||
reg struct room *rp;
|
||||
reg struct linked_list *item;
|
||||
reg struct thing *tp;
|
||||
struct coord top, bsze, mp;
|
||||
|
||||
/*
|
||||
* bsze is the maximum room size
|
||||
*/
|
||||
bsze.x = COLS / 3;
|
||||
bsze.y = (LINES - 1) / 3;
|
||||
/*
|
||||
* Clear things for a new level
|
||||
*/
|
||||
for (rp = rooms; rp < &rooms[MAXROOMS]; rp++)
|
||||
rp->r_goldval = rp->r_nexits = rp->r_flags = 0;
|
||||
/*
|
||||
* Put the gone rooms, if any, on the level
|
||||
*/
|
||||
left_out = rnd(4);
|
||||
for (i = 0; i < left_out; i++)
|
||||
rooms[rnd_room()].r_flags |= ISGONE;
|
||||
/*
|
||||
* dig and populate all the rooms on the level
|
||||
*/
|
||||
for (i = 0, rp = rooms; i < MAXROOMS; rp++, i++) {
|
||||
/*
|
||||
* Find upper left corner of box that this room goes in
|
||||
*/
|
||||
top.x = (i%3) * bsze.x + 1;
|
||||
top.y = i/3 * bsze.y;
|
||||
if (rf_on(rp,ISGONE)) {
|
||||
/*
|
||||
* Place a gone room. Make certain that there is a
|
||||
* blank line for passage drawing.
|
||||
*/
|
||||
roomtries = 0;
|
||||
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;
|
||||
if (++roomtries > 250)
|
||||
fatal("failed to place a gone room");
|
||||
} 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
|
||||
*/
|
||||
roomtries = 0;
|
||||
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);
|
||||
if (++roomtries > 250) {
|
||||
fatal("failed to place a good room");
|
||||
}
|
||||
} until (rp->r_pos.y != 0);
|
||||
if (level < max_level)
|
||||
mchance = 30; /* 30% when going up (all monsters) */
|
||||
else
|
||||
mchance = 3; /* 3% when going down */
|
||||
treas = FALSE;
|
||||
if (rnd(100) < mchance && (rp->r_max.x * rp->r_max.y) >
|
||||
((bsze.x * bsze.y * 55) / 100)) {
|
||||
treas = TRUE;
|
||||
rp->r_flags |= ISTREAS;
|
||||
rp->r_flags |= ISDARK;
|
||||
}
|
||||
/*
|
||||
* Put the gold in
|
||||
*/
|
||||
if ((rnd(100) < 50 || treas) && (!amulet || level >= max_level)) {
|
||||
rp->r_goldval = GOLDCALC;
|
||||
if (treas)
|
||||
rp->r_goldval += 200 + (15 * (rnd(level) + 2));
|
||||
rp->r_gold.y = rp->r_pos.y + rnd(rp->r_max.y - 2) + 1;
|
||||
rp->r_gold.x = rp->r_pos.x + rnd(rp->r_max.x - 2) + 1;
|
||||
}
|
||||
draw_room(rp);
|
||||
/*
|
||||
* Put the monster in
|
||||
*/
|
||||
if (treas) {
|
||||
mloops = rnd(level / 3) + 6;
|
||||
mchance = 1;
|
||||
}
|
||||
else {
|
||||
mloops = 1;
|
||||
mchance = 100;
|
||||
}
|
||||
for (nummons = 0; nummons < mloops; nummons++) {
|
||||
if (rnd(mchance) < (rp->r_goldval > 0 ? 80 : 25))
|
||||
add_mon(rp, treas);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* add_mon:
|
||||
* Add a monster to a room
|
||||
*/
|
||||
add_mon(rm, treas)
|
||||
struct room *rm;
|
||||
bool treas;
|
||||
{
|
||||
reg struct thing *tp;
|
||||
reg struct linked_list *item;
|
||||
struct coord mp;
|
||||
int chance;
|
||||
|
||||
mp = *rnd_pos(rm);
|
||||
item = new_monster(rnd_mon(FALSE,FALSE), &mp, treas);
|
||||
tp = THINGPTR(item);
|
||||
chance = rnd(100);
|
||||
if (levtype == MAZELEV)
|
||||
chance = rnd(50);
|
||||
/*
|
||||
* See if monster has a treasure
|
||||
*/
|
||||
if (levtype == MAZELEV && rnd(100) < 20) {
|
||||
reg struct linked_list *fd;
|
||||
|
||||
fd = new_thing(FALSE, FOOD, 0);
|
||||
attach(tp->t_pack, fd);
|
||||
}
|
||||
else {
|
||||
if (chance < monsters[tp->t_indx].m_carry)
|
||||
attach(tp->t_pack, new_thing(FALSE, ANYTHING));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* draw_room:
|
||||
* Draw a box around a room
|
||||
*/
|
||||
draw_room(rp)
|
||||
struct room *rp;
|
||||
{
|
||||
reg 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);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Put the gold there
|
||||
*/
|
||||
if (rp->r_goldval > 0)
|
||||
mvaddch(rp->r_gold.y, rp->r_gold.x, GOLD);
|
||||
}
|
||||
|
||||
/*
|
||||
* horiz:
|
||||
* draw a horizontal line
|
||||
*/
|
||||
horiz(cnt)
|
||||
int cnt;
|
||||
{
|
||||
while (cnt-- > 0)
|
||||
addch('-');
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* vert:
|
||||
* draw a vertical line
|
||||
*/
|
||||
vert(cnt)
|
||||
int cnt;
|
||||
{
|
||||
reg int x, y;
|
||||
|
||||
getyx(stdscr, y, x);
|
||||
x--;
|
||||
while (cnt-- > 0) {
|
||||
move(++y, x);
|
||||
addch('|');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* rnd_pos:
|
||||
* pick a random spot in a room
|
||||
*/
|
||||
struct coord *
|
||||
rnd_pos(rp)
|
||||
struct room *rp;
|
||||
{
|
||||
reg int y, x, i;
|
||||
static struct coord spot;
|
||||
|
||||
i = 0;
|
||||
do {
|
||||
x = rp->r_pos.x + rnd(rp->r_max.x - 2) + 1;
|
||||
y = rp->r_pos.y + rnd(rp->r_max.y - 2) + 1;
|
||||
i += 1;
|
||||
} while(winat(y, x) != FLOOR && i < 1000);
|
||||
spot.x = x;
|
||||
spot.y = y;
|
||||
return &spot;
|
||||
}
|
||||
|
||||
/*
|
||||
* rf_on:
|
||||
* Returns TRUE if flag is set for room stuff
|
||||
*/
|
||||
rf_on(rm, bit)
|
||||
struct room *rm;
|
||||
long bit;
|
||||
{
|
||||
return (rm->r_flags & bit);
|
||||
}
|
||||
339
srogue/save.c
Normal file
339
srogue/save.c
Normal file
|
|
@ -0,0 +1,339 @@
|
|||
/*
|
||||
* save and restore routines
|
||||
*
|
||||
* @(#)save.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include "rogue.h"
|
||||
#include "rogue.ext"
|
||||
|
||||
#ifdef BSD
|
||||
#define srand48(seed) srandom(seed)
|
||||
#endif
|
||||
|
||||
EXTCHAR version[];
|
||||
EXTCHAR *ctime();
|
||||
|
||||
typedef struct stat STAT;
|
||||
STAT sbuf;
|
||||
|
||||
/*
|
||||
* ignore:
|
||||
* Ignore ALL signals possible
|
||||
*/
|
||||
ignore()
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NSIG; i++)
|
||||
signal(i, SIG_IGN);
|
||||
}
|
||||
|
||||
/*
|
||||
* save_game:
|
||||
* Save the current game
|
||||
*/
|
||||
save_game()
|
||||
{
|
||||
reg FILE *savef;
|
||||
reg int c;
|
||||
char buf[LINLEN];
|
||||
|
||||
mpos = 0;
|
||||
if (file_name[0] != '\0') {
|
||||
msg("Save file (%s)? ", file_name);
|
||||
do {
|
||||
c = wgetch(cw);
|
||||
if(c == ESCAPE) {
|
||||
msg("");
|
||||
return FALSE;
|
||||
}
|
||||
} while (c != 'n' && c != 'y');
|
||||
mpos = 0;
|
||||
if (c == 'y')
|
||||
goto gotfile;
|
||||
}
|
||||
msg("File name: ");
|
||||
mpos = 0;
|
||||
buf[0] = '\0';
|
||||
if (get_str(buf, cw) == QUIT) {
|
||||
msg("");
|
||||
return FALSE;
|
||||
}
|
||||
msg("");
|
||||
strcpy(file_name, buf);
|
||||
gotfile:
|
||||
c = dosave(); /* try to save this game */
|
||||
if (c == FALSE)
|
||||
msg("Could not save game to file %s", file_name);
|
||||
return c;
|
||||
}
|
||||
|
||||
/*
|
||||
* auto_save:
|
||||
* Automatically save a game
|
||||
*/
|
||||
void
|
||||
auto_save(int a)
|
||||
{
|
||||
dosave(); /* save this game */
|
||||
byebye(1); /* so long for now */
|
||||
}
|
||||
|
||||
/*
|
||||
* game_err:
|
||||
* When an error occurs. Set error flag and save game.
|
||||
*/
|
||||
void
|
||||
game_err(int a)
|
||||
{
|
||||
int ok;
|
||||
|
||||
ok = dosave(); /* try to save this game */
|
||||
clear();
|
||||
refresh();
|
||||
endwin();
|
||||
|
||||
printf("\nInternal error !!!\n\nYour game was ");
|
||||
if (ok)
|
||||
printf("saved.");
|
||||
else
|
||||
printf("NOT saveable.");
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef SIGIOT
|
||||
signal(SIGIOT, SIG_DFL); /* allow core dump signal */
|
||||
#endif
|
||||
|
||||
abort(); /* cause core dump */
|
||||
byebye(3);
|
||||
}
|
||||
|
||||
/*
|
||||
* dosave:
|
||||
* Set UID back to user and save the game
|
||||
*/
|
||||
dosave()
|
||||
{
|
||||
FILE *savef;
|
||||
|
||||
ignore();
|
||||
setuid(playuid);
|
||||
setgid(playgid);
|
||||
umask(022);
|
||||
|
||||
if (file_name[0] != '\0') {
|
||||
if ((savef = fopen(file_name,"w")) != NULL)
|
||||
{
|
||||
save_file(savef);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* save_file:
|
||||
* Do the actual save of this game to a file
|
||||
*/
|
||||
save_file(savef)
|
||||
FILE *savef;
|
||||
{
|
||||
reg int fnum;
|
||||
int slines = LINES;
|
||||
int scols = COLS;
|
||||
|
||||
#ifdef __DJGPP__ /* st_ino w/ DJGPP under WinXP broken */
|
||||
_djstat_flags |= _STAT_INODE; /* so turn off computing it for now */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* force allocation of the buffer now so that inodes, etc
|
||||
* can be checked when restoring saved games.
|
||||
*/
|
||||
fnum = fileno(savef);
|
||||
fstat(fnum, &sbuf);
|
||||
write(fnum, "RDK", 4);
|
||||
lseek(fnum, 0L, 0);
|
||||
encwrite(version,strlen(version)+1,savef);
|
||||
encwrite(&sbuf.st_ino,sizeof(sbuf.st_ino),savef);
|
||||
encwrite(&sbuf.st_dev,sizeof(sbuf.st_dev),savef);
|
||||
encwrite(&sbuf.st_ctime,sizeof(sbuf.st_ctime),savef);
|
||||
encwrite(&sbuf.st_mtime,sizeof(sbuf.st_mtime),savef);
|
||||
encwrite(&slines,sizeof(slines),savef);
|
||||
encwrite(&scols,sizeof(scols),savef);
|
||||
msg("");
|
||||
rs_save_file(savef);
|
||||
close(fnum);
|
||||
signal(SIGINT, byebye);
|
||||
signal(SIGQUIT, byebye);
|
||||
wclear(cw);
|
||||
draw(cw);
|
||||
}
|
||||
|
||||
/*
|
||||
* restore:
|
||||
* Restore a saved game from a file
|
||||
*/
|
||||
restore(file, envp)
|
||||
char *file, **envp;
|
||||
{
|
||||
register inf, pid;
|
||||
int ret_status;
|
||||
#ifndef _AIX
|
||||
extern char **environ;
|
||||
#endif
|
||||
#ifdef __DJGPP__ /* st_ino w/ DJGPP under WinXP broken */
|
||||
_djstat_flags |= _STAT_INODE; /* so turn off computing it for now */
|
||||
#endif
|
||||
char buf[LINLEN];
|
||||
STAT sbuf2;
|
||||
int slines, scols;
|
||||
|
||||
if ((inf = open(file, O_RDONLY)) < 0) {
|
||||
printf("Cannot read save game %s\n",file);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
encread(buf, strlen(version) + 1, inf);
|
||||
|
||||
if (strcmp(buf, version) != 0) {
|
||||
printf("Sorry, saved game version is out of date.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fstat(inf, &sbuf2);
|
||||
|
||||
encread(&sbuf.st_ino,sizeof(sbuf.st_ino), inf);
|
||||
encread(&sbuf.st_dev,sizeof(sbuf.st_dev), inf);
|
||||
encread(&sbuf.st_ctime,sizeof(sbuf.st_ctime), inf);
|
||||
encread(&sbuf.st_mtime,sizeof(sbuf.st_mtime), inf);
|
||||
encread(&slines,sizeof(slines),inf);
|
||||
encread(&scols,sizeof(scols),inf);
|
||||
|
||||
/*
|
||||
* we do not close the file so that we will have a hold of the
|
||||
* inode for as long as possible
|
||||
*/
|
||||
|
||||
if (!wizard)
|
||||
{
|
||||
if(sbuf2.st_ino!=sbuf.st_ino || sbuf2.st_dev!=sbuf.st_dev) {
|
||||
printf("Sorry, saved game is not in the same file.\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __INTERIX
|
||||
setenv("TERM","interix");
|
||||
#endif
|
||||
|
||||
initscr();
|
||||
|
||||
if (slines > LINES)
|
||||
{
|
||||
endwin();
|
||||
printf("Sorry, original game was played on a screen with %d lines.\n",slines);
|
||||
printf("Current screen only has %d lines. Unable to restore game\n",LINES);
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
if (scols > COLS)
|
||||
{
|
||||
endwin();
|
||||
printf("Sorry, original game was played on a screen with %d columns.\n", scols);
|
||||
printf("Current screen only has %d columns. Unable to restore game\n",COLS);
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
cw = newwin(LINES, COLS, 0, 0);
|
||||
mw = newwin(LINES, COLS, 0, 0);
|
||||
hw = newwin(LINES, COLS, 0, 0);
|
||||
|
||||
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("Cannot restore from a linked file\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (rs_restore_file(inf) == FALSE)
|
||||
{
|
||||
endwin();
|
||||
printf("Cannot restore file\n");
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
#if defined(__CYGWIN__) || defined(__DJGPP__)
|
||||
close(inf);
|
||||
#endif
|
||||
if (!wizard)
|
||||
{
|
||||
#ifndef __DJGPP__
|
||||
endwin();
|
||||
while((pid = fork()) < 0)
|
||||
sleep(1);
|
||||
|
||||
/* set id to unlink file */
|
||||
if(pid == 0)
|
||||
{
|
||||
setuid(playuid);
|
||||
setgid(playgid);
|
||||
unlink(file);
|
||||
exit(0);
|
||||
}
|
||||
/* wait for unlink to finish */
|
||||
else
|
||||
{
|
||||
while(wait(&ret_status) != pid)
|
||||
continue;
|
||||
if (ret_status < 0)
|
||||
{
|
||||
printf("Cannot unlink file\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (unlink(file) < 0)
|
||||
{
|
||||
printf("Cannot unlink file\n");
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
environ = envp;
|
||||
|
||||
strcpy(file_name, file);
|
||||
setup();
|
||||
restscr(cw);
|
||||
srand48(getpid());
|
||||
playit();
|
||||
}
|
||||
463
srogue/scrolls.c
Normal file
463
srogue/scrolls.c
Normal file
|
|
@ -0,0 +1,463 @@
|
|||
/*
|
||||
* Read a scroll and let it happen
|
||||
*
|
||||
* @(#)scrolls.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include "rogue.h"
|
||||
#include "rogue.ext"
|
||||
|
||||
/*
|
||||
* read_scroll:
|
||||
* Let the hero read a scroll
|
||||
*/
|
||||
read_scroll()
|
||||
{
|
||||
reg struct object *obj;
|
||||
reg struct linked_list *item;
|
||||
reg int i, j, wh;
|
||||
reg char ch, nch;
|
||||
struct room *rp;
|
||||
struct linked_list *titem;
|
||||
char buf[LINLEN];
|
||||
bool bless, curse;
|
||||
|
||||
if ((item = get_item("read", SCROLL)) == NULL)
|
||||
return;
|
||||
obj = OBJPTR(item);
|
||||
if (obj->o_type != SCROLL) {
|
||||
msg("Nothing to read.");
|
||||
after = FALSE;
|
||||
return;
|
||||
}
|
||||
msg("As you read the scroll, it vanishes.");
|
||||
wh = obj->o_which;
|
||||
bless = o_on(obj, ISBLESS);
|
||||
curse = o_on(obj, ISCURSED);
|
||||
del_pack(item); /* Get rid of the thing */
|
||||
|
||||
/*
|
||||
* Calculate the effect it has on the hero
|
||||
*/
|
||||
switch(wh) {
|
||||
case S_KNOWALL:
|
||||
if (!curse) {
|
||||
idenpack(); /* identify all the pack */
|
||||
msg("You feel more knowledgable.");
|
||||
chg_abil(WIS,1,TRUE);
|
||||
s_know[S_KNOWALL] = TRUE;
|
||||
}
|
||||
when S_CONFUSE:
|
||||
if (!curse) {
|
||||
/*
|
||||
* Scroll of monster confusion. Give him that power.
|
||||
*/
|
||||
msg("Your hands begin to glow red.");
|
||||
player.t_flags |= CANHUH;
|
||||
s_know[S_CONFUSE] = TRUE;
|
||||
}
|
||||
when S_LIGHT:
|
||||
rp = player.t_room;
|
||||
if (!curse) {
|
||||
if (rp == NULL) {
|
||||
s_know[S_LIGHT] = TRUE;
|
||||
msg("The corridor glows and then fades.");
|
||||
}
|
||||
else {
|
||||
if (rf_on(rp,ISDARK)) {
|
||||
s_know[S_LIGHT] = TRUE;
|
||||
msg("The room is lit.");
|
||||
rp->r_flags &= ~ISDARK;
|
||||
}
|
||||
light(&hero);
|
||||
mvwaddch(cw, hero.y, hero.x, PLAYER);
|
||||
}
|
||||
}
|
||||
when S_ARMOR:
|
||||
if (!curse) {
|
||||
if (cur_armor != NULL && o_off(cur_armor,ISPROT)) {
|
||||
s_know[S_ARMOR] = TRUE;
|
||||
msg("Your armor glows faintly for a moment.");
|
||||
if (o_on(cur_armor,ISCURSED))
|
||||
cur_armor->o_ac = armors[cur_armor->o_which].a_class;
|
||||
else
|
||||
cur_armor->o_ac--;
|
||||
resoflg(cur_armor,ISCURSED);
|
||||
}
|
||||
}
|
||||
when S_HOLD:
|
||||
if (!curse) {
|
||||
/*
|
||||
* Hold monster scroll. Stop all monsters within 3 spaces
|
||||
* from chasing after the hero.
|
||||
*/
|
||||
reg int x,y;
|
||||
reg struct linked_list *mon;
|
||||
|
||||
for (x = hero.x - 3; x <= hero.x + 3; x++) {
|
||||
for (y = hero.y - 3; y <= hero.y + 3; y++) {
|
||||
if (y > 0 && x > 0 && isalpha(mvwinch(mw, y, x))) {
|
||||
if ((mon = find_mons(y, x)) != NULL) {
|
||||
reg struct thing *th;
|
||||
|
||||
th = THINGPTR(mon);
|
||||
th->t_flags &= ~ISRUN;
|
||||
th->t_flags |= ISHELD;
|
||||
th->t_flags |= ISSTUCK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
when S_SLEEP:
|
||||
/*
|
||||
* Scroll which makes you fall asleep
|
||||
*/
|
||||
if (!bless) {
|
||||
s_know[S_SLEEP] = TRUE;
|
||||
msg("You fall asleep.");
|
||||
player.t_nocmd += 4 + rnd(SLEEPTIME);
|
||||
}
|
||||
when S_CREATE:
|
||||
if (!bless) {
|
||||
if (makemons(mtlev[rnd(levcount)]->m_show))
|
||||
s_know[S_CREATE] = TRUE;
|
||||
else
|
||||
msg("You hear a faint cry of anguish in the distance.");
|
||||
}
|
||||
when S_IDENT:
|
||||
if (!curse) {
|
||||
msg("This scroll is an identify scroll");
|
||||
s_know[S_IDENT] = TRUE;
|
||||
whatis(NULL);
|
||||
}
|
||||
when S_MAP:
|
||||
if (curse)
|
||||
break;
|
||||
s_know[S_MAP] = TRUE;
|
||||
addmsg("Oh, now this scroll has a ");
|
||||
if (rnd(100) < 10 || bless) {
|
||||
addmsg("very detailed map on it.");
|
||||
endmsg();
|
||||
displevl();
|
||||
}
|
||||
else {
|
||||
addmsg("map on it.");
|
||||
endmsg();
|
||||
overwrite(stdscr, hw);
|
||||
for (i = 1; i < LINES - 2; i++) {
|
||||
for (j = 0; j < COLS; j++) {
|
||||
switch (nch = ch = mvwinch(hw, i, j)) {
|
||||
case SECRETDOOR:
|
||||
nch = DOOR;
|
||||
mvaddch(i, j, nch);
|
||||
case '-':
|
||||
case '|':
|
||||
case DOOR:
|
||||
case PASSAGE:
|
||||
case ' ':
|
||||
case STAIRS:
|
||||
if (mvwinch(mw, i, j) != ' ') {
|
||||
struct thing *it;
|
||||
struct linked_list *blah;
|
||||
|
||||
blah = find_mons(i, j);
|
||||
if (blah != NULL) {
|
||||
it = THINGPTR(blah);
|
||||
if (it->t_oldch == ' ')
|
||||
it->t_oldch = nch;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
nch = ' ';
|
||||
}
|
||||
if (nch != ch)
|
||||
waddch(hw, nch);
|
||||
}
|
||||
}
|
||||
overlay(cw, hw);
|
||||
overwrite(hw, cw);
|
||||
}
|
||||
when S_GFIND:
|
||||
if (!curse) {
|
||||
int gtotal = 0;
|
||||
struct room *rp;
|
||||
|
||||
wclear(hw);
|
||||
for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) {
|
||||
gtotal += rp->r_goldval;
|
||||
if (rp->r_goldval != 0 &&
|
||||
mvinch(rp->r_gold.y,rp->r_gold.x) == GOLD)
|
||||
mvwaddch(hw,rp->r_gold.y,rp->r_gold.x,GOLD);
|
||||
}
|
||||
if (gtotal) {
|
||||
s_know[S_GFIND] = TRUE;
|
||||
msg("You begin to feel greedy and sense gold.");
|
||||
overlay(hw,cw);
|
||||
}
|
||||
else
|
||||
msg("You begin to feel a pull downward.");
|
||||
}
|
||||
when S_TELEP:
|
||||
if (!curse) {
|
||||
int rm;
|
||||
struct room *cur_room;
|
||||
|
||||
cur_room = player.t_room;
|
||||
rm = teleport(rndspot, &player);
|
||||
if (cur_room != &rooms[rm])
|
||||
s_know[S_TELEP] = TRUE;
|
||||
}
|
||||
when S_ENCH:
|
||||
if (!curse) {
|
||||
if (cur_weapon == NULL || (cur_weapon != NULL &&
|
||||
(o_on(cur_weapon,ISPROT) || cur_weapon->o_type != WEAPON)))
|
||||
msg("You feel a strange sense of loss.");
|
||||
else {
|
||||
s_know[S_ENCH] = TRUE;
|
||||
if (o_on(cur_weapon,ISCURSED)) {
|
||||
resoflg(cur_weapon,ISCURSED);
|
||||
cur_weapon->o_hplus = rnd(2);
|
||||
cur_weapon->o_dplus = rnd(2);
|
||||
}
|
||||
else { /* weapon was not cursed here */
|
||||
if (rnd(100) < 50)
|
||||
cur_weapon->o_hplus += 1;
|
||||
else
|
||||
cur_weapon->o_dplus += 1;
|
||||
}
|
||||
setoflg(cur_weapon, ISKNOW);
|
||||
msg("Your %s glows blue for a moment.",
|
||||
w_magic[cur_weapon->o_which].mi_name);
|
||||
}
|
||||
}
|
||||
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 (!curse) {
|
||||
if (cur_armor != NULL && o_off(cur_armor,ISPROT))
|
||||
resoflg(cur_armor,ISCURSED);
|
||||
if (cur_weapon != NULL && o_off(cur_weapon,ISPROT))
|
||||
resoflg(cur_weapon,ISCURSED);
|
||||
if (cur_ring[LEFT]!=NULL && o_off(cur_ring[LEFT],ISPROT))
|
||||
resoflg(cur_ring[LEFT],ISCURSED);
|
||||
if (cur_ring[RIGHT]!=NULL && o_off(cur_ring[RIGHT],ISPROT))
|
||||
resoflg(cur_ring[RIGHT],ISCURSED);
|
||||
msg("You feel as if somebody is watching over you.");
|
||||
s_know[S_REMOVE] = TRUE;
|
||||
}
|
||||
when S_AGGR:
|
||||
if (!bless) {
|
||||
if (mlist != NULL) {
|
||||
aggravate();
|
||||
msg("You hear a high pitched humming noise.");
|
||||
s_know[S_AGGR] = TRUE;
|
||||
}
|
||||
}
|
||||
when S_NOP:
|
||||
msg("This scroll seems to be blank.");
|
||||
when S_GENOCIDE:
|
||||
if (!curse) {
|
||||
msg("You have been granted the boon of genocide.");
|
||||
genocide();
|
||||
s_know[S_GENOCIDE] = TRUE;
|
||||
}
|
||||
when S_DCURSE:
|
||||
if (!bless) {
|
||||
struct linked_list *ll;
|
||||
struct object *lb;
|
||||
|
||||
msg("Your pack shudders.");
|
||||
for (ll = pack ; ll != NULL ; ll = next(ll)) {
|
||||
lb = OBJPTR(ll);
|
||||
if (o_off(lb,ISPROT)) {
|
||||
resoflg(lb, ISBLESS);
|
||||
setoflg(lb, ISCURSED);
|
||||
}
|
||||
}
|
||||
}
|
||||
when S_DLEVEL:
|
||||
if (!bless) {
|
||||
int much = rnd(9) - 4;
|
||||
|
||||
if (much != 0) {
|
||||
level += much;
|
||||
if (level < 1)
|
||||
level = 1;
|
||||
mpos = 0;
|
||||
new_level(NORMLEV); /* change levels */
|
||||
msg("You are whisked away to another region.");
|
||||
s_know[S_DLEVEL] = TRUE;
|
||||
}
|
||||
}
|
||||
when S_PROTECT:
|
||||
if (!curse) {
|
||||
struct linked_list *ll;
|
||||
struct object *lb;
|
||||
|
||||
msg("You are granted the power of protection.");
|
||||
if ((ll = get_item("protect",0)) != NULL) {
|
||||
lb = OBJPTR(ll);
|
||||
setoflg(lb,ISPROT);
|
||||
mpos = 0;
|
||||
msg("Protected %s.",inv_name(lb,TRUE));
|
||||
}
|
||||
s_know[S_PROTECT] = TRUE;
|
||||
}
|
||||
when S_ALLENCH:
|
||||
if (!curse) {
|
||||
struct linked_list *ll;
|
||||
struct object *lb;
|
||||
int howmuch, ac, good;
|
||||
|
||||
msg("You are granted the power of enchantment.");
|
||||
good = TRUE;
|
||||
if ((ll = get_item("enchant",0)) != NULL) {
|
||||
lb = OBJPTR(ll);
|
||||
resoflg(lb,ISCURSED);
|
||||
resoflg(lb,ISPROT);
|
||||
howmuch = rnd(3) + 1;
|
||||
switch(lb->o_type) {
|
||||
case RING:
|
||||
if (lb->o_ac < 0)
|
||||
lb->o_ac = 0;
|
||||
lb->o_ac += howmuch;
|
||||
when ARMOR:
|
||||
ac = armors[lb->o_which].a_class;
|
||||
if (lb->o_ac > ac)
|
||||
lb->o_ac = ac;
|
||||
lb->o_ac -= howmuch;
|
||||
when STICK:
|
||||
lb->o_charges += howmuch + 10;
|
||||
when WEAPON:
|
||||
if (lb->o_dplus < 0)
|
||||
lb->o_dplus = 0;
|
||||
if (lb->o_hplus < 0)
|
||||
lb->o_hplus = 0;
|
||||
lb->o_hplus += howmuch;
|
||||
lb->o_dplus += howmuch;
|
||||
otherwise:
|
||||
msg("You are injured as the scroll flashes & bursts into flames !!!");
|
||||
chg_hpt(-roll(6,6),FALSE,K_SCROLL);
|
||||
good = FALSE;
|
||||
}
|
||||
if (good) {
|
||||
mpos = 0;
|
||||
msg("Enchanted %s.",inv_name(lb,TRUE));
|
||||
}
|
||||
}
|
||||
s_know[S_ALLENCH] = TRUE;
|
||||
}
|
||||
when S_BLESS:
|
||||
if (!curse) {
|
||||
struct linked_list *ll;
|
||||
struct object *lb;
|
||||
|
||||
msg("Your pack glistens brightly.");
|
||||
for (ll = pack ; ll != NULL ; ll = next(ll)) {
|
||||
whatis(ll);
|
||||
lb = OBJPTR(ll);
|
||||
resoflg(lb,ISCURSED);
|
||||
setoflg(lb,ISBLESS);
|
||||
}
|
||||
}
|
||||
when S_MAKEIT:
|
||||
if (!curse) {
|
||||
msg("You have been endowed with the power of creation.");
|
||||
s_know[S_MAKEIT] = TRUE;
|
||||
create_obj(TRUE);
|
||||
}
|
||||
when S_BAN: {
|
||||
int howdeep;
|
||||
char *ptr;
|
||||
|
||||
if (bless) {
|
||||
if (level > 6) {
|
||||
howdeep = 1 + rnd(5);
|
||||
ptr = "elevated to the upper";
|
||||
}
|
||||
else {
|
||||
howdeep = -1;
|
||||
bless = FALSE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
howdeep = level + 10 + rnd(20) + (curse * 20);
|
||||
ptr = "banished to the lower";
|
||||
}
|
||||
if ((!bless && level < howdeep) || bless) {
|
||||
level = howdeep;
|
||||
new_level(NORMLEV);
|
||||
mpos = 0;
|
||||
msg("You are %s regions.", ptr);
|
||||
s_know[S_BAN] = TRUE;
|
||||
}
|
||||
}
|
||||
when S_CWAND:
|
||||
if (!curse) {
|
||||
struct linked_list *ll;
|
||||
struct object *lb;
|
||||
bool wands = FALSE;
|
||||
|
||||
for (ll = pack ; ll != NULL ; ll = next(ll)) {
|
||||
lb = OBJPTR(ll);
|
||||
if (lb->o_type == STICK) {
|
||||
whatis(ll);
|
||||
setoflg(lb, ISKNOW);
|
||||
resoflg(lb, ISCURSED);
|
||||
lb->o_charges += rnd(11) + 5;
|
||||
wands = TRUE;
|
||||
}
|
||||
}
|
||||
if (wands) {
|
||||
msg("Your sticks gleam.");
|
||||
s_know[wh] = TRUE;
|
||||
}
|
||||
}
|
||||
when S_LOCTRAP: {
|
||||
struct trap *trp;
|
||||
|
||||
if (ntraps > 0) {
|
||||
for (trp = &traps[0]; trp < &traps[ntraps]; trp++)
|
||||
trp->tr_flags |= ISFOUND;
|
||||
look(FALSE);
|
||||
msg("You now recognize pitfalls.");
|
||||
s_know[S_LOCTRAP] = TRUE;
|
||||
}
|
||||
}
|
||||
otherwise:
|
||||
msg("What a puzzling scroll!");
|
||||
return;
|
||||
}
|
||||
look(TRUE);
|
||||
nochange = FALSE;
|
||||
if (s_know[wh] && s_guess[wh]) {
|
||||
free(s_guess[wh]);
|
||||
s_guess[wh] = NULL;
|
||||
}
|
||||
else if (!s_know[wh] && s_guess[wh] == NULL) {
|
||||
strcpy(buf, s_names[wh]);
|
||||
msg(callit);
|
||||
if (get_str(buf, cw) == NORM) {
|
||||
s_guess[wh] = new(strlen(buf) + 1);
|
||||
strcpy(s_guess[wh], buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
2320
srogue/state.c
Normal file
2320
srogue/state.c
Normal file
File diff suppressed because it is too large
Load diff
592
srogue/sticks.c
Normal file
592
srogue/sticks.c
Normal file
|
|
@ -0,0 +1,592 @@
|
|||
/*
|
||||
* Functions to deal with the various sticks one
|
||||
* might find while wandering around the dungeon.
|
||||
*
|
||||
* @(#)sticks.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include "rogue.h"
|
||||
#include "rogue.ext"
|
||||
|
||||
/*
|
||||
* fix_stick:
|
||||
* Init a stick for the hero
|
||||
*/
|
||||
fix_stick(cur)
|
||||
struct object *cur;
|
||||
{
|
||||
struct rod *rd;
|
||||
|
||||
cur->o_type = STICK;
|
||||
cur->o_charges = 4 + rnd(5);
|
||||
strcpy(cur->o_hurldmg, "1d1");
|
||||
rd = &ws_stuff[cur->o_which];
|
||||
cur->o_weight = rd->ws_wght;
|
||||
cur->o_vol = rd->ws_vol;
|
||||
if (strcmp(rd->ws_type, "staff") == 0) {
|
||||
strcpy(cur->o_damage, "2d3");
|
||||
cur->o_charges += rnd(5) + 3;
|
||||
}
|
||||
else {
|
||||
strcpy(cur->o_damage, "1d1");
|
||||
}
|
||||
switch (cur->o_which) {
|
||||
case WS_HIT:
|
||||
if(rnd(100) < 15) {
|
||||
cur->o_hplus = 9;
|
||||
cur->o_dplus = 9;
|
||||
strcpy(cur->o_damage,"3d8");
|
||||
}
|
||||
else {
|
||||
cur->o_hplus = 3;
|
||||
cur->o_dplus = 3;
|
||||
strcpy(cur->o_damage,"1d8");
|
||||
}
|
||||
when WS_LIGHT:
|
||||
cur->o_charges += 7 + rnd(9);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* do_zap:
|
||||
* Zap a stick at something
|
||||
*/
|
||||
do_zap(gotdir)
|
||||
bool gotdir;
|
||||
{
|
||||
reg struct linked_list *item;
|
||||
reg struct object *obj;
|
||||
reg struct thing *tp;
|
||||
reg int y, x, wh;
|
||||
struct room *rp;
|
||||
bool bless, curse;
|
||||
int better = 0;
|
||||
|
||||
if ((item = get_item("zap with", STICK)) == NULL)
|
||||
return;
|
||||
obj = OBJPTR(item);
|
||||
wh = obj->o_which;
|
||||
bless = o_on(obj, ISBLESS);
|
||||
curse = o_on(obj, ISCURSED);
|
||||
if (obj->o_type != STICK) {
|
||||
msg("You can't zap with that!");
|
||||
after = FALSE;
|
||||
return;
|
||||
}
|
||||
if (obj->o_charges == 0) {
|
||||
msg("Nothing happens.");
|
||||
return;
|
||||
}
|
||||
if (!gotdir)
|
||||
do {
|
||||
delta.y = rnd(3) - 1;
|
||||
delta.x = rnd(3) - 1;
|
||||
} while (delta.y == 0 && delta.x == 0);
|
||||
rp = player.t_room;
|
||||
if (bless)
|
||||
better = 3;
|
||||
else if (curse)
|
||||
better = -3;
|
||||
switch (wh) {
|
||||
case WS_SAPLIFE:
|
||||
if (!bless) {
|
||||
if (him->s_hpt > 1)
|
||||
him->s_hpt /= 2; /* zap half his hit points */
|
||||
}
|
||||
when WS_CURE:
|
||||
if (!curse) {
|
||||
ws_know[WS_CURE] = TRUE;
|
||||
heal_self(6, FALSE);
|
||||
unconfuse(FALSE);
|
||||
notslow(FALSE);
|
||||
sight(FALSE);
|
||||
}
|
||||
when WS_PYRO:
|
||||
if (!bless) {
|
||||
msg("The rod explodes !!!");
|
||||
chg_hpt(-roll(6,6), FALSE, K_ROD);
|
||||
ws_know[WS_PYRO] = TRUE;
|
||||
del_pack(item); /* throw it away */
|
||||
}
|
||||
when WS_HUNGER:
|
||||
if (!bless) {
|
||||
struct linked_list *ip;
|
||||
struct object *lb;
|
||||
|
||||
food_left /= 3;
|
||||
if ((ip = pack) != NULL) {
|
||||
lb = OBJPTR(ip);
|
||||
if (lb->o_type == FOOD) {
|
||||
if ((lb->o_count -= roll(1,4)) < 1)
|
||||
del_pack(ip);
|
||||
}
|
||||
}
|
||||
}
|
||||
when WS_PARZ:
|
||||
case WS_MREG:
|
||||
case WS_MDEG:
|
||||
case WS_ANNIH: {
|
||||
struct linked_list *mitem;
|
||||
struct thing *it;
|
||||
reg int i,j;
|
||||
|
||||
for (i = hero.y - 3; i <= hero.y + 3; i++) {
|
||||
for (j = hero.x - 3; j <= hero.x + 3; j++) {
|
||||
if (!cordok(i, j))
|
||||
continue;
|
||||
if (isalpha(mvwinch(mw,i,j))) {
|
||||
mitem = find_mons(i, j);
|
||||
if (mitem == NULL)
|
||||
continue;
|
||||
it = THINGPTR(mitem);
|
||||
switch(wh) {
|
||||
case WS_ANNIH:
|
||||
if (!curse)
|
||||
killed(mitem,FALSE);
|
||||
when WS_MREG:
|
||||
if (!bless)
|
||||
it->t_stats.s_hpt *= 2;
|
||||
when WS_MDEG:
|
||||
if (!curse) {
|
||||
it->t_stats.s_hpt /= 2;
|
||||
if (it->t_stats.s_hpt < 2)
|
||||
killed(mitem,FALSE);
|
||||
}
|
||||
when WS_PARZ:
|
||||
if (!curse) {
|
||||
it->t_flags |= ISPARA;
|
||||
it->t_flags &= ~ISRUN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
when WS_LIGHT:
|
||||
if (!curse) {
|
||||
ws_know[WS_LIGHT] = TRUE;
|
||||
if (rp == NULL)
|
||||
msg("The corridor glows and then fades.");
|
||||
else {
|
||||
msg("The room is lit.");
|
||||
rp->r_flags &= ~ISDARK;
|
||||
light(&hero);
|
||||
mvwaddch(cw, hero.y, hero.x, PLAYER);
|
||||
}
|
||||
}
|
||||
when WS_DRAIN:
|
||||
/*
|
||||
* Take away 1/2 of hero's hit points, then take it away
|
||||
* evenly from the monsters in the room (or next to hero
|
||||
* if he is in a passage)
|
||||
*/
|
||||
if (him->s_hpt < 2) {
|
||||
msg("You are too weak to use it.");
|
||||
return;
|
||||
}
|
||||
else if (!curse) {
|
||||
if (rp == NULL)
|
||||
drain(hero.y-1, hero.y+1, hero.x-1, hero.x+1);
|
||||
else
|
||||
drain(rp->r_pos.y, rp->r_pos.y+rp->r_max.y,
|
||||
rp->r_pos.x, rp->r_pos.x+rp->r_max.x);
|
||||
}
|
||||
when WS_POLYM:
|
||||
case WS_TELAWAY:
|
||||
case WS_TELTO:
|
||||
case WS_CANCEL:
|
||||
case WS_MINVIS:
|
||||
{
|
||||
reg char monster, oldch;
|
||||
|
||||
y = hero.y;
|
||||
x = hero.x;
|
||||
do {
|
||||
y += delta.y;
|
||||
x += delta.x;
|
||||
} while (step_ok(winat(y, x)));
|
||||
if (isalpha(monster = mvwinch(mw, y, x))) {
|
||||
int omonst;
|
||||
|
||||
if (wh != WS_MINVIS)
|
||||
unhold(monster);
|
||||
item = find_mons(y, x);
|
||||
if (item == NULL)
|
||||
break;
|
||||
tp = THINGPTR(item);
|
||||
omonst = tp->t_indx;
|
||||
if (wh == WS_POLYM && !curse) {
|
||||
detach(mlist, item);
|
||||
discard(item);
|
||||
oldch = tp->t_oldch;
|
||||
delta.y = y;
|
||||
delta.x = x;
|
||||
monster = rnd_mon(FALSE, TRUE);
|
||||
item = new_monster(monster, &delta, FALSE);
|
||||
if (!(tp->t_flags & ISRUN))
|
||||
runto(&delta, &hero);
|
||||
if (isalpha(mvwinch(cw, y, x)))
|
||||
mvwaddch(cw, y, x, monsters[monster].m_show);
|
||||
tp->t_oldch = oldch;
|
||||
ws_know[WS_POLYM] |= (monster != omonst);
|
||||
}
|
||||
else if (wh == WS_MINVIS && !bless) {
|
||||
tp->t_flags |= ISINVIS;
|
||||
mvwaddch(cw,y,x,tp->t_oldch); /* hide em */
|
||||
runto(&tp->t_pos, &hero);
|
||||
}
|
||||
else if (wh == WS_CANCEL && !curse) {
|
||||
tp->t_flags |= ISCANC;
|
||||
tp->t_flags &= ~ISINVIS;
|
||||
}
|
||||
else {
|
||||
if (wh == WS_TELAWAY) {
|
||||
if (curse)
|
||||
break;
|
||||
tp->t_pos = *rnd_pos(&rooms[rnd_room()]);
|
||||
}
|
||||
else { /* WS_TELTO */
|
||||
if (bless)
|
||||
break;
|
||||
tp->t_pos.y = hero.y + delta.y;
|
||||
tp->t_pos.x = hero.x + delta.x;
|
||||
}
|
||||
if (isalpha(mvwinch(cw, y, x)))
|
||||
mvwaddch(cw, y, x, tp->t_oldch);
|
||||
tp->t_dest = &hero;
|
||||
tp->t_flags |= ISRUN;
|
||||
mvwaddch(mw, y, x, ' ');
|
||||
mvwaddch(mw, tp->t_pos.y, tp->t_pos.x, monster);
|
||||
tp->t_oldch = mvwinch(cw,tp->t_pos.y,tp->t_pos.x);
|
||||
}
|
||||
}
|
||||
}
|
||||
when WS_MISSILE:
|
||||
{
|
||||
struct coord *whe;
|
||||
static struct object bolt = {
|
||||
{0, 0}, "", "6d6", "", '*', 0, 0, 1000, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
if (curse)
|
||||
strcpy(bolt.o_hurldmg,"3d3");
|
||||
else if (bless)
|
||||
strcpy(bolt.o_hurldmg,"9d9");
|
||||
ws_know[WS_MISSILE] = TRUE;
|
||||
do_motion(&bolt, delta.y, delta.x);
|
||||
whe = &bolt.o_pos;
|
||||
if (isalpha(mvwinch(mw, whe->y, whe->x))) {
|
||||
struct linked_list *it;
|
||||
|
||||
runto(whe, &hero);
|
||||
it = find_mons(whe->y, whe->x);
|
||||
if (it != NULL) {
|
||||
if (!save_throw(VS_MAGIC + better, THINGPTR(it))) {
|
||||
hit_monster(whe, &bolt);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
msg("Missle vanishes.");
|
||||
}
|
||||
when WS_NOP:
|
||||
msg("Your %s flickers momentarily and then fades",
|
||||
ws_stuff[wh].ws_type);
|
||||
when WS_HIT: {
|
||||
char ch;
|
||||
|
||||
delta.y += hero.y;
|
||||
delta.x += hero.x;
|
||||
ch = winat(delta.y, delta.x);
|
||||
if (curse) { /* decrease for cursed */
|
||||
strcpy(obj->o_damage,"1d1");
|
||||
obj->o_hplus = obj->o_dplus = 0;
|
||||
}
|
||||
else if (bless) { /* increase for blessed */
|
||||
strcpy(obj->o_damage,"5d8");
|
||||
obj->o_hplus = obj->o_dplus = 12;
|
||||
}
|
||||
if (isalpha(ch))
|
||||
fight(&delta, obj, FALSE);
|
||||
}
|
||||
when WS_HASTE_M:
|
||||
case WS_CONFMON:
|
||||
case WS_SLOW_M:
|
||||
case WS_MOREMON: {
|
||||
reg int m1,m2;
|
||||
struct coord mp;
|
||||
struct linked_list *titem;
|
||||
|
||||
y = hero.y;
|
||||
x = hero.x;
|
||||
do {
|
||||
y += delta.y;
|
||||
x += delta.x;
|
||||
} while (step_ok(winat(y, x)));
|
||||
if (isalpha(mvwinch(mw, y, x))) {
|
||||
item = find_mons(y, x);
|
||||
if (item == NULL)
|
||||
break;
|
||||
tp = THINGPTR(item);
|
||||
if (wh == WS_HASTE_M && !bless) { /* haste it */
|
||||
if (on(*tp, ISSLOW))
|
||||
tp->t_flags &= ~ISSLOW;
|
||||
else
|
||||
tp->t_flags |= ISHASTE;
|
||||
}
|
||||
else if (wh == WS_CONFMON && !curse) { /* confuse it */
|
||||
tp->t_flags |= ISHUH;
|
||||
if (pl_on(ISHELD) && tp->t_type == 'd')
|
||||
player.t_flags &= ~ISHELD;
|
||||
}
|
||||
else if (wh == WS_SLOW_M && !curse) { /* slow it */
|
||||
if (on(*tp, ISHASTE))
|
||||
tp->t_flags &= ~ISHASTE;
|
||||
else
|
||||
tp->t_flags |= ISSLOW;
|
||||
tp->t_turn = TRUE;
|
||||
}
|
||||
else if (!bless) { /* WS_MOREMON: multiply it */
|
||||
char ch;
|
||||
struct thing *th;
|
||||
|
||||
for (m1 = tp->t_pos.x-1; m1 <= tp->t_pos.x+1; m1++) {
|
||||
for(m2 = tp->t_pos.y-1; m2 <= tp->t_pos.y+1; m2++) {
|
||||
if (hero.x == m1 && hero.y == m2)
|
||||
continue;
|
||||
ch = winat(m2,m1);
|
||||
if (step_ok(ch)) {
|
||||
mp.x = m1; /* create it */
|
||||
mp.y = m2;
|
||||
titem = new_monster(tp->t_indx, &mp, FALSE);
|
||||
th = THINGPTR(titem);
|
||||
th->t_flags |= ISMEAN;
|
||||
runto(&mp, &hero);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delta.y = y;
|
||||
delta.x = x;
|
||||
runto(&delta, &hero);
|
||||
}
|
||||
}
|
||||
when WS_ELECT:
|
||||
case WS_FIRE:
|
||||
case WS_COLD: {
|
||||
reg char dirch, ch, *name;
|
||||
reg bool bounced, used;
|
||||
int boingcnt, boltlen;
|
||||
struct coord pos;
|
||||
struct coord spotpos[BOLT_LENGTH * 2];
|
||||
static struct object bolt = {
|
||||
{0, 0}, "", "6d6", "", '*', 0, 0, 1000, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
boltlen = BOLT_LENGTH;
|
||||
if (curse) {
|
||||
strcpy(bolt.o_hurldmg,"3d3");
|
||||
boltlen -= 3;
|
||||
}
|
||||
else if (bless) {
|
||||
strcpy(bolt.o_hurldmg,"9d9");
|
||||
boltlen += 3;
|
||||
}
|
||||
switch (delta.y + delta.x) {
|
||||
case 0: dirch = '/';
|
||||
when 1: case -1: dirch = (delta.y == 0 ? '-' : '|');
|
||||
when 2: case -2: dirch = '\\';
|
||||
}
|
||||
pos = hero;
|
||||
bounced = FALSE;
|
||||
boingcnt = 0;
|
||||
used = FALSE;
|
||||
if (wh == WS_ELECT)
|
||||
name = "bolt";
|
||||
else if (wh == WS_FIRE)
|
||||
name = "flame";
|
||||
else
|
||||
name = "ice";
|
||||
for (y = 0; y < boltlen && !used; y++) {
|
||||
ch = winat(pos.y, pos.x);
|
||||
spotpos[y] = pos;
|
||||
switch (ch) {
|
||||
case SECRETDOOR:
|
||||
case '|':
|
||||
case '-':
|
||||
case ' ':
|
||||
bounced = TRUE;
|
||||
if (++boingcnt > 6)
|
||||
used = TRUE; /* only so many bounces */
|
||||
delta.y = -delta.y;
|
||||
delta.x = -delta.x;
|
||||
y--;
|
||||
msg("The bolt bounces");
|
||||
break;
|
||||
default:
|
||||
if (isalpha(ch)) {
|
||||
struct linked_list *it;
|
||||
|
||||
it = find_mons(pos.y, pos.x);
|
||||
runto(&pos, &hero);
|
||||
if (it != NULL) {
|
||||
if (!save_throw(VS_MAGIC+better,THINGPTR(it))) {
|
||||
bolt.o_pos = pos;
|
||||
hit_monster(&pos, &bolt);
|
||||
used = TRUE;
|
||||
}
|
||||
else if(ch != 'M' || show(pos.y,pos.x)=='M') {
|
||||
msg("%s misses", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(bounced && pos.y==hero.y && pos.x==hero.x) {
|
||||
bounced = FALSE;
|
||||
if (!save(VS_MAGIC + better)) {
|
||||
msg("The %s hits you.", name);
|
||||
chg_hpt(-roll(6, 6),FALSE,K_BOLT);
|
||||
used = TRUE;
|
||||
}
|
||||
else
|
||||
msg("The %s whizzes by you.", name);
|
||||
}
|
||||
mvwaddch(cw, pos.y, pos.x, dirch);
|
||||
draw(cw);
|
||||
}
|
||||
pos.y += delta.y;
|
||||
pos.x += delta.x;
|
||||
}
|
||||
for (x = 0; x < y; x++)
|
||||
mvwaddch(cw, spotpos[x].y, spotpos[x].x,
|
||||
show(spotpos[x].y, spotpos[x].x));
|
||||
ws_know[wh] = TRUE;
|
||||
}
|
||||
when WS_ANTIM: {
|
||||
reg int m1, m2, x1, y1;
|
||||
struct linked_list *ll;
|
||||
struct thing *lt;
|
||||
int ch, radius;
|
||||
|
||||
y1 = hero.y;
|
||||
x1 = hero.x;
|
||||
do {
|
||||
y1 += delta.y;
|
||||
x1 += delta.x;
|
||||
ch = winat(y1, x1);
|
||||
} while (ch == PASSAGE || ch == FLOOR);
|
||||
if (curse)
|
||||
radius = 2;
|
||||
else if (bless)
|
||||
radius = 0;
|
||||
else
|
||||
radius = 1;
|
||||
for (m1 = x1 - radius; m1 <= x1 + radius; m1++) {
|
||||
for (m2 = y1 - radius; m2 <= y1 + radius; m2++) {
|
||||
if (!cordok(m2, m1))
|
||||
continue;
|
||||
ch = winat(m2, m1);
|
||||
if (m1 == hero.x && m2 == hero.y)
|
||||
continue;
|
||||
if (ch == ' ')
|
||||
continue;
|
||||
ll = find_obj(m2,m1);
|
||||
if (ll != NULL) {
|
||||
detach(lvl_obj,ll);
|
||||
discard(ll);
|
||||
}
|
||||
ll = find_mons(m2,m1);
|
||||
if (ll != NULL) {
|
||||
lt = THINGPTR(ll);
|
||||
him->s_exp += lt->t_stats.s_exp;
|
||||
unhold(lt->t_type);
|
||||
/*
|
||||
* throw away anything that the monster
|
||||
* was carrying in its pack
|
||||
*/
|
||||
free_list(lt->t_pack);
|
||||
detach(mlist,ll);
|
||||
discard(ll);
|
||||
mvwaddch(mw,m2,m1,' ');
|
||||
}
|
||||
mvaddch(m2,m1,' ');
|
||||
mvwaddch(cw,m2,m1,' ');
|
||||
}
|
||||
}
|
||||
touchwin(cw);
|
||||
touchwin(mw);
|
||||
check_level();
|
||||
}
|
||||
otherwise:
|
||||
msg("What a bizarre schtick!");
|
||||
}
|
||||
obj->o_charges--;
|
||||
}
|
||||
|
||||
/*
|
||||
* drain:
|
||||
* Do drain hit points from player stick
|
||||
*/
|
||||
drain(ymin, ymax, xmin, xmax)
|
||||
int ymin, ymax, xmin, xmax;
|
||||
{
|
||||
reg int i, j, cnt;
|
||||
reg struct thing *ick;
|
||||
reg struct linked_list *item;
|
||||
|
||||
/*
|
||||
* First count how many things we need to spread the hit points among
|
||||
*/
|
||||
cnt = 0;
|
||||
for (i = ymin; i <= ymax; i++)
|
||||
for (j = xmin; j <= xmax; j++)
|
||||
if (isalpha(mvwinch(mw, i, j)))
|
||||
cnt++;
|
||||
if (cnt == 0) {
|
||||
msg("You have a tingling feeling.");
|
||||
return;
|
||||
}
|
||||
cnt = him->s_hpt / cnt;
|
||||
him->s_hpt /= 2;
|
||||
/*
|
||||
* Now zot all of the monsters
|
||||
*/
|
||||
for (i = ymin; i <= ymax; i++) {
|
||||
for (j = xmin; j <= xmax; j++) {
|
||||
if(isalpha(mvwinch(mw, i, j))) {
|
||||
item = find_mons(i, j);
|
||||
if (item == NULL)
|
||||
continue;
|
||||
ick = THINGPTR(item);
|
||||
if ((ick->t_stats.s_hpt -= cnt) < 1)
|
||||
killed(item,cansee(i,j) && !(ick->t_flags & ISINVIS));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* charge_str:
|
||||
* Return number of charges left in a stick
|
||||
*/
|
||||
char *
|
||||
charge_str(obj)
|
||||
struct object *obj;
|
||||
{
|
||||
static char buf[20];
|
||||
|
||||
buf[0] = '\0';
|
||||
if (o_on(obj,ISKNOW) || o_on(obj,ISPOST))
|
||||
sprintf(buf, " [%d]", obj->o_charges);
|
||||
return buf;
|
||||
}
|
||||
460
srogue/things.c
Normal file
460
srogue/things.c
Normal file
|
|
@ -0,0 +1,460 @@
|
|||
/*
|
||||
* Contains functions for dealing with things like
|
||||
* potions and scrolls
|
||||
*
|
||||
* @(#)things.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include "rogue.h"
|
||||
#include "rogue.ext"
|
||||
|
||||
|
||||
/*
|
||||
* inv_name:
|
||||
* Return the name of something as it would appear in an inventory.
|
||||
*/
|
||||
char *
|
||||
inv_name(obj, drop)
|
||||
struct object *obj;
|
||||
bool drop;
|
||||
{
|
||||
reg char *pb, *tn, *pl;
|
||||
reg int wh, knowit;
|
||||
char nm[3], *inm, *q;
|
||||
|
||||
wh = obj->o_which;
|
||||
knowit = FALSE;
|
||||
if (obj->o_count > 1)
|
||||
pl = "s";
|
||||
else
|
||||
pl = "";
|
||||
if (obj->o_count > 1)
|
||||
sprintf(nm, "%d", obj->o_count);
|
||||
else
|
||||
strcpy(nm, "A");
|
||||
tn = obj->o_typname;
|
||||
q = "";
|
||||
switch(obj->o_type) {
|
||||
case SCROLL:
|
||||
sprintf(prbuf, "%s %s%s ", nm, tn, pl);
|
||||
pb = &prbuf[strlen(prbuf)];
|
||||
if (s_know[wh] || o_on(obj,ISPOST)) {
|
||||
knowit = TRUE;
|
||||
sprintf(pb, "of %s", s_magic[wh].mi_name);
|
||||
}
|
||||
else if (s_guess[wh])
|
||||
sprintf(pb, "called %s", s_guess[wh]);
|
||||
else
|
||||
sprintf(pb, "titled '%s'", s_names[wh]);
|
||||
when POTION:
|
||||
sprintf(prbuf, "%s %s%s ", nm, tn, pl);
|
||||
pb = &prbuf[strlen(prbuf)];
|
||||
if (p_know[wh] || o_on(obj, ISPOST)) {
|
||||
sprintf(pb, "of %s", p_magic[wh].mi_name);
|
||||
knowit = TRUE;
|
||||
if (p_know[wh]) {
|
||||
pb = &prbuf[strlen(prbuf)];
|
||||
sprintf(pb,"(%s)",p_colors[wh]);
|
||||
}
|
||||
}
|
||||
else if (p_guess[wh])
|
||||
sprintf(pb,"called %s(%s)", p_guess[wh],p_colors[wh]);
|
||||
else
|
||||
sprintf(prbuf,"%s%s %s %s%s", nm, vowelstr(p_colors[wh]),
|
||||
p_colors[wh], tn, pl);
|
||||
when FOOD:
|
||||
if (wh == 1) {
|
||||
if (obj->o_count == 1)
|
||||
q = vowelstr(fruit);
|
||||
sprintf(prbuf, "%s%s %s%s", nm, q, fruit, pl);
|
||||
}
|
||||
else {
|
||||
if (obj->o_count == 1)
|
||||
sprintf(prbuf, "Some %s", tn);
|
||||
else
|
||||
sprintf(prbuf, "%s rations of %s", nm, tn);
|
||||
}
|
||||
knowit = TRUE;
|
||||
when WEAPON:
|
||||
inm = w_magic[wh].mi_name;
|
||||
strcpy(prbuf, nm);
|
||||
if (obj->o_count == 1)
|
||||
q = vowelstr(inm);
|
||||
pb = &prbuf[strlen(prbuf)];
|
||||
if (o_on(obj,ISKNOW | ISPOST)) {
|
||||
knowit = TRUE;
|
||||
sprintf(pb, " %s %s", num(obj->o_hplus, obj->o_dplus), inm);
|
||||
}
|
||||
else
|
||||
sprintf(pb, "%s %s", q, inm);
|
||||
strcat(prbuf, pl);
|
||||
when ARMOR:
|
||||
inm = a_magic[wh].mi_name;
|
||||
if (o_on(obj,ISKNOW | ISPOST)) {
|
||||
knowit = TRUE;
|
||||
sprintf(prbuf, "%s %s",num(armors[wh].a_class - obj->o_ac, 0),
|
||||
inm);
|
||||
}
|
||||
else
|
||||
sprintf(prbuf, "%s", inm);
|
||||
when AMULET:
|
||||
strcpy(prbuf, "The Amulet of Yendor");
|
||||
when STICK: {
|
||||
struct rod *rd;
|
||||
|
||||
rd = &ws_stuff[wh];
|
||||
sprintf(prbuf, "A %s ", rd->ws_type);
|
||||
pb = &prbuf[strlen(prbuf)];
|
||||
if (ws_know[wh] || o_on(obj, ISPOST)) {
|
||||
knowit = TRUE;
|
||||
sprintf(pb,"of %s%s",ws_magic[wh].mi_name,charge_str(obj));
|
||||
if (ws_know[wh]) {
|
||||
pb = &prbuf[strlen(prbuf)];
|
||||
sprintf(pb,"(%s)",rd->ws_made);
|
||||
}
|
||||
}
|
||||
else if (ws_guess[wh])
|
||||
sprintf(pb, "called %s(%s)", ws_guess[wh], rd->ws_made);
|
||||
else
|
||||
sprintf(prbuf, "A%s %s %s", vowelstr(rd->ws_made),
|
||||
rd->ws_made, rd->ws_type);
|
||||
}
|
||||
when RING:
|
||||
if (r_know[wh] || o_on(obj, ISPOST)) {
|
||||
knowit = TRUE;
|
||||
sprintf(prbuf, "A%s %s of %s", ring_num(obj), tn,
|
||||
r_magic[wh].mi_name);
|
||||
if (r_know[wh]) {
|
||||
pb = &prbuf[strlen(prbuf)];
|
||||
sprintf(pb,"(%s)", r_stones[wh]);
|
||||
}
|
||||
}
|
||||
else if (r_guess[wh])
|
||||
sprintf(prbuf,"A %s called %s(%s)",tn, r_guess[wh],
|
||||
r_stones[wh]);
|
||||
else
|
||||
sprintf(prbuf,"A%s %s %s",vowelstr(r_stones[wh]),
|
||||
r_stones[wh], tn);
|
||||
otherwise:
|
||||
sprintf(prbuf,"Something bizarre %s", unctrl(obj->o_type));
|
||||
}
|
||||
if (obj == cur_armor)
|
||||
strcat(prbuf, " (being worn)");
|
||||
if (obj == cur_weapon)
|
||||
strcat(prbuf, " (weapon in hand)");
|
||||
if (obj == cur_ring[LEFT])
|
||||
strcat(prbuf, " (on left hand)");
|
||||
else if (obj == cur_ring[RIGHT])
|
||||
strcat(prbuf, " (on right hand)");
|
||||
if (drop && isupper(prbuf[0]))
|
||||
prbuf[0] = tolower(prbuf[0]);
|
||||
else if (!drop && islower(*prbuf))
|
||||
*prbuf = toupper(*prbuf);
|
||||
if (o_on(obj, ISPROT))
|
||||
strcat(prbuf, " [!]");
|
||||
if (o_on(obj, ISPOST))
|
||||
strcat(prbuf, " [$]");
|
||||
if (knowit) {
|
||||
if (o_on(obj, ISCURSED))
|
||||
strcat(prbuf, " [-]");
|
||||
else if (o_on(obj, ISBLESS))
|
||||
strcat(prbuf, " [+]");
|
||||
}
|
||||
if (!drop)
|
||||
strcat(prbuf, ".");
|
||||
return prbuf;
|
||||
}
|
||||
|
||||
/*
|
||||
* money:
|
||||
* Add to characters purse
|
||||
*/
|
||||
money()
|
||||
{
|
||||
reg struct room *rp;
|
||||
reg struct linked_list *item;
|
||||
reg struct thing *tp;
|
||||
|
||||
rp = player.t_room;
|
||||
if (rp != NULL && ce(hero, rp->r_gold)) {
|
||||
msg("%d gold pieces.", rp->r_goldval);
|
||||
purse += rp->r_goldval;
|
||||
rp->r_goldval = 0;
|
||||
cmov(rp->r_gold);
|
||||
addch(FLOOR);
|
||||
/*
|
||||
* once gold is taken, all monsters will chase him
|
||||
*/
|
||||
for (item = mlist; item != NULL; item = next(item)) {
|
||||
tp = THINGPTR(item);
|
||||
if (rnd(100) < 70 && tp->t_room == rp && !iswearing(R_STEALTH)
|
||||
&& ((tp->t_flags & (ISMEAN | ISGREED)) || rnd(1000) < 20))
|
||||
runto(&tp->t_pos, &hero);
|
||||
}
|
||||
}
|
||||
else
|
||||
msg("That gold must have been counterfeit.");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* drop:
|
||||
* put something down
|
||||
*/
|
||||
drop(item)
|
||||
struct linked_list *item;
|
||||
{
|
||||
reg char ch;
|
||||
reg struct linked_list *ll, *nll;
|
||||
reg struct object *op;
|
||||
|
||||
if (item == NULL) {
|
||||
ch = mvinch(hero.y, hero.x);
|
||||
if (ch != FLOOR && ch != PASSAGE && ch != POOL) {
|
||||
msg("There is something there already.");
|
||||
after = FALSE;
|
||||
return SOMTHERE;
|
||||
}
|
||||
if ((ll = get_item("drop", 0)) == NULL)
|
||||
return FALSE;
|
||||
}
|
||||
else {
|
||||
ll = item;
|
||||
}
|
||||
op = OBJPTR(ll);
|
||||
if (!dropcheck(op))
|
||||
return CANTDROP;
|
||||
/*
|
||||
* Take it out of the pack
|
||||
*/
|
||||
if (op->o_count >= 2 && op->o_type != WEAPON) {
|
||||
nll = new_item(sizeof *op);
|
||||
op->o_count--;
|
||||
op->o_vol = itemvol(op);
|
||||
op = OBJPTR(nll);
|
||||
*op = *(OBJPTR(ll));
|
||||
op->o_count = 1;
|
||||
op->o_vol = itemvol(op);
|
||||
ll = nll;
|
||||
}
|
||||
else {
|
||||
detach(pack, ll);
|
||||
}
|
||||
if (ch == POOL) {
|
||||
msg("%s sinks out of sight.",inv_name(op, TRUE));
|
||||
discard(ll);
|
||||
}
|
||||
else { /* put on dungeon floor */
|
||||
if (levtype == POSTLEV) {
|
||||
op->o_pos = hero; /* same place as hero */
|
||||
fall(ll,FALSE);
|
||||
if (item == NULL) /* if item wasn't sold */
|
||||
msg("Thanks for your donation to the Fiend's flea market.");
|
||||
}
|
||||
else {
|
||||
attach(lvl_obj, ll);
|
||||
mvaddch(hero.y, hero.x, op->o_type);
|
||||
op->o_pos = hero;
|
||||
msg("Dropped %s", inv_name(op, TRUE));
|
||||
}
|
||||
}
|
||||
updpack(); /* new pack weight */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* dropcheck:
|
||||
* Do special checks for dropping or unweilding|unwearing|unringing
|
||||
*/
|
||||
dropcheck(op)
|
||||
struct object *op;
|
||||
{
|
||||
if (op == NULL)
|
||||
return TRUE;
|
||||
if (levtype == POSTLEV) {
|
||||
if (o_on(op,ISCURSED) && o_on(op,ISKNOW)) {
|
||||
msg("The trader does not accept shoddy merchandise.");
|
||||
return FALSE;
|
||||
}
|
||||
else {
|
||||
cur_null(op); /* update cur_weapon, etc */
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
if (op != cur_armor && op != cur_weapon
|
||||
&& op != cur_ring[LEFT] && op != cur_ring[RIGHT])
|
||||
return TRUE;
|
||||
if (o_on(op,ISCURSED)) {
|
||||
msg("You can't. It appears to be cursed.");
|
||||
return FALSE;
|
||||
}
|
||||
if (op == cur_weapon)
|
||||
cur_weapon = NULL;
|
||||
else if (op == cur_armor) {
|
||||
waste_time();
|
||||
cur_armor = NULL;
|
||||
}
|
||||
else if (op == cur_ring[LEFT] || op == cur_ring[RIGHT])
|
||||
toss_ring(op);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* new_thing:
|
||||
* Return a new thing
|
||||
*/
|
||||
struct linked_list *
|
||||
new_thing(treas, type, which)
|
||||
int type, which;
|
||||
bool treas;
|
||||
{
|
||||
struct linked_list *item;
|
||||
struct magic_item *mi;
|
||||
struct object *cur;
|
||||
int chance, whi;
|
||||
|
||||
item = new_item(sizeof *cur);
|
||||
cur = OBJPTR(item);
|
||||
basic_init(cur);
|
||||
if (type == DONTCARE) {
|
||||
if (++no_food > 4 && !treas)
|
||||
whi = TYP_FOOD;
|
||||
else
|
||||
whi = pick_one(things);
|
||||
}
|
||||
else {
|
||||
whi = getindex(type);
|
||||
}
|
||||
mi = thnginfo[whi].mf_magic;
|
||||
if (which == DONTCARE) {
|
||||
which = 0;
|
||||
if (mi != NULL)
|
||||
which = pick_one(mi);
|
||||
}
|
||||
cur->o_typname = things[whi].mi_name;
|
||||
cur->o_weight = things[whi].mi_wght;
|
||||
switch (whi) {
|
||||
case TYP_AMULET:
|
||||
cur->o_type = AMULET;
|
||||
cur->o_hplus = 500;
|
||||
strcpy(cur->o_hurldmg,"80d8"); /* if thrown, WOW!!! */
|
||||
cur->o_vol = itemvol(cur);
|
||||
when TYP_POTION:
|
||||
cur->o_type = POTION;
|
||||
cur->o_which = which;
|
||||
cur->o_count += extras();
|
||||
cur->o_vol = itemvol(cur);
|
||||
when TYP_SCROLL:
|
||||
cur->o_type = SCROLL;
|
||||
cur->o_which = which;
|
||||
cur->o_count += extras();
|
||||
cur->o_vol = itemvol(cur);
|
||||
when TYP_FOOD:
|
||||
no_food = 0;
|
||||
initfood(cur);
|
||||
when TYP_WEAPON:
|
||||
cur->o_which = which;
|
||||
init_weapon(cur, which);
|
||||
if ((chance = rnd(100)) < 10) {
|
||||
setoflg(cur,ISCURSED);
|
||||
cur->o_hplus -= rnd(3)+1;
|
||||
cur->o_dplus -= rnd(3)+1;
|
||||
}
|
||||
else if (chance < 15) {
|
||||
cur->o_hplus += rnd(3)+1;
|
||||
cur->o_dplus += rnd(3)+1;
|
||||
}
|
||||
when TYP_ARMOR:
|
||||
cur->o_which = which;
|
||||
initarmor(cur, which);
|
||||
if ((chance = rnd(100)) < 20) {
|
||||
setoflg(cur,ISCURSED);
|
||||
cur->o_ac += rnd(3)+1;
|
||||
}
|
||||
else if (chance < 30)
|
||||
cur->o_ac -= rnd(3)+1;
|
||||
when TYP_RING:
|
||||
cur->o_which = which;
|
||||
init_ring(cur, FALSE);
|
||||
when TYP_STICK:
|
||||
default:
|
||||
cur->o_which = which;
|
||||
fix_stick(cur);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
/*
|
||||
* basic_init:
|
||||
* Set all params of an object to the basic values.
|
||||
*/
|
||||
basic_init(cur)
|
||||
struct object *cur;
|
||||
{
|
||||
cur->o_ac = 11;
|
||||
cur->o_count = 1;
|
||||
cur->o_launch = 0;
|
||||
cur->o_typname = NULL;
|
||||
cur->o_group = newgrp();
|
||||
cur->o_weight = cur->o_vol = 0;
|
||||
cur->o_hplus = cur->o_dplus = 0;
|
||||
strcpy(cur->o_damage,"0d0");
|
||||
strcpy(cur->o_hurldmg,"0d0");
|
||||
cur->o_flags = cur->o_type = cur->o_which = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* pick_one:
|
||||
* Pick an item out of a list of nitems possible magic items
|
||||
*/
|
||||
pick_one(mag)
|
||||
struct magic_item *mag;
|
||||
{
|
||||
reg struct magic_item *start;
|
||||
reg int i;
|
||||
|
||||
start = mag;
|
||||
for (i = rnd(1000); mag->mi_name != NULL; mag++) {
|
||||
if (i < mag->mi_prob)
|
||||
break;
|
||||
if (mag->mi_name == NULL) {
|
||||
if (author() || wizard) {
|
||||
for (mag = start; mag->mi_name != NULL; mag++)
|
||||
msg("%s: %d%%", mag->mi_name, mag->mi_prob);
|
||||
}
|
||||
mag = start;
|
||||
}
|
||||
}
|
||||
return mag - start;
|
||||
}
|
||||
497
srogue/trader.c
Normal file
497
srogue/trader.c
Normal file
|
|
@ -0,0 +1,497 @@
|
|||
/*
|
||||
* Anything to do with trading posts & mazes
|
||||
*
|
||||
* @(#)trader.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* 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 "rogue.h"
|
||||
#include "rogue.ext"
|
||||
|
||||
#define NOTPRICED -1
|
||||
|
||||
/*
|
||||
* do_post:
|
||||
* Put a trading post room and stuff on the screen
|
||||
*/
|
||||
do_post()
|
||||
{
|
||||
struct coord tp;
|
||||
reg int i;
|
||||
reg struct room *rp;
|
||||
reg struct object *op;
|
||||
reg struct linked_list *ll;
|
||||
|
||||
free_list(lvl_obj); /* throw old items away */
|
||||
|
||||
for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) {
|
||||
rp->r_goldval = 0; /* no gold */
|
||||
rp->r_nexits = 0; /* no exits */
|
||||
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(FALSE, ANYTHING); /* get something */
|
||||
attach(lvl_obj, ll);
|
||||
op = OBJPTR(ll);
|
||||
setoflg(op, ISPOST); /* object in trading post */
|
||||
tp = *rnd_pos(rp);
|
||||
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();
|
||||
}
|
||||
|
||||
/*
|
||||
* price_it:
|
||||
* Price the object that the hero stands on
|
||||
*/
|
||||
price_it()
|
||||
{
|
||||
static char *bargain[] = {
|
||||
"great bargain",
|
||||
"quality product",
|
||||
"exceptional find",
|
||||
};
|
||||
reg struct linked_list *item;
|
||||
reg struct object *obj;
|
||||
reg int worth;
|
||||
|
||||
if (!open_market()) /* after buying hours */
|
||||
return FALSE;
|
||||
if ((item = find_obj(hero.y,hero.x)) == NULL)
|
||||
return FALSE;
|
||||
obj = OBJPTR(item);
|
||||
if (curprice == NOTPRICED) {
|
||||
worth = get_worth(obj);
|
||||
worth += 50 - rnd(100);
|
||||
if (worth < 25)
|
||||
worth = 25;
|
||||
worth *= 3; /* slightly expensive */
|
||||
curprice = worth; /* save price */
|
||||
strcpy(curpurch, obj->o_typname); /* save item */
|
||||
}
|
||||
msg("That %s is a %s for only %d pieces of gold", curpurch,
|
||||
bargain[rnd(3)], curprice);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* buy_it:
|
||||
* Buy the item on which the hero stands
|
||||
*/
|
||||
buy_it()
|
||||
{
|
||||
reg int wh;
|
||||
|
||||
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 = readchar();
|
||||
if (isupper(wh))
|
||||
wh = tolower(wh);
|
||||
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
|
||||
*/
|
||||
mpos = 0;
|
||||
wh = add_pack(NULL,FALSE); /* try to put it in his pack */
|
||||
if (wh) { /* he could get it */
|
||||
purse -= curprice; /* take his money */
|
||||
++trader; /* another transaction */
|
||||
trans_line(); /* show remaining deals */
|
||||
curprice = NOTPRICED;
|
||||
curpurch[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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("sell",0)) == NULL)
|
||||
return;
|
||||
obj = OBJPTR(item);
|
||||
wo = get_worth(obj);
|
||||
if (wo <= 0) {
|
||||
mpos = 0;
|
||||
msg("We don't buy those.");
|
||||
return;
|
||||
}
|
||||
if (wo < 25)
|
||||
wo = 25;
|
||||
msg("Your %s is worth %d pieces of gold.", obj->o_typname, wo);
|
||||
msg("Do you want to sell it? ");
|
||||
do {
|
||||
ch = readchar();
|
||||
if (isupper(ch))
|
||||
ch = tolower(ch);
|
||||
if (ch == ESCAPE || ch == 'n') {
|
||||
msg("");
|
||||
return;
|
||||
}
|
||||
} until (ch == 'y');
|
||||
mpos = 0;
|
||||
if (drop(item) == TRUE) { /* drop this item */
|
||||
nochange = FALSE; /* show gold value */
|
||||
purse += wo; /* give him his money */
|
||||
++trader; /* another transaction */
|
||||
wo = obj->o_count;
|
||||
obj->o_count = 1;
|
||||
msg("Sold %s",inv_name(obj,TRUE));
|
||||
obj->o_count = wo;
|
||||
trans_line(); /* show remaining deals */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* open_market:
|
||||
* Retruns TRUE when ok do to transacting
|
||||
*/
|
||||
open_market()
|
||||
{
|
||||
if (trader >= MAXPURCH) {
|
||||
msg("The market is closed. The stairs are that-a-way.");
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* get_worth:
|
||||
* Calculate an objects worth in gold
|
||||
*/
|
||||
get_worth(obj)
|
||||
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 = w_magic[wh].mi_worth;
|
||||
worth *= (2 + (4 * obj->o_hplus + 4 * obj->o_dplus));
|
||||
}
|
||||
when ARMOR:
|
||||
if (wh < MAXARMORS) {
|
||||
worth = a_magic[wh].mi_worth;
|
||||
worth *= (1 + (10 * (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;
|
||||
if (magring(obj)) {
|
||||
if (obj->o_ac > 0)
|
||||
worth += obj->o_ac * 40;
|
||||
else
|
||||
worth = 50;
|
||||
}
|
||||
}
|
||||
when STICK:
|
||||
if (wh < MAXSTICKS) {
|
||||
worth = ws_magic[wh].mi_worth;
|
||||
worth += 20 * obj->o_charges;
|
||||
}
|
||||
when AMULET:
|
||||
worth = 1000;
|
||||
otherwise:
|
||||
worth = 0;
|
||||
}
|
||||
if (worth < 0)
|
||||
worth = 0;
|
||||
if (o_on(obj, ISPROT)) /* 300% more for protected */
|
||||
worth *= 3;
|
||||
if (o_on(obj, ISBLESS)) /* 50% more for blessed */
|
||||
worth = worth * 3 / 2;
|
||||
return worth;
|
||||
}
|
||||
|
||||
/*
|
||||
* trans_line:
|
||||
* Show how many transactions the hero has left
|
||||
*/
|
||||
trans_line()
|
||||
{
|
||||
sprintf(prbuf,"You have %d transactions remaining.",MAXPURCH-trader);
|
||||
mvwaddstr(cw, LINES - 4, 0, prbuf);
|
||||
}
|
||||
|
||||
/*
|
||||
* domaze:
|
||||
* Draw the maze on this level.
|
||||
*/
|
||||
do_maze()
|
||||
{
|
||||
struct coord tp;
|
||||
reg int i, least;
|
||||
reg struct room *rp;
|
||||
bool treas;
|
||||
|
||||
for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) {
|
||||
rp->r_goldval = 0;
|
||||
rp->r_nexits = 0; /* no exits */
|
||||
rp->r_flags = ISGONE; /* kill all rooms */
|
||||
}
|
||||
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 - 2;
|
||||
rp->r_goldval = 500 + (rnd(10) + 1) * GOLDCALC;
|
||||
draw_maze(); /* put maze into window */
|
||||
rp->r_gold = *rnd_pos(rp);
|
||||
mvaddch(rp->r_gold.y, rp->r_gold.x, GOLD);
|
||||
if (rnd(100) < 3) { /* 3% for treasure maze level */
|
||||
treas = TRUE;
|
||||
least = 6;
|
||||
rp->r_flags |= ISTREAS;
|
||||
}
|
||||
else { /* normal maze level */
|
||||
least = 1;
|
||||
treas = FALSE;
|
||||
}
|
||||
for (i = 0; i < level + least; i++)
|
||||
if (treas || rnd(100) < 50) /* put in some little buggers */
|
||||
add_mon(rp, treas);
|
||||
}
|
||||
|
||||
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 */
|
||||
} mborder;
|
||||
|
||||
char *frontier, *bits;
|
||||
char *moffset(), *foffset();
|
||||
int tlines, tcols;
|
||||
|
||||
/*
|
||||
* draw_maze:
|
||||
* Generate and draw the maze on the screen
|
||||
*/
|
||||
draw_maze()
|
||||
{
|
||||
reg int i, j, more;
|
||||
reg char *ptr;
|
||||
|
||||
tlines = (LINES - 3) / 2;
|
||||
tcols = (COLS - 1) / 2;
|
||||
bits = ALLOC((LINES - 3) * (COLS - 1));
|
||||
frontier = ALLOC(tlines * tcols);
|
||||
ptr = frontier;
|
||||
while (ptr < (frontier + (tlines * tcols)))
|
||||
*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 < tlines; i++) {
|
||||
for (j = 0; j < tcols; j++) {
|
||||
do
|
||||
more = findcells(i,j);
|
||||
while(more != 0);
|
||||
}
|
||||
}
|
||||
crankout();
|
||||
FREE(frontier);
|
||||
FREE(bits);
|
||||
}
|
||||
|
||||
/*
|
||||
* moffset:
|
||||
* Calculate memory address for bits
|
||||
*/
|
||||
char *
|
||||
moffset(y, x)
|
||||
int y, x;
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
ptr = bits + (y * (COLS - 1)) + x;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* foffset:
|
||||
* Calculate memory address for frontier
|
||||
*/
|
||||
char *
|
||||
foffset(y, x)
|
||||
int y, x;
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
ptr = frontier + (y * tcols) + x;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* findcells:
|
||||
* Figure out cells to open up
|
||||
*/
|
||||
findcells(y,x)
|
||||
int x, y;
|
||||
{
|
||||
reg int rtpos, i;
|
||||
|
||||
*foffset(y, x) = FALSE;
|
||||
mborder.num_pos = 0;
|
||||
if (y < tlines - 1) { /* look below */
|
||||
if (*foffset(y + 1, x)) {
|
||||
mborder.conn[mborder.num_pos].y_pos = y + 1;
|
||||
mborder.conn[mborder.num_pos].x_pos = x;
|
||||
mborder.num_pos += 1;
|
||||
}
|
||||
}
|
||||
if (y > 0) { /* look above */
|
||||
if (*foffset(y - 1, x)) {
|
||||
mborder.conn[mborder.num_pos].y_pos = y - 1;
|
||||
mborder.conn[mborder.num_pos].x_pos = x;
|
||||
mborder.num_pos += 1;
|
||||
|
||||
}
|
||||
}
|
||||
if (x < tcols - 1) { /* look right */
|
||||
if (*foffset(y, x + 1)) {
|
||||
mborder.conn[mborder.num_pos].y_pos = y;
|
||||
mborder.conn[mborder.num_pos].x_pos = x + 1;
|
||||
mborder.num_pos += 1;
|
||||
}
|
||||
}
|
||||
if (x > 0) { /* look left */
|
||||
if (*foffset(y, x - 1)) {
|
||||
mborder.conn[mborder.num_pos].y_pos = y;
|
||||
mborder.conn[mborder.num_pos].x_pos = x - 1;
|
||||
mborder.num_pos += 1;
|
||||
|
||||
}
|
||||
}
|
||||
if (mborder.num_pos == 0) /* no neighbors available */
|
||||
return 0;
|
||||
else {
|
||||
i = rnd(mborder.num_pos);
|
||||
rtpos = mborder.num_pos - 1;
|
||||
rmwall(mborder.conn[i].y_pos, mborder.conn[i].x_pos, y, x);
|
||||
return rtpos;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* crankout:
|
||||
* Does actual drawing of maze to window
|
||||
*/
|
||||
crankout()
|
||||
{
|
||||
reg int x, y, i;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
16
srogue/vers.c
Normal file
16
srogue/vers.c
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* version number.
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
char version[] = "@(#)vers.c 9.0 (rdk) 7/17/84";
|
||||
char *release = "9.0 RDK 7/17/84";
|
||||
265
srogue/weapons.c
Normal file
265
srogue/weapons.c
Normal file
|
|
@ -0,0 +1,265 @@
|
|||
/*
|
||||
* Functions for dealing with weapons
|
||||
*
|
||||
* @(#)weapons.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include "rogue.h"
|
||||
#include "rogue.ext"
|
||||
|
||||
/*
|
||||
* missile:
|
||||
* Fire a missile in a given direction
|
||||
*/
|
||||
missile(ydelta, xdelta)
|
||||
int ydelta, xdelta;
|
||||
{
|
||||
reg struct object *obj, *nowwield;
|
||||
reg struct linked_list *item, *nitem;
|
||||
|
||||
/*
|
||||
* Get which thing we are hurling
|
||||
*/
|
||||
nowwield = cur_weapon; /* must save current weap */
|
||||
if ((item = get_item("throw", WEAPON)) == NULL)
|
||||
return;
|
||||
obj = OBJPTR(item);
|
||||
if (!dropcheck(obj) || is_current(obj))
|
||||
return;
|
||||
if (obj == nowwield || obj->o_type != WEAPON) {
|
||||
reg int c;
|
||||
|
||||
msg("Do you want to throw that %s? (y or n)",obj->o_typname);
|
||||
do {
|
||||
c = readchar();
|
||||
if (isupper(c))
|
||||
c = tolower(c);
|
||||
if (c == ESCAPE || c == 'n') {
|
||||
msg("");
|
||||
cur_weapon = nowwield;
|
||||
after = FALSE; /* ooops, a mistake */
|
||||
return;
|
||||
}
|
||||
} while (c != 'y'); /* keep looking for good ans */
|
||||
}
|
||||
/*
|
||||
* 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(pack, item);
|
||||
}
|
||||
else {
|
||||
obj->o_count--;
|
||||
obj->o_vol = itemvol(obj);
|
||||
nitem = new_item(sizeof *obj);
|
||||
obj = OBJPTR(nitem);
|
||||
*obj = *(OBJPTR(item));
|
||||
obj->o_count = 1;
|
||||
obj->o_vol = itemvol(obj);
|
||||
item = nitem;
|
||||
}
|
||||
updpack(); /* new pack weight */
|
||||
do_motion(obj, ydelta, xdelta);
|
||||
if (!isalpha(mvwinch(mw, obj->o_pos.y, obj->o_pos.x))
|
||||
|| !hit_monster(&obj->o_pos, obj))
|
||||
fall(item, TRUE);
|
||||
mvwaddch(cw, hero.y, hero.x, PLAYER);
|
||||
}
|
||||
|
||||
/*
|
||||
* do the actual motion on the screen done by an object traveling
|
||||
* across the room
|
||||
*/
|
||||
do_motion(obj, ydelta, xdelta)
|
||||
struct object *obj;
|
||||
int ydelta, xdelta;
|
||||
{
|
||||
reg int ch, y, x;
|
||||
|
||||
obj->o_pos = hero;
|
||||
while (1) {
|
||||
y = obj->o_pos.y;
|
||||
x = obj->o_pos.x;
|
||||
if (!ce(obj->o_pos, hero) && cansee(unc(obj->o_pos)) &&
|
||||
mvwinch(cw, y, x) != ' ')
|
||||
mvwaddch(cw, y, x, show(y, x));
|
||||
/*
|
||||
* Get the new position
|
||||
*/
|
||||
obj->o_pos.y += ydelta;
|
||||
obj->o_pos.x += xdelta;
|
||||
y = obj->o_pos.y;
|
||||
x = obj->o_pos.x;
|
||||
ch = winat(y, x);
|
||||
if (step_ok(ch) && ch != DOOR) {
|
||||
if (cansee(unc(obj->o_pos)) && mvwinch(cw, y, x) != ' ') {
|
||||
mvwaddch(cw, y, x, obj->o_type);
|
||||
draw(cw);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* fall:
|
||||
* Drop an item someplace around here.
|
||||
*/
|
||||
|
||||
fall(item, pr)
|
||||
struct linked_list *item;
|
||||
bool pr;
|
||||
{
|
||||
reg struct object *obj;
|
||||
reg struct room *rp;
|
||||
static struct coord fpos;
|
||||
|
||||
obj = OBJPTR(item);
|
||||
if (fallpos(&obj->o_pos, &fpos, TRUE)) {
|
||||
mvaddch(fpos.y, fpos.x, obj->o_type);
|
||||
obj->o_pos = fpos;
|
||||
rp = player.t_room;
|
||||
if (rp != NULL && !rf_on(rp,ISDARK)) {
|
||||
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("Your %s vanishes as it hits the ground.", w_magic[obj->o_which].mi_name);
|
||||
else
|
||||
msg("%s vanishes as it hits the ground.", inv_name(obj,TRUE));
|
||||
|
||||
discard(item);
|
||||
}
|
||||
|
||||
/*
|
||||
* init_weapon:
|
||||
* Set up the initial goodies for a weapon
|
||||
*/
|
||||
|
||||
init_weapon(weap, type)
|
||||
struct object *weap;
|
||||
int type;
|
||||
{
|
||||
reg struct init_weps *iwp;
|
||||
|
||||
weap->o_type = WEAPON;
|
||||
weap->o_which = type;
|
||||
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;
|
||||
weap->o_typname = things[TYP_WEAPON].mi_name;
|
||||
if (o_on(weap,ISMANY))
|
||||
weap->o_count = rnd(8) + 8;
|
||||
else
|
||||
weap->o_count = 1;
|
||||
weap->o_group = newgrp();
|
||||
weap->o_vol = itemvol(weap);
|
||||
}
|
||||
|
||||
/*
|
||||
* hit_monster:
|
||||
* Does the missile hit the monster
|
||||
*/
|
||||
hit_monster(mp, obj)
|
||||
struct coord *mp;
|
||||
struct object *obj;
|
||||
{
|
||||
return fight(mp, obj, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* num:
|
||||
* Figure out the plus number for armor/weapons
|
||||
*/
|
||||
char *
|
||||
num(n1, n2)
|
||||
int n1, n2;
|
||||
{
|
||||
static char numbuf[LINLEN];
|
||||
|
||||
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()
|
||||
{
|
||||
reg struct linked_list *item;
|
||||
reg struct object *obj, *oweapon;
|
||||
|
||||
oweapon = cur_weapon;
|
||||
if (!dropcheck(cur_weapon)) {
|
||||
cur_weapon = oweapon;
|
||||
return;
|
||||
}
|
||||
cur_weapon = oweapon;
|
||||
if ((item = get_item("wield", WEAPON)) == NULL)
|
||||
return;
|
||||
obj = OBJPTR(item);
|
||||
if (is_current(obj)) {
|
||||
after = FALSE;
|
||||
return;
|
||||
}
|
||||
msg("Wielding %s", inv_name(obj, TRUE));
|
||||
cur_weapon = obj;
|
||||
}
|
||||
|
||||
/*
|
||||
* fallpos:
|
||||
* Pick a random position around the give (y, x) coordinates
|
||||
*/
|
||||
fallpos(pos, newpos, passages)
|
||||
struct coord *pos, *newpos;
|
||||
bool passages;
|
||||
{
|
||||
reg int y, x, ch;
|
||||
|
||||
for (y = pos->y - 1; y <= pos->y + 1; y++) {
|
||||
for (x = pos->x - 1; x <= pos->x + 1; x++) {
|
||||
/*
|
||||
* check to make certain the spot is empty, if it is,
|
||||
* put the object there, set it in the level list
|
||||
* and re-draw the room if he can see it
|
||||
*/
|
||||
if (y == hero.y && x == hero.x)
|
||||
continue;
|
||||
ch = winat(y, x);
|
||||
if (ch == FLOOR || (passages && ch == PASSAGE)) {
|
||||
newpos->y = y;
|
||||
newpos->x = x;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
369
srogue/wizard.c
Normal file
369
srogue/wizard.c
Normal file
|
|
@ -0,0 +1,369 @@
|
|||
/*
|
||||
* Mostly wizard commands. Sometimes used by players.
|
||||
*
|
||||
* @(#)wizard.c 9.0 (rdk) 7/17/84
|
||||
*
|
||||
* Super-Rogue
|
||||
* Copyright (C) 1984 Robert D. Kindelberger
|
||||
* All rights reserved.
|
||||
*
|
||||
* Based on "Rogue: Exploring the Dungeons of Doom"
|
||||
* Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
|
||||
* All rights reserved.
|
||||
*
|
||||
* See the file LICENSE.TXT for full copyright and licensing information.
|
||||
*/
|
||||
|
||||
#include <termios.h>
|
||||
#include <ctype.h>
|
||||
#include "rogue.h"
|
||||
#include <pwd.h>
|
||||
#include "rogue.ext"
|
||||
|
||||
extern struct termios terminal;
|
||||
|
||||
/*
|
||||
* whatis:
|
||||
* What a certain object is
|
||||
*/
|
||||
whatis(what)
|
||||
struct linked_list *what;
|
||||
{
|
||||
reg struct object *obj;
|
||||
reg struct linked_list *item;
|
||||
reg int wh;
|
||||
|
||||
if (what == NULL) { /* we need to ask */
|
||||
if ((item = get_item("identify", 0)) == NULL)
|
||||
return;
|
||||
}
|
||||
else /* no need to ask */
|
||||
item = what;
|
||||
obj = OBJPTR(item);
|
||||
setoflg(obj, ISKNOW);
|
||||
wh = obj->o_which;
|
||||
switch (obj->o_type) {
|
||||
case SCROLL:
|
||||
s_know[wh] = TRUE;
|
||||
if (s_guess[wh]) {
|
||||
free(s_guess[wh]);
|
||||
s_guess[wh] = NULL;
|
||||
}
|
||||
when POTION:
|
||||
p_know[wh] = TRUE;
|
||||
if (p_guess[wh]) {
|
||||
free(p_guess[wh]);
|
||||
p_guess[wh] = NULL;
|
||||
}
|
||||
when STICK:
|
||||
ws_know[wh] = TRUE;
|
||||
if (ws_guess[wh]) {
|
||||
free(ws_guess[wh]);
|
||||
ws_guess[wh] = NULL;
|
||||
}
|
||||
when RING:
|
||||
r_know[wh] = TRUE;
|
||||
if (r_guess[wh]) {
|
||||
free(r_guess[wh]);
|
||||
r_guess[wh] = NULL;
|
||||
}
|
||||
}
|
||||
if (what == NULL)
|
||||
msg(inv_name(obj, FALSE));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* create_obj:
|
||||
* Create any object for wizard or scroll (almost)
|
||||
*/
|
||||
create_obj(fscr)
|
||||
bool fscr;
|
||||
{
|
||||
reg struct linked_list *item;
|
||||
reg struct object *obj;
|
||||
reg int wh, ch, otype;
|
||||
char newitem, newtype, msz, *oname;
|
||||
struct magic_info *mf;
|
||||
bool nogood = TRUE, inhw = FALSE;
|
||||
|
||||
if (fscr)
|
||||
msg(" ");
|
||||
else if (wizard) {
|
||||
msg("Create what?%s: ", starlist);
|
||||
ch = readchar();
|
||||
mpos = 0;
|
||||
if (ch == ESCAPE)
|
||||
return;
|
||||
else if (ch != '*')
|
||||
nogood = FALSE;
|
||||
}
|
||||
if (nogood) {
|
||||
inhw = TRUE;
|
||||
wclear(hw);
|
||||
wprintw(hw,"Item\tKey\n\n");
|
||||
for (otype = 0; otype < NUMTHINGS; otype++) {
|
||||
if (otype != TYP_AMULET || wizard) {
|
||||
mf = &thnginfo[otype];
|
||||
wprintw(hw,"%s\t %c\n",things[otype].mi_name,mf->mf_show);
|
||||
}
|
||||
}
|
||||
if (wizard)
|
||||
waddstr(hw,"monster\t (A-z)");
|
||||
wprintw(hw,"\n\nWhat do you want to create? ");
|
||||
draw(hw);
|
||||
do {
|
||||
ch = readchar();
|
||||
if (ch == ESCAPE) {
|
||||
after = FALSE;
|
||||
restscr(cw);
|
||||
return;
|
||||
}
|
||||
switch (ch) {
|
||||
case RING: case STICK: case POTION:
|
||||
case SCROLL: case ARMOR: case WEAPON:
|
||||
case FOOD: case AMULET:
|
||||
nogood = FALSE;
|
||||
break;
|
||||
default:
|
||||
if (isalpha(ch))
|
||||
nogood = FALSE;
|
||||
}
|
||||
} while (nogood);
|
||||
}
|
||||
if (isalpha(ch)) {
|
||||
if (inhw)
|
||||
restscr(cw);
|
||||
makemons(ch); /* make monster & be done with it */
|
||||
return;
|
||||
}
|
||||
otype = getindex(ch);
|
||||
if (otype == -1 || (otype == AMULET && !wizard)) {
|
||||
if (inhw)
|
||||
restscr(cw);
|
||||
mpos = 0;
|
||||
msg("You can't create that !!");
|
||||
return;
|
||||
}
|
||||
newitem = ch;
|
||||
mf = &thnginfo[otype];
|
||||
oname = things[otype].mi_name;
|
||||
msz = mf->mf_max;
|
||||
nogood = TRUE;
|
||||
if (msz == 1) { /* if only one type of item */
|
||||
ch = 'a';
|
||||
nogood = FALSE;
|
||||
}
|
||||
else if (!fscr && wizard) {
|
||||
if (!inhw) {
|
||||
msg("Which %s?%s: ", oname, starlist);
|
||||
ch = readchar();
|
||||
if (ch == ESCAPE)
|
||||
return;
|
||||
if (ch != '*')
|
||||
nogood = FALSE;
|
||||
}
|
||||
}
|
||||
if (nogood) {
|
||||
struct magic_item *wmi;
|
||||
int ii;
|
||||
|
||||
mpos = 0;
|
||||
inhw = TRUE;
|
||||
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 WEAPON: wmi = &w_magic[0];
|
||||
otherwise: wmi = &a_magic[0];
|
||||
}
|
||||
wclear(hw);
|
||||
for (ii = 0 ; ii < msz ; ii++) {
|
||||
mvwaddch(hw,ii % 13,ii > 12 ? COLS/2 : 0, ii + 'a');
|
||||
waddstr(hw,") ");
|
||||
waddstr(hw,wmi->mi_name);
|
||||
wmi++;
|
||||
}
|
||||
sprintf(prbuf,"Which %s? ", oname);
|
||||
mvwaddstr(hw,LINES - 1, 0, prbuf);
|
||||
draw(hw);
|
||||
do {
|
||||
ch = readchar();
|
||||
if (ch == ESCAPE) {
|
||||
restscr(cw);
|
||||
msg("");
|
||||
return;
|
||||
}
|
||||
} while (!isalpha(ch));
|
||||
}
|
||||
if (inhw) /* restore screen if need be */
|
||||
restscr(cw);
|
||||
|
||||
newtype = tolower(ch) - 'a';
|
||||
if (newtype < 0 || newtype >= msz) { /* if an illegal value */
|
||||
mpos = 0;
|
||||
after = FALSE;
|
||||
if (inhw)
|
||||
restscr(cw);
|
||||
msg("There is no such %s", oname);
|
||||
return;
|
||||
}
|
||||
mpos = 0;
|
||||
item = new_thing(FALSE, newitem, newtype);
|
||||
obj = OBJPTR(item);
|
||||
wh = obj->o_type;
|
||||
if (wh == WEAPON || wh == ARMOR || wh == RING) {
|
||||
if (fscr) /* users get +3 to -3 */
|
||||
ch = rnd(7) - 3;
|
||||
else { /* wizard gets to choose */
|
||||
if (wh == RING)
|
||||
init_ring(obj, TRUE);
|
||||
else
|
||||
ch = getbless();
|
||||
}
|
||||
if (wh == WEAPON)
|
||||
obj->o_hplus = obj->o_dplus = ch;
|
||||
else if (wh == ARMOR)
|
||||
obj->o_ac = armors[obj->o_which].a_class - ch;
|
||||
if (ch < 0)
|
||||
setoflg(obj, ISCURSED);
|
||||
else
|
||||
resoflg(obj, ISCURSED);
|
||||
}
|
||||
mpos = 0;
|
||||
if (fscr)
|
||||
whatis(item); /* identify for aquirement scroll */
|
||||
wh = add_pack(item, FALSE);
|
||||
if (wh == FALSE) /* won't fit in pack */
|
||||
discard(item);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* getbless:
|
||||
* Get a blessing for a wizards object
|
||||
*/
|
||||
getbless()
|
||||
{
|
||||
int bless;
|
||||
|
||||
msg("Blessing: ");
|
||||
prbuf[0] = '\0';
|
||||
bless = get_str(prbuf, cw);
|
||||
if (bless == NORM)
|
||||
bless = atoi(prbuf);
|
||||
else
|
||||
bless = 0;
|
||||
return bless;
|
||||
}
|
||||
|
||||
/*
|
||||
* makemons:
|
||||
* Make a monster
|
||||
*/
|
||||
makemons(what)
|
||||
int what;
|
||||
{
|
||||
reg int x, y, oktomake = FALSE, appear = 1;
|
||||
struct coord mp;
|
||||
|
||||
oktomake = FALSE;
|
||||
for (x = hero.x - 1 ; x <= hero.x + 1 ; x++) {
|
||||
for (y = hero.y - 1 ; y <= hero.y + 1 ; y++) {
|
||||
if (x != hero.x || y != hero.y) {
|
||||
if (step_ok(winat(y, x)) && rnd(++appear) == 0) {
|
||||
mp.x = x;
|
||||
mp.y = y;
|
||||
oktomake = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (oktomake) {
|
||||
new_monster(midx(what), &mp, FALSE);
|
||||
look(FALSE);
|
||||
}
|
||||
return oktomake;
|
||||
}
|
||||
|
||||
/*
|
||||
* telport:
|
||||
* Bamf the thing someplace else
|
||||
*/
|
||||
teleport(spot, th)
|
||||
struct coord spot;
|
||||
struct thing *th;
|
||||
{
|
||||
reg int rm, y, x;
|
||||
struct coord oldspot;
|
||||
struct room *rp;
|
||||
bool ishero;
|
||||
|
||||
ishero = (th == &player);
|
||||
oldspot = th->t_pos;
|
||||
y = th->t_pos.y;
|
||||
x = th->t_pos.x;
|
||||
mvwaddch(cw, y, x, th->t_oldch);
|
||||
if (!ishero)
|
||||
mvwaddch(mw, y, x, ' ');
|
||||
rp = roomin(&spot);
|
||||
if (spot.y < 0 || !step_ok(winat(spot.y, spot.x))) {
|
||||
rp = &rooms[rnd_room()];
|
||||
th->t_pos = *rnd_pos(rp);
|
||||
}
|
||||
else
|
||||
th->t_pos = spot;
|
||||
rm = rp - &rooms[0];
|
||||
th->t_room = rp;
|
||||
th->t_oldch = mvwinch(cw, th->t_pos.y, th->t_pos.x);
|
||||
light(&oldspot);
|
||||
th->t_nomove = 0;
|
||||
if (ishero) {
|
||||
light(&hero);
|
||||
mvwaddch(cw, hero.y, hero.x, PLAYER);
|
||||
/*
|
||||
* turn off ISHELD in case teleportation was done
|
||||
* while fighting a Fungi or Bone Devil.
|
||||
*/
|
||||
if (pl_on(ISHELD))
|
||||
unhold('F');
|
||||
count = 0;
|
||||
running = FALSE;
|
||||
flushinp(); /* flush typeahead */
|
||||
nochange = FALSE;
|
||||
}
|
||||
else
|
||||
mvwaddch(mw, th->t_pos.y, th->t_pos.x, th->t_type);
|
||||
return rm;
|
||||
}
|
||||
|
||||
/*
|
||||
* passwd:
|
||||
* See if user knows password
|
||||
*/
|
||||
passwd()
|
||||
{
|
||||
reg char *sp, c;
|
||||
bool passok;
|
||||
char buf[LINLEN], *xcrypt();
|
||||
|
||||
msg(wizstr);
|
||||
mpos = 0;
|
||||
sp = buf;
|
||||
while ((c = getchar()) != '\n' && c != '\r' && c != ESCAPE)
|
||||
if (c == terminal.c_cc[VKILL])
|
||||
sp = buf;
|
||||
else if (c == terminal.c_cc[VERASE] && sp > buf)
|
||||
sp--;
|
||||
else
|
||||
*sp++ = c;
|
||||
if (sp == buf)
|
||||
passok = FALSE;
|
||||
else {
|
||||
*sp = '\0';
|
||||
passok = (strcmp(PASSWD, xcrypt(buf, "mT")) == 0);
|
||||
}
|
||||
return passok;
|
||||
}
|
||||
696
srogue/xcrypt.c
Normal file
696
srogue/xcrypt.c
Normal file
|
|
@ -0,0 +1,696 @@
|
|||
/*
|
||||
* 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 <sys/param.h>
|
||||
#include <pwd.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 = ntohl(*(unsigned int *) key);
|
||||
rawkey1 = 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, 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 = ntohl(x[0]);
|
||||
rawr = ntohl(x[1]);
|
||||
retval = do_des(rawl, rawr, &l_out, &r_out, count);
|
||||
|
||||
x[0] = htonl(l_out);
|
||||
x[1] = 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