# HG changeset patch # User elwin # Date 1290687701 0 # Node ID 2128c7dc8a400686fb31035586bd3c6e5fbcfc51 # Parent 05018c63a7211a4aee35d99bb118233f50b24746 Import Super-Rogue 9.0 from the Roguelike Restoration Project (r1490) diff -r 05018c63a721 -r 2128c7dc8a40 srogue/LICENSE.TXT --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/srogue/LICENSE.TXT Thu Nov 25 12:21:41 2010 +0000 @@ -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. diff -r 05018c63a721 -r 2128c7dc8a40 srogue/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/srogue/Makefile Thu Nov 25 12:21:41 2010 +0000 @@ -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 diff -r 05018c63a721 -r 2128c7dc8a40 srogue/armor.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/srogue/armor.c Thu Nov 25 12:21:41 2010 +0000 @@ -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; +} diff -r 05018c63a721 -r 2128c7dc8a40 srogue/bob.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/srogue/bob.h Thu Nov 25 12:21:41 2010 +0000 @@ -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 +typedef struct sgttyb SGTTY; +static SGTTY _tty, _res_flg; + diff -r 05018c63a721 -r 2128c7dc8a40 srogue/bsdtty.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/srogue/bsdtty.c Thu Nov 25 12:21:41 2010 +0000 @@ -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); +} diff -r 05018c63a721 -r 2128c7dc8a40 srogue/chase.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/srogue/chase.c Thu Nov 25 12:21:41 2010 +0000 @@ -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; +} diff -r 05018c63a721 -r 2128c7dc8a40 srogue/command.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/srogue/command.c Thu Nov 25 12:21:41 2010 +0000 @@ -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 +#include +#include +#include "rogue.h" +#include "rogue.ext" +#ifdef __DJGPP__ +#include +#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); + } +} diff -r 05018c63a721 -r 2128c7dc8a40 srogue/cx.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/srogue/cx.h Thu Nov 25 12:21:41 2010 +0000 @@ -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 +#include + +#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(); diff -r 05018c63a721 -r 2128c7dc8a40 srogue/daemon.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/srogue/daemon.c Thu Nov 25 12:21:41 2010 +0000 @@ -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)); +} diff -r 05018c63a721 -r 2128c7dc8a40 srogue/daemons.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/srogue/daemons.c Thu Nov 25 12:21:41 2010 +0000 @@ -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; +} diff -r 05018c63a721 -r 2128c7dc8a40 srogue/disply.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/srogue/disply.c Thu Nov 25 12:21:41 2010 +0000 @@ -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 +#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; +} diff -r 05018c63a721 -r 2128c7dc8a40 srogue/encumb.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/srogue/encumb.c Thu Nov 25 12:21:41 2010 +0000 @@ -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