Import Super-Rogue 9.0 from the Roguelike Restoration Project (r1490)

This commit is contained in:
John "Elwin" Edwards 2010-11-25 12:21:41 +00:00
parent 00669593bd
commit ce4b930551
48 changed files with 17601 additions and 0 deletions

139
srogue/LICENSE.TXT Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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 */