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 */
|
||||