# HG changeset patch # User John "Elwin" Edwards # Date 1487552203 18000 # Node ID 08489644940b808bf490245ffe59b3621b1a93d6 # Parent 7fcb2f9f57e6f7dc574c655f276f8e59de2b3c88# Parent 69ffcb6b90da4e3bbe4fd3fa984141ae3345d24a Merge the UltraRogue branch. diff -r 69ffcb6b90da -r 08489644940b README.txt --- a/README.txt Fri Feb 10 09:06:50 2017 -0500 +++ b/README.txt Sun Feb 19 19:56:43 2017 -0500 @@ -16,6 +16,9 @@ it include Rogue Clone, a reimplementation sometimes found in BSD or Linux distributions. +UltraRogue has recently been added to the collection. It is still in an +experimental state, with several known bugs. + --- Installation To install on Unix (including OS X): @@ -50,6 +53,9 @@ It is recommended to run 'configure' with the '--disable-logfile' option, and 'make' with the 'LDFLAGS=-static' option. +UltraRogue is not yet integrated with Autoconf or the Visual Studio solution +file. + See the individual games' subdirectories for further documentation. Some of the manpages may be outdated, but the guides to playing should be accurate. diff -r 69ffcb6b90da -r 08489644940b urogue/LICENSE.TXT --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/urogue/LICENSE.TXT Sun Feb 19 19:56:43 2017 -0500 @@ -0,0 +1,138 @@ +Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong +Portions Copyright (C) 1985 Michael Morgan, Ken Dalka +Portions Copyright (C) 1981 Michael Toy, Ken Arnold and Glenn Wichman +Portions Copyright (C) 1993, 1995 Nicholas J. Kisseberth +All rights reserved. + +=========================================================================== + +UltaRogue: The Ultimate Adventure in the Dungeons of Doom +Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong +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 "UltraRogue" and "urogue" 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 "UltraRogue" or + "urogue", nor may "UltraRogue" or "urogue" 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 Morgan and +Ken Dalka. Used under license: + +Advanced Rogue +Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka +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 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) 1993, 1995 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. diff -r 69ffcb6b90da -r 08489644940b urogue/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/urogue/Makefile Sun Feb 19 19:56:43 2017 -0500 @@ -0,0 +1,171 @@ +# UltraRogue: The Ultimate Adventure in the Dungeons of Doom +# Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong +# All rights reserved. +# +# See the file LICENSE.TXT for full copyright and licensing information. + +# +# Makefile for urogue +# + +DISTNAME=urogue1.0.7 + +HDRS = dict.h dictutil.h rogue.h +OBJS = armor.o \ + artifact.o \ + bag.o \ + chase.o \ + command.o \ + daemon.o \ + daemons.o \ + dict.o \ + dictutil.o \ + encumb.o \ + fight.o \ + getplay.o \ + ident.o \ + init.o \ + io.o \ + list.o \ + magic.o \ + main.o \ + maze.o \ + mdport.o \ + memory.o \ + misc.o \ + monsdata.o \ + monsters.o \ + move.o \ + newlvl.o \ + options.o \ + pack.o \ + passages.o \ + player.o \ + potions.o \ + random.o \ + rings.o \ + rip.o \ + rooms.o \ + save.o \ + scrolls.o \ + state.o \ + status.o \ + sticks.o \ + things.o \ + trader.o \ + verify.o \ + vers.o \ + weapons.o \ + wizard.o \ + xcrypt.o + +PROGRAM = ur + +CFILES = armor.c \ + artifact.c \ + bag.c \ + chase.c \ + command.c \ + daemon.c \ + daemons.c \ + dict.c \ + dictutil.c \ + encumb.c \ + fight.c \ + getplay.c \ + ident.c \ + init.c \ + io.c \ + list.c \ + magic.c \ + main.c \ + maze.c \ + mdport.c \ + memory.c \ + misc.c \ + monsdata.c \ + monsters.c \ + move.c \ + newlvl.c \ + options.c \ + pack.c \ + passages.c \ + player.c \ + potions.c \ + random.c \ + rings.c \ + rip.c \ + rooms.c \ + save.c \ + scrolls.c \ + state.c \ + status.c \ + sticks.c \ + things.c \ + trader.c \ + verify.c \ + vers.c \ + weapons.c \ + wizard.c \ + xcrypt.c + +MISC= Makefile README LICENSE.TXT history.txt TODO + +CC = gcc +CFLAGS= -O3 +CRLIB = -lcurses +RM = rm -f +TAR = tar + +urogue: $(OBJS) $(MAKEFILE) + $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(CRLIB) -o $@ + +clean: + rm -f $(OBJS) urogue a.out core *.map urogue.exe urogue.cat + +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" urogue + nroff -man urogue.6 | colcrt - > urogue.cat + tar cf $(DISTNAME)-irix.tar urogue urogue.cat README LICENSE.TXT + gzip -f $(DISTNAME)-irix.tar + +dist.aix: + make clean + make CC=xlc CFLAGS="-qmaxmem=16768 -O3 -qstrict" urogue + nroff -man urogue.6 | colcrt - > urogue.cat + tar cf $(DISTNAME)-aix.tar urogue urogue.cat README LICENSE.TXT + gzip -f $(DISTNAME)-aix.tar + +dist.linux: + make clean + make urogue + groff -man urogue.6 | sed -e 's/.\x08//g' > urogue.cat + tar cf $(DISTNAME)-linux.tar urogue urogue.cat README LICENSE.TXT + gzip -f $(DISTNAME)-linux.tar + +dist.interix: + make clean + make urogue + groff -P-b -P-u -man -Tascii urogue.6 > urogue.cat + tar cf $(DISTNAME)-interix.tar urogue urogue.cat README LICENSE.TXT + gzip -f $(DISTNAME)-interix.tar + +dist.cygwin: + make clean + make urogue + groff -P-c -man -Tascii urogue.6 | sed -e 's/.\x08//g' > urogue.cat + tar cf $(DISTNAME)-cygwin.tar urogue.exe urogue.cat README LICENSE.TXT + gzip -f $(DISTNAME)-cygwin.tar + +dist.djgpp: + make clean + make LDFLAGS="-L$(DJDIR)/LIB" CRLIB="-lpdcurses" urogue + groff -man -Tascii urogue.6 | sed -e 's/.\x08//g' > urogue.cat + rm -f $(DISTNAME)-djgpp.zip + zip $(DISTNAME)-djgpp.zip urogue.exe urogue.cat README LICENSE.TXT diff -r 69ffcb6b90da -r 08489644940b urogue/README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/urogue/README Sun Feb 19 19:56:43 2017 -0500 @@ -0,0 +1,74 @@ +UltraRogue: The Ultimate Adventure in the Dungeons of Doom +Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong +All rights reserved. + +There are 8 different treasures to be picked up in this version of rogue. +The first is on level 25 and is relatively easy to pick up. The last is +on level 100 and is very difficult to get. Carrying any one of the +unique treasures allows the rogue to go up the stairs, but one has to +be very careful. To be a total winner, yu must pick up all 8 and +return to the surface again. + +(note: the above may be incorrect, i think the number of levels is +reduced to 50 and you have to get all 8 artifacts to go back up) + +The environment variable UROGUE is used to set up the default things +for a player. The options that can be set are: + +terse: short output messages +flush: flush typeahead when fighting +jump: show position only at the end of running +inven: inventory style +askme: ask about unidentified things +stopdoor: stop running when next to something interesting +name: the rogue's name (string) +fruit: the funny fruit used by the rogue (string) +file: default savefile name (string) +score: default scorefile name (string) +class: default player class (string) + +Something like + +setenv UROGUE "name=George of the Jungle,fruit=peach,noterse,jump" + +does the obvious. The "score" option is ignored unless you start +urogue in wizard mode. The class option string can have the following +values: "fighter", "illus", "paladin", "ranger", "cleric", "magic", +"assasin", "druid", "ninja", and "thief" and is initialized only at +startup time. The "inven" option can take the values "slow", "clear", +and "overwrite". + + +About the Author +================ + +Herb Chong is currently freelance writing and doing some teaching. +If you pick up a copy of Windows Sources Magazine, you can usually +find something he has written. Starting in October (1993) he will +have a regular column. Herb has also just started teaching Adult Ed +and undergraduate classes at Mercy College, a small and not very well +known college in Westchester, NY. + +Acknowledgements +================ + +The source code for Rogue 3.6 (by Michael Toy, Ken Arnold and Glenn +Wichman) was used as the original basis for this game. A thousand +thanks go out to them and their classic adventure game of the early 1980s. + +Modifications of a long forgotten and bastardized nature were taken +from Advanced Rogue 1.0 and/or SuperRogue. We believe that the flea market, +pools, and maze levels had their origin somewhere around here. + +Chief Architect : Herb Chong + +Major Contributers: Carlton Hommel Mike Cooper Mike Laman + Jason Venner Nick Kisseberth + +Other Contributers: Nick Flor Henry Chai Pat Place + Michael Maudlin dan@ciprico edjames@ucbshadow + Web Dove Tim Haapanen tecot@cmu-cs-k.arpa + +Any omissions or errors are purely unintentional. The above list was +compiled by Nick Kisseberth from the change log in UltraRogue through +1987 and from correspondense with Herb Chong. diff -r 69ffcb6b90da -r 08489644940b urogue/TODO --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/urogue/TODO Sun Feb 19 19:56:43 2017 -0500 @@ -0,0 +1,23 @@ +UltraRogue: The Ultimate Adventure in the Dungeons of Doom +Copyright (C) 1993, 1995 Herb Chong +All rights reserved. + +%W% %G% + +add_pack() calls ur_free() on the linked list pointer passed +to it. Need to go through code and look for cases where we +use that pointer after calling add_pack(). Electric +fence in guard-free() mode should help. + +Similary throw_away(), discard(), discard_pack() free items... +there will be more like this... + +Bug in genocide scroll: don't request list, type letter, etc... + +Implement potion of true sight. + +Bug: apparently when creating a new familiar after a player level +change, something isn't begin reset because ur SEGVs when running +through the monster list in do_chase() right after the new +familiar is created. It appears that the familiar isn't being removed +from the monster list. diff -r 69ffcb6b90da -r 08489644940b urogue/armor.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/urogue/armor.c Sun Feb 19 19:56:43 2017 -0500 @@ -0,0 +1,207 @@ +/* + armor.c - functions for dealing with armor + + UltraRogue: The Ultimate Adventure in the Dungeons of Doom + Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong + All rights reserved. + + Based on "Advanced Rogue" + Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka + 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" + +/* + wear() + The player wants to wear something, so let him/her put it on. +*/ + +void +wear(void) +{ + struct object *obj; + + if (cur_armor != NULL) + { + msg("You are already wearing some."); + + after = FALSE; + + return; + } + + /* What does player want to wear? */ + + if ((obj = get_object(pack, "wear", ARMOR, NULL)) == NULL) + return; + + wear_ok(&player, obj, MESSAGE); + waste_time(); + + cur_armor = obj; + obj->o_flags |= ISKNOW; + + msg("You are now wearing %s.", inv_name(obj, TRUE)); + + return; +} + +/* + take_off() + Get the armor off of the players back +*/ + +void +take_off(void) +{ + struct object *obj; + + if ((obj = cur_armor) == NULL) + { + msg("You aren't wearing armor!"); + return; + } + + if (!dropcheck(cur_armor)) + return; + + msg("You were wearing %c%c) %s.", ARMOR, print_letters[get_ident(obj)], + inv_name(obj, LOWERCASE)); + + cur_armor = NULL; + + if (on(player, STUMBLER)) + { + msg("Your foot feels a lot better now."); + turn_off(player, STUMBLER); + } +} + +/* + wear_ok() + enforce player class armor restrictions +*/ + +int +wear_ok(struct thing *wearee, struct object *obj, int print_message) +{ + int which = obj->o_which; + int ret_val = TRUE; + int class_type = wearee->t_ctype; + + if (obj->o_type != ARMOR) + return(FALSE); + else + switch (class_type) + { + case C_MAGICIAN: /* cannot wear metal */ + case C_ILLUSION: + switch (which) + { + case RING_MAIL: + case SCALE_MAIL: + case PADDED_ARMOR: + case CHAIN_MAIL: + case BRIGANDINE: + case SPLINT_MAIL: + case GOOD_CHAIN: + case PLATE_MAIL: + case PLATE_ARMOR: + ret_val = FALSE; + break; + default: + break; + } + + case C_THIEF: /* cannot clank around */ + case C_ASSASIN: + case C_NINJA: + switch (which) + { + case CHAIN_MAIL: + case BRIGANDINE: + case SPLINT_MAIL: + case GOOD_CHAIN: + case PLATE_MAIL: + case PLATE_ARMOR: + ret_val = FALSE; + break; + default: + break; + } + + case C_CLERIC: /* cannot wear plate */ + case C_DRUID: + switch (which) + { + case PLATE_MAIL: + case PLATE_ARMOR: + case MITHRIL: + ret_val = FALSE; + break; + default: + break; + } + + case C_FIGHTER: /* wear anything */ + case C_RANGER: + break; + + case C_PALADIN: /* cannot wear common stuff */ + switch (which) + { + case SOFT_LEATHER: + case CUIRBOLILLI: + case HEAVY_LEATHER: + case STUDDED_LEATHER: + case PADDED_ARMOR: + case BRIGANDINE: + ret_val = FALSE; + break; + default: + break; + } + + case C_MONSTER: + break; + + default: /* Unknown class */ + debug("Unknown class %d.", class_type); + break; + } + + if (ret_val == FALSE && print_message == MESSAGE) + switch (class_type) + { + case C_MAGICIAN: + case C_ILLUSION: + msg("You cannot regenerate spell points while wearing that!"); + break; + + case C_THIEF: + case C_ASSASIN: + case C_NINJA: + msg("Don't expect to be stealthy while wearing that!"); + break; + + case C_CLERIC: + case C_DRUID: + case C_PALADIN: + msg("Your god strongly disapproves of your wearing that!"); + break; + + case C_FIGHTER: + case C_RANGER: + case C_MONSTER: + break; + } + + return(ret_val); +} diff -r 69ffcb6b90da -r 08489644940b urogue/artifact.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/urogue/artifact.c Sun Feb 19 19:56:43 2017 -0500 @@ -0,0 +1,1922 @@ +/* + artifact.c - functions for dealing with artifacts + + UltraRogue: The Ultimate Adventure in the Dungeons of Doom + Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong + All rights reserved. + + See the file LICENSE.TXT for full copyright and licensing information. +*/ + +#include +#include +#include "rogue.h" + +/* + apply() + apply an artifact +*/ + +void +apply(void) +{ + struct linked_list *item; + struct object *obj; + int which; + int chance; + + if ((item = get_item("activate", ARTIFACT)) == NULL) + return; + + obj = OBJPTR(item); + which = obj->o_which; + + if (!(obj->ar_flags & ISACTIVE)) + { + chance = rnd(100) - 10 * rnd(luck); + debug("Rolled %d.", chance); + if (chance < 5) + do_major(); + else if (chance < 50) + do_minor(obj); + else + obj->ar_flags |= ISACTIVE; + } + + if (obj->ar_flags & ISACTIVE) + { + switch (which) + { + case TR_PURSE: do_bag(obj); + break; + case TR_PHIAL: do_phial(); + break; + case TR_AMULET: do_amulet(); + break; + case TR_PALANTIR: do_palantir(); + break; + case TR_CROWN: do_crown(); + break; + case TR_SCEPTRE: do_sceptre(); + break; + case TR_SILMARIL: do_silmaril(); + break; + case TR_WAND: do_wand(); + break; + default: nothing_message(ISCURSED); + return; + } + } + + if (rnd(pstats.s_lvl) < 6) + do_minor(obj); + + turn_on(player, POWEREAT); +} + +/* + possessed(int artifact) + was the hero carrying a particular artifact +*/ + +int +possessed(int artifact) +{ + return (picked_artifact >> artifact) & 1; +} + +/* + is_carrying(int artifact) + is the hero carrying a particular artifact +*/ + +int +is_carrying(int artifact) +{ + return (has_artifact >> artifact) & 1; +} + +/* + make_artifact() + is it time to make a new artifact? +*/ + +int +make_artifact(void) +{ + int i; + + mpos = 0; + + debug("Artifact possession and picked flags : %x %x.", + has_artifact, picked_artifact); + + for(i = 0; i < maxartifact; i++) + { + if (!is_carrying(i) && arts[i].ar_level <= level) + return TRUE; + } + + return FALSE; +} + +/* + new_artifact(int which, struct object *cur) + make a specified artifact +*/ + +struct object * +new_artifact(int which, struct object *cur) +{ + if (which >= maxartifact) + { + debug("Bad artifact %d. Random one created.", which); + which = rnd(maxartifact); + } + + if (which < 0) + { + for (which = 0; which < maxartifact; which++) + if (!is_carrying(which) && arts[which].ar_level <= level) + break; + } + + debug("Artifact number: %d.", which); + + cur->o_hplus = cur->o_dplus = 0; + cur->o_damage = cur->o_hurldmg = "0d0"; + cur->o_ac = 11; + cur->o_mark[0] = '\0'; + cur->o_type = ARTIFACT; + cur->o_which = which; + cur->o_weight = arts[which].ar_weight; + cur->o_flags = 0; + cur->o_group = 0; + cur->o_count = 1; + cur->o_bag = NULL; + cur->ar_flags = 0; + + return(cur); +} + +/* + do_minor(struct object *tr) + side effects and minor malevolent effects of artifacts +*/ + +void +do_minor(struct object *tr) +{ + int which; + long loss; + + which = rnd(110); + + debug("Rolled %d.", which); + + switch (which) + { + case 0: + seemsg("You develop some acne on your face."); + break; + + case 1: + if (on(player, CANSCENT)) + { + msg("A sudden whiff of BO causes you to faint."); + no_command = STONETIME; + } + else if (off(player, ISUNSMELL)) + msg("You begin to smell funny."); + break; + + case 2: + seemsg("A wart grows on the end of your nose."); + break; + + case 3: + hearmsg("Your hear strange noises in the distance."); + break; + + case 4: + hearmsg("You hear shuffling in the distance."); + break; + + case 5: + hearmsg("You hear clanking in the distance."); + break; + + case 6: + hearmsg("You hear water dripping onto the floor."); + break; + + case 7: + hearmsg("The dungeon goes strangely silent."); + break; + + case 8: + msg("You suddenly feel very warm."); + break; + + case 9: + msg("You feel very hot."); + break; + + case 10: + msg("A blast of heat hits you."); + break; + + case 11: + { + struct room *rp; + + if (off(player, ISBLIND)) + msg("A pillar of flame leaps up beside you."); + else + msg("You feel something very hot nearby."); + + if (ntraps + 1 < 2 * MAXTRAPS && + fallpos(hero, &traps[ntraps].tr_pos)) + { + mvaddch(traps[ntraps].tr_pos.y, traps[ntraps].tr_pos.x, + FIRETRAP); + traps[ntraps].tr_type = FIRETRAP; + traps[ntraps].tr_flags = ISFOUND; + traps[ntraps].tr_show = FIRETRAP; + ntraps++; + + if ((rp = roomin(hero)) != NULL) + { + rp->r_flags &= ~ISDARK; + light(&hero); + mvwaddch(cw, hero.y, hero.x, PLAYER); + } + } + } + break; + + case 12: + msg("You feel a blast of hot air."); + break; + + case 13: + msg("You feel very cold."); + break; + + case 14: + msg("You break out in a cold sweat."); + break; + + case 15: + if (off(player, ISBLIND) && cur_armor == NULL) + msg("You are covered with frost."); + else if (off(player, ISBLIND)) + msg("Your armor is covered with frost."); + else if (cur_armor == NULL) + msg("Your body feels very cold and you begin to shiver."); + else + msg("Your armor feels very cold. You hear cracking ice."); + break; + + case 16: + msg("A cold wind whistles through the dungeon."); + break; + + case 17: + { + int change; + + change = 18 - pstats.s_str; + chg_str(change, TRUE, FALSE); + chg_dext(-change, TRUE, FALSE); + + if (change > 0) + msg("You feel stronger and clumsier now."); + else if (change < 0) + msg("You feel weaker and more dextrous now."); + else + nothing_message(ISCURSED); + } + break; + + case 18: + msg("You begin to itch all over."); + break; + + case 19: + msg("You begin to feel hot and itchy."); + break; + + case 20: + msg("You feel a burning itch."); + chg_dext(-1, FALSE, TRUE); + + if (off(player, HASITCH)) + { + turn_on(player, HASITCH); + light_fuse(FUSE_UNITCH, 0, roll(4,6), AFTER); + } + else + lengthen_fuse(FUSE_UNITCH, roll(4,6)); + break; + + case 21: + if (off(player, ISBLIND)) + msg("Your skin begins to flake and peel."); + else + msg("You feel an urge to scratch an itch."); + break; + + + case 22: + seemsg("Your hair begins to turn grey."); + break; + + case 23: + seemsg("Your hair begins to turn white."); + break; + + case 24: + seemsg("Some of your hair instantly turns white."); + break; + + case 25: + seemsg("You are covered with long white hair."); + break; + + case 26: + seemsg("You are covered with long red hair."); + break; + + case 27: + msg("You grow a beard."); + break; + + case 28: + msg("Your hair falls out."); + break; + + case 29: + msg("You feel a burning down below."); + break; + + case 30: + msg("Your toes fall off."); + break; + + case 31: + msg("You grow some extra toes."); + break; + + case 32: + msg("You grow some extra fingers."); + break; + + case 33: + msg("You grow an extra thumb."); + break; + + case 34: + msg("Your nose falls off."); + break; + + case 35: + msg("Your nose gets bigger."); + break; + + case 36: + msg("Your nose shrinks."); + break; + + case 37: + msg("An eye grows on your forehead."); + break; + + case 38: + seemsg("You see beady eyes watching from a distance."); + break; + + case 39: + msg("The dungeon rumbles for a moment."); + break; + + case 40: + seemsg("A flower grows on the floor next to you."); + break; + + case 41: + msg("You are stunned by a psionic blast."); + + if (on(player, ISHUH)) + lengthen_fuse(FUSE_UNCONFUSE, rnd(40) + (HUHDURATION * 3)); + else + { + light_fuse(FUSE_UNCONFUSE,0,rnd(40)+(HUHDURATION * 3), AFTER); + turn_on(player, ISHUH); + } + break; + + case 42: + msg("You are confused by thousands of voices in your head."); + + if (on(player, ISHUH)) + lengthen_fuse(FUSE_UNCONFUSE, rnd(10) + (HUHDURATION * 2)); + else + { + light_fuse(FUSE_UNCONFUSE,0,rnd(10)+(HUHDURATION * 2), AFTER); + turn_on(player, ISHUH); + } + break; + + case 43: + hearmsg("You hear voices in the distance."); + break; + + case 44: + msg("You feel a strange pull."); + teleport(); + + if (off(player, ISCLEAR)) + { + if (on(player, ISHUH)) + lengthen_fuse(FUSE_UNCONFUSE, rnd(8) + HUHDURATION); + else + { + light_fuse(FUSE_UNCONFUSE, 0, rnd(8) + HUHDURATION, AFTER); + turn_on(player, ISHUH); + } + } + break; + + case 45: + msg("You feel less healthy now."); + pstats.s_const = max(pstats.s_const - 1, 3); + max_stats.s_const = max(max_stats.s_const - 1, 3); + break; + + case 46: + msg("You feel weaker now."); + chg_str(-1, TRUE, FALSE); + break; + + case 47: + msg("You feel less wise now."); + pstats.s_wisdom = max(pstats.s_wisdom - 1, 3); + max_stats.s_wisdom = max(max_stats.s_wisdom - 1, 3); + break; + + case 48: + msg("You feel less dextrous now."); + chg_dext(-1, TRUE, FALSE); + break; + + case 49: + msg("You feel less intelligent now."); + pstats.s_intel = max(pstats.s_intel - 1, 3); + max_stats.s_intel = max(max_stats.s_intel - 1, 3); + break; + + case 50: + msg("A trap door opens underneath your feet."); + mpos = 0; + level++; + new_level(NORMLEV,0); + + if (rnd(4) < 2) + { + addmsg("You are damaged by the fall"); + + if ((pstats.s_hpt -= roll(1, 6)) <= 0) + { + addmsg("! The fall killed you."); + endmsg(); + death(D_FALL); + return; + } + } + + addmsg("!"); + endmsg(); + + if (off(player, ISCLEAR) && rnd(4) < 3) + { + if (on(player, ISHUH)) + lengthen_fuse(FUSE_UNCONFUSE, rnd(8) + HUHDURATION); + else + light_fuse(FUSE_UNCONFUSE, 0, rnd(8) + HUHDURATION, AFTER); + + turn_on(player, ISHUH); + } + else + msg("You feel dizzy for a moment, but it quickly passes."); + + break; + + case 51: + msg("A maze entrance opens underneath your feet."); + mpos = 0; + level++; + new_level(MAZELEV,0); + + if (rnd(4) < 2) + { + addmsg("You are damaged by the fall"); + + if ((pstats.s_hpt -= roll(1, 6)) <= 0) + { + addmsg("! The fall killed you."); + endmsg(); + death(D_FALL); + return; + } + } + addmsg("!"); + endmsg(); + + if (off(player, ISCLEAR) && rnd(4) < 3) + { + if (on(player, ISHUH)) + lengthen_fuse(FUSE_UNCONFUSE, rnd(8) + HUHDURATION); + else + light_fuse(FUSE_UNCONFUSE,0, rnd(8) + HUHDURATION, AFTER); + + turn_on(player, ISHUH); + } + else + msg("You feel dizzy for a moment, but it quickly passes."); + + break; + + case 52: + hearmsg("You hear a wailing sound in the distance."); + aggravate(); + break; + + case 53: + read_scroll(&player, S_HOLD, ISCURSED); + break; + + case 54: + msg("You can't move."); + no_command = 3 * HOLDTIME; + break; + + case 55: + hearmsg("You hear a buzzing sound."); + aggravate(); + break; + + case 56: + msg("Your limbs stiffen."); + no_command = 3 * STONETIME; + break; + + case 57: + msg("You feel a rock in your shoe hurting your foot."); + turn_on(player, STUMBLER); + break; + + case 58: + msg("You get a hollow feeling in your stomach."); + food_left -= 500; + break; + + case 59: + msg("Your purse feels lighter."); + + loss = 50L + ulrnd(purse / 2L); + purse = (purse > loss) ? purse - loss : 0L; + break; + + case 60: + msg("A pixie appears and grabs gold from your purse."); + + loss = 50L + rnd(50); + purse = (purse > loss) ? purse - loss : 0L; + break; + + case 61: + msg("You feel a tingling sensation all over."); + pstats.s_hpt -= ulrnd(pstats.s_hpt / 3L); + break; + + case 62: + msg("You feel a pull downwards."); + break; + + case 63: + msg("You feel a strange pull downwards."); + break; + + case 64: + msg("You feel a peculiar pull downwards."); + break; + + case 65: + msg("You have a strange urge to go down."); + break; + + case 66: + msg("You feel a pull upwards."); + break; + + case 67: + msg("You feel a strange pull upwards."); + break; + + case 68: + msg("You have a strange feeling for a moment."); + break; + + case 69: + msg("You float in the air for a moment."); + break; + + case 70: + msg("You feel very heavy for a moment."); + break; + + case 71: + msg("You feel a strange sense of loss."); + break; + + case 72: + msg("You feel the earth spinning underneath your feet."); + break; + + case 73: + msg("You feel in touch with a Universal Oneness."); + break; + + case 74: + hearmsg("You hear voices in the distance."); + break; + + case 75: + msg("A strange feeling of power comes over you."); + break; + + case 76: + msg("You feel a strange sense of unease."); + break; + + case 77: + msg("You feel Lady Luck is looking the other way."); + luck++; + break; + + case 78: + msg("You feel your pack vibrate for a moment."); + break; + + case 79: + msg("You feel someone is watching you."); + break; + + case 80: + msg("You feel your hair standing on end."); + break; + + case 81: + msg("Wait! The walls are moving!"); + new_level(NORMLEV,0); + break; + + case 82: + msg("Wait! Walls are appearing out of nowhere!"); + new_level(MAZELEV,0); + break; + + case 83: + blue_light(ISCURSED); + break; + + case 84: + msg("Your mind goes blank for a moment."); + wclear(cw); + light(&hero); + status(TRUE); + break; + + case 85: + if (on(player, ISDEAF)) + { + msg("You feel your ears burn for a moment."); + lengthen_fuse(FUSE_HEAR, 2 * PHASEDURATION); + } + else + { + msg("You are suddenly surrounded by silence."); + turn_on(player, ISDEAF); + light_fuse(FUSE_HEAR, 0, 2 * PHASEDURATION, AFTER); + } + break; + + case 86: + { + apply_to_bag(pack, 0, NULL, baf_curse, NULL); + + if (off(player, ISUNSMELL)) + msg("You smell a faint trace of burning sulfur."); + } + break; + + case 87: + msg("You have contracted a parasitic infestation."); + infest_dam++; + turn_on(player, HASINFEST); + break; + + case 88: + msg("You suddenly feel a chill run up and down your spine."); + turn_on(player, ISFLEE); + player.t_ischasing = FALSE; + player.t_chasee = &player; + break; + + case 89: + if (cur_weapon != NULL) + msg("You feel your %s get very hot.", + inv_name(cur_weapon, LOWERCASE)); + break; + + case 90: + if (cur_weapon != NULL) + msg("Your %s glows white for an instant.", + inv_name(cur_weapon, LOWERCASE)); + break; + + case 91: + if (cur_armor != NULL) + msg("Your %s gets very hot.", inv_name(cur_armor, LOWERCASE)); + break; + + case 92: + if (cur_weapon != NULL) + msg("Your %s suddenly feels very cold.", + inv_name(cur_weapon, LOWERCASE)); + break; + + case 93: + if (cur_armor != NULL) + msg("Your armor is covered by an oily film."); + break; + + case 94: + read_scroll(&player, S_CREATE, ISNORMAL); + break; + + case 95: + lower_level(D_POTION); + break; + + case 96: + { + int x, y; + + for (x = -1; x <= 1; x++) + { + for (y = -1; y <= 1; y++) + { + if (x == 0 && y == 0) + continue; + + delta.x = x; + delta.y = y; + + do_zap(&player, WS_POLYMORPH, rnd(2) + ? ISCURSED : ISNORMAL); + } + } + } + break; + + case 97: + { + int x, y; + + for (x = -1; x <= 1; x++) + { + for (y = -1; y <= 1; y++) + { + if (x == 0 && y == 0) + continue; + + delta.x = x; + delta.y = y; + + do_zap(&player, WS_INVIS, ISNORMAL); + } + } + } + break; + + default: + tr->ar_flags &= ~ISACTIVE; + hearmsg("You hear a click coming from %s.",inv_name(tr,LOWERCASE)); + break; + + } +} + +/* + do_major() + + major malevolent effects + + 0. read_scroll(S_SELFTELEPORT, ISCURSED) + 1. PERMBLIND for twice normal duration + 2. new_level(THRONE); + 3. turn_on(player, SUPEREAT); + 4. lengthen(noslow, 20 + rnd(20)); + 5. lower_level(D_POTION) * roll(1,4) + 6. change stats + 7. FIRETRAP + 8. armor crumbles + 9. weapon crumbles + 10. weapon crumbles + 11. curse weapon +*/ + +void +do_major(void) +{ + int which; + + which = rnd(12); + + debug("Rolled %d.", which); + + switch (which) + { + case 0: + read_scroll(&player, S_SELFTELEP, ISCURSED); + break; + + case 1: + quaff(&player, P_TRUESEE, ISCURSED); + quaff(&player, P_TRUESEE, ISCURSED); + break; + + case 2: + new_level(THRONE,0); + break; + + case 3: /* Turn off other body-affecting spells */ + + if (on(player, ISREGEN)) + { + extinguish_fuse(FUSE_UNREGEN); + turn_off(player, ISREGEN); + unregen(NULL); + } + + if (on(player, NOCOLD)) + { + extinguish_fuse(FUSE_UNCOLD); + turn_off(player, NOCOLD); + uncold(NULL); + } + + if (on(player, NOFIRE)) + { + extinguish_fuse(FUSE_UNHOT); + turn_off(player, NOFIRE); + unhot(NULL); + } + + if (on(player, SUPEREAT)) + { + lengthen_fuse(FUSE_UNSUPEREAT, 2 * PHASEDURATION); + msg("Your body temperature rises still further."); + } + else + { + msg("You feel very warm all over."); + light_fuse(FUSE_UNSUPEREAT, 0, 2 * PHASEDURATION, AFTER); + turn_on(player, SUPEREAT); + } + break; + + case 4: + msg("You feel yourself moving %sslower.", + on(player, ISSLOW) ? "even " : ""); + + if (on(player, ISSLOW)) + lengthen_fuse(FUSE_NOSLOW, PHASEDURATION); + else + { + turn_on(player, ISSLOW); + player.t_turn = TRUE; + light_fuse(FUSE_NOSLOW, 0, PHASEDURATION, AFTER); + } + break; + + case 5: + { + int i, n = roll(1, 4); + + for (i = 1; i < n; i++) + lower_level(D_POTION); + } + break; + + case 6: + if (rnd(2)) + add_intelligence(TRUE); + + if (rnd(2)) + chg_dext(-1, TRUE, FALSE); + + if (rnd(2)) + chg_str(-1, TRUE, FALSE); + + if (rnd(2)) + add_wisdom(TRUE); + + if (rnd(2)) + add_const(TRUE); + + break; + + case 7: + { + struct room *rp; + + if (ntraps + 1 >= MAXTRAPS) + { + msg("You feel a puff of hot air."); + return; + } + + for (; ntraps < 2 * MAXTRAPS; ntraps++) + { + if (!fallpos(hero, &traps[ntraps].tr_pos)) + break; + + mvaddch(traps[ntraps].tr_pos.y, traps[ntraps].tr_pos.x, + FIRETRAP); + traps[ntraps].tr_type = FIRETRAP; + traps[ntraps].tr_flags |= ISFOUND; + traps[ntraps].tr_show = FIRETRAP; + + if ((rp = roomin(hero)) != NULL) + rp->r_flags &= ~ISDARK; + } + } + break; + + case 8: + { + object *obj; + + if (cur_weapon == NULL) + { + msg("You feel your hands tingle a moment."); + pstats.s_dmg = "1d2"; + return; + } + + obj = apply_to_bag(pack, 0, NULL, bafcweapon, NULL); + + if (obj->o_flags & ISMETAL) + msg("Your %s melts and disappears.", + inv_name(obj,LOWERCASE)); + else + msg("Your %s crumbles in your hands.", + inv_name(obj, LOWERCASE)); + + obj->o_flags &= ~ISCURSED; + dropcheck(obj); + del_bag(pack, obj); + + } + break; + + case 9: + { + object *obj; + + if (cur_armor == NULL) + { + msg("Your body tingles a moment."); + return; + } + + obj = apply_to_bag(pack, 0, NULL, bafcarmor, NULL); + + msg("Your %s crumbles into small black powdery dust.", + inv_name(obj, LOWERCASE)); + + obj->o_flags &= ~ISCURSED; + dropcheck(obj); + del_bag(pack, obj); + } + break; + + default: + + if (cur_weapon == NULL) + { + seemsg("Your hand glows yellow for an instant."); + pstats.s_dmg = "1d3"; + return; + } + + seemsg("Your %s glows bright red for a moment.", + weaps[cur_weapon->o_which].w_name); + + if (cur_weapon->o_hplus > 0) + cur_weapon->o_hplus = -rnd(3); + else + cur_weapon->o_hplus -= rnd(3); + + if (cur_weapon->o_dplus > 0) + cur_weapon->o_dplus = -rnd(3); + else + cur_weapon->o_dplus -= rnd(3); + + cur_weapon->o_flags = ISCURSED | ISLOST; + cur_weapon->o_ac = 0; + + break; + } +} + +/* + do_phial() + handle powers of the Phial of Galadriel +*/ + +void +do_phial(void) +{ + int which; + + /* Prompt for action */ + + msg("How do you wish to apply the Phial of Galadriel (* for list)? "); + + which = (short) ((readchar() & 0177) - 'a'); + + if (which == (short) ESCAPE - (short) 'a') + { + after = FALSE; + return; + } + + if (which < 0 || which > 1) + { + add_line("[a] total healing"); + add_line("[b] total monster confusion"); + end_line(); + msg(""); + msg("Which power do you wish to use? "); + + which = (short) ((readchar() & 0177) - 'a'); + + while (which < 0 || which > 1) + { + if (which == (short) ESCAPE - (short) 'a') + { + after = FALSE; + return; + } + + msg(""); + msg("Please enter one of the listed powers: "); + + which = (short) ((readchar() & 0177) - 'a'); + } + msg("Your attempt is successful."); + } + else + msg("Your attempt is successsful."); + + switch (which) + { + case 0: + pstats.s_hpt = max_stats.s_hpt += rnd(pstats.s_lvl) + 1; + pstats.s_power = max_stats.s_power += rnd(pstats.s_lvl) + 1; + break; + + case 1: + { + struct linked_list *mi; + struct thing *tp; + + for (mi = mlist; mi != NULL; mi = next(mi)) + { + tp = THINGPTR(mi); + + if (off(*tp, ISUNIQUE) || !save_throw(VS_MAGIC, tp)) + turn_on(*tp, ISHUH); + } + } + break; + + default: + msg("What a strange thing to do!!"); + break; + + } +} + +/* + do_palantir() + handle powers of the Palantir of Might +*/ + +void +do_palantir(void) +{ + int which, limit; + + /* Prompt for action */ + + msg("How do you wish to apply the Palantir of Might? (* for list): "); + + limit = 3; + + if (is_carrying(TR_SCEPTRE)) + limit += 1; + + if (is_carrying(TR_CROWN)) + limit += 1; + + which = (short) ((readchar() & 0177) - 'a'); + + if (which == (short) ESCAPE - (short) 'a') + { + after = FALSE; + return; + } + + if (which < 0 || which > limit) + { + msg(""); + add_line("[a] monster detection"); + add_line("[b] gold detection"); + add_line("[c] magic detection"); + add_line("[d] food detection"); + + if (limit >= 4) + add_line("[e] teleportation"); + + if (limit >= 5) + add_line("[f] clear thought"); + + end_line(); + + msg("Which power do you wish to use?"); + + which = (short) ((readchar() & 0177) - 'a'); + + while (which < 0 || which > limit) + { + if (which == (short) ESCAPE - (short) 'a') + { + after = FALSE; + return; + } + + msg("Please enter one of the listed powers: "); + which = (short) ((readchar() & 0177) - 'a'); + } + + msg("Your attempt is successful."); + } + else + msg("Your attempt is successful."); + + switch (which) + { + case 0: quaff(&player, P_MONSTDET, ISNORMAL); + break; + case 1: read_scroll(&player, S_GFIND, ISNORMAL); + break; + case 2: quaff(&player, P_TREASDET, ISNORMAL); + break; + case 3: read_scroll(&player, S_FOODDET, ISNORMAL); + break; + case 4: read_scroll(&player, S_SELFTELEP, ISNORMAL); + break; + case 5: quaff(&player, P_CLEAR, ISNORMAL); + break; + default: + msg("What a strange thing to do!!"); + break; + } +} + +/* + do_silmaril() + handle powers of the Silamril of Ea +*/ + +void +do_silmaril(void) +{ + int which; + + /* Prompt for action */ + msg("How do you wish to apply the Silamril of Ea (* for list)? "); + + which = (short) ((readchar() & 0177) - 'a'); + + if (which == (short) ESCAPE - (short) 'a') + { + after = FALSE; + return; + } + + if (which < 0 || which > 2) + { + msg(""); + add_line("[a] magic mapping"); + add_line("[b] petrification"); + add_line("[c] stairwell downwards"); + end_line(); + + msg("Which power do you wish to use?"); + + which = (short) ((readchar() & 0177) - 'a'); + + while (which < 0 || which > 2) + { + if (which == (short) ESCAPE - (short) 'a') + { + after = FALSE; + return; + } + msg(""); + msg("Please enter one of the listed powers: "); + which = (short) ((readchar() & 0177) - 'a'); + } + msg("Your attempt is successful."); + } + else + msg("Your attempt is successful."); + + switch (which) + { + case 0: read_scroll(&player, S_MAP, ISNORMAL); + break; + case 1: read_scroll(&player, S_PETRIFY, ISNORMAL); + break; + case 2: msg("A stairwell opens beneath your feet and you go down."); + level++; + new_level(NORMLEV,0); + break; + default:msg("What a strange thing to do!!"); + break; + } +} + +/* + do_amulet() + handle powers of the Amulet of Yendor +*/ + +void +do_amulet(void) +{ + int which, limit; + + /* Prompt for action */ + msg("How do you wish to apply the Amulet of Yendor (* for list)? "); + + limit = 0; + + if (is_carrying(TR_PURSE)) + limit += 1; + + which = (short) ((readchar() & 0177) - 'a'); + + if (which == (short) ESCAPE - (short) 'a') + { + after = FALSE; + return; + } + + if (which < 0 || which > limit) + { + msg(""); + add_line("[a] level evaluation"); + + if (limit >= 1) + add_line("[b] invisibility"); + + end_line(); + msg("Which power do you wish to use?"); + + which = (short) ((readchar() & 0177) - 'a'); + + while (which < 0 || which > limit) + { + if (which == (short) ESCAPE - (short) 'a') + { + after = FALSE; + return; + } + + msg(""); + msg("Please enter one of the listed powers: "); + which = (short) ((readchar() & 0177) - 'a'); + } + + msg("Your attempt is successful."); + } + else + msg("Your attempt is successful."); + + switch (which) + { + case 0: level_eval(); + break; + case 1: quaff(&player, P_INVIS, ISNORMAL); + break; + default:msg("What a strange thing to do!!"); + break; + } +} + +/* + do_bag() + handle powers of the Magic Purse of Yendor as a bag of holding +*/ + +void +do_bag(struct object *obj) +{ + int which, limit; + + /* Prompt for action */ + msg("How do you wish to apply the Magic Purse of Yendor (* for list)? "); + + which = (short) ((readchar() & 0177) - 'a'); + + if (which == (short) ESCAPE - (short) 'a') + { + after = FALSE; + return; + } + + limit = 2; + + if (is_carrying(TR_AMULET)) + limit += 1; + + if (which < 0 || which > limit) + { + msg(""); + add_line("[a] inventory"); + add_line("[b] add to bag"); + add_line("[c] remove from bag"); + + if (limit >= 3) + add_line("[d] see invisible"); + + end_line(); + + msg("Which power do you wish to use?"); + + which = (short) ((readchar() & 0177) - 'a'); + + while (which < 0 || which > limit) + { + if (which == (short) ESCAPE - (short) 'a') + { + after = FALSE; + return; + } + + msg(""); + msg("Please enter one of the listed powers: "); + which = (short) ((readchar() & 0177) - 'a'); + } + + msg("Your attempt is successful."); + } + else + msg("Your attempt is successful."); + + switch (which) + { + case 0: + inventory(obj->o_bag, 0); + break; + + case 1: + { + object *new_obj_p; /* what the user selected */ + + if ((new_obj_p = get_object(pack, "add", 0, NULL)) != NULL) + { + rem_pack(new_obj_p); /* free up pack slot */ + push_bag(&obj->o_bag, new_obj_p); + pack_report(new_obj_p, MESSAGE, "You just added "); + } + } + break; + + case 2: + { + object *obj_p; + linked_list *item_p; + + if ((obj_p=get_object(obj->o_bag,"remove",0,NULL)) != NULL) + { + item_p = make_item(obj_p); /* attach upper structure */ + + if (add_pack(item_p, MESSAGE) != FALSE) + pop_bag(&obj->o_bag, obj_p); + } + } + break; + + case 3: + quaff(&player, P_TRUESEE, ISBLESSED); + break; + + default: + msg("What a strange thing to do!!"); + } +} + +/* + do_sceptre() + handle powers of the Sceptre of Might +*/ + +void +do_sceptre(void) +{ + int which, limit; + + /* Prompt for action */ + msg("How do you wish to apply the Sceptre of Might (* for list)? "); + + which = (short) ((readchar() & 0177) - 'a'); + + if (which == (short) ESCAPE - (short) 'a') + { + after = FALSE; + return; + } + + limit = 5; + + if (is_carrying(TR_CROWN)) + limit += 1; + + if (is_carrying(TR_PALANTIR)) + limit += 1; + + if (which < 0 || which > limit) + { + msg(""); + add_line("[a] cancellation"); + add_line("[b] polymorph monster"); + add_line("[c] slow monster"); + add_line("[d] teleport monster"); + add_line("[e] monster confusion"); + add_line("[f] paralyze monster"); + + if (limit >= 6) + add_line("[g] drain life"); + + if (limit >= 7) + add_line("[h] smell monster"); + + end_line(); + + msg("Which power do you wish to use?"); + + which = (short) ((readchar() & 0177) - 'a'); + + while (which < 0 || which > limit) + { + if (which == (short) ESCAPE - (short) 'a') + { + after = FALSE; + return; + } + + msg(""); + msg("Please enter one of the listed powers: "); + which = (short) ((readchar() & 0177) - 'a'); + } + + msg("Your attempt is successful."); + } + else + msg("Your attempt is successful."); + + if (rnd(pstats.s_lvl) < 7) + { + msg("Your finger slips."); + which = rnd(6); + if (wizard) + { + msg("What wand? (%d)", which); + + if (get_string(prbuf, cw) == NORM) + { + which = atoi(prbuf); + if (which < 0 || which > 5) + { + msg("Invalid selection."); + which = rnd(6); + msg("Rolled %d.", which); + } + } + } + } + + switch (which) + { + case 0: + if (get_dir()) + do_zap(&player, WS_CANCEL, ISBLESSED); + break; + + case 1: + if (get_dir()) + do_zap(&player, WS_POLYMORPH, ISBLESSED); + break; + + case 2: + if (get_dir()) + do_zap(&player, WS_SLOW_M, ISBLESSED); + break; + + case 3: + if (get_dir()) + do_zap(&player, WS_MONSTELEP, ISBLESSED); + break; + + case 4: + if (get_dir()) + do_zap(&player, WS_CONFMON, ISBLESSED); + break; + + case 5: + if (get_dir()) + do_zap(&player, WS_PARALYZE, ISBLESSED); + break; + + case 6: + if (get_dir()) + do_zap(&player, WS_DRAIN, ISBLESSED); + break; + + case 7: + quaff(&player, P_SMELL, ISBLESSED); + break; + + default: + msg("What a strange thing to do!!"); + break; + } +} + +/* + do_wand() + handle powers of the Wand of Yendor +*/ + +void +do_wand(void) +{ + int which, i; + + /* Prompt for action */ + msg("How do you wish to apply the Wand of Yendor (* for list)? "); + + which = (short) ((readchar() & 0177) - 'a'); + + if (which == (short) ESCAPE - (short) 'a') + { + after = FALSE; + return; + } + + if (which < 0 || which >= maxsticks) + { + msg(""); + + for (i = 0; i < maxsticks; i++) + { + sprintf(prbuf, "[%c] %s", i + 'a', ws_magic[i].mi_name); + add_line(prbuf); + } + + end_line(); + + msg("Which power do you wish to use?"); + + which = (short) ((readchar() & 0177) - 'a'); + + while (which < 0 || which >= maxsticks) + { + if (which == (short) ESCAPE - (short) 'a') + { + after = FALSE; + return; + } + + msg(""); + msg("Please enter one of the listed powers: "); + which = (short) ((readchar() & 0177) - 'a'); + } + msg("Your attempt is successful."); + } + else + msg("Your attempt is successful."); + + if (rnd(pstats.s_lvl) < 12) + { + msg("Your finger slips."); + which = rnd(maxsticks); + + if (wizard) + { + msg("What wand? (%d)", which); + + if (get_string(prbuf, cw) == NORM) + { + which = atoi(prbuf); + + if (which < 0 || which >= maxsticks) + { + msg("Invalid selection."); + which = rnd(maxsticks); + msg("Rolled %d.", which); + } + } + } + } + + if (get_dir()) + do_zap(&player, which, ISBLESSED); +} + +/* + do_crown() + handle powers of the Crown of Might +*/ + +void +do_crown(void) +{ + int which, limit; + + /* Prompt for action */ + msg("How do you wish to apply the Crown of Might (* for list)? "); + + which = (short) ((readchar() & 0177) - 'a'); + + if (which == (short) ESCAPE - (short) 'a') + { + after = FALSE; + return; + } + + limit = 9; + + if (is_carrying(TR_PALANTIR)) + limit += 1; + + if (is_carrying(TR_SCEPTRE))