diff urogue/artifact.c @ 256:c495a4f288c6

Import UltraRogue from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Tue, 31 Jan 2017 19:56:04 -0500
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/urogue/artifact.c	Tue Jan 31 19:56:04 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 <stdlib.h>
+#include <ctype.h>
+#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))
+        limit += 1;
+
+    if (which < 0 || which > limit)
+    {
+        msg("");
+        add_line("[a] add strength");
+        add_line("[b] add intelligence");
+        add_line("[c] add wisdom");
+        add_line("[d] add dexterity");
+        add_line("[e] add constitution");
+        add_line("[f] normal strength");
+        add_line("[g] normal intelligence");
+        add_line("[h] normal wisdom");
+        add_line("[i] normal dexterity");
+        add_line("[j] normal constitution");
+
+        if (limit >= 10)
+            add_line("[k] disguise");
+
+        if (limit >= 11)
+            add_line("[l] super heroism");
+
+        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:
+            if (off(player, POWERSTR))
+            {
+                turn_on(player, POWERSTR);
+                chg_str(10, FALSE, FALSE);
+                msg("You feel much stronger now.");
+            }
+            else
+                nothing_message(ISCURSED);
+            break;
+
+        case 1:
+            if (off(player, POWERINTEL))
+            {
+                pstats.s_intel += 10;
+                turn_on(player, POWERINTEL);
+                msg("You feel much more intelligent now.");
+            }
+            else
+                nothing_message(ISCURSED);
+            break;
+
+        case 2:
+            if (off(player, POWERWISDOM))
+            {
+                pstats.s_wisdom += 10;
+                turn_on(player, POWERWISDOM);
+                msg("Your feel much wiser know.");
+            }
+            else
+                nothing_message(ISCURSED);
+            break;
+
+        case 3:
+            if (off(player, POWERDEXT))
+            {
+                turn_on(player, POWERDEXT);
+                chg_dext(10, FALSE, FALSE);
+                msg("You feel much more dextrous now.");
+            }
+            else
+                nothing_message(ISCURSED);
+            break;
+
+        case 4:
+            if (off(player, POWERCONST))
+            {
+                pstats.s_const += 10;
+                turn_on(player, POWERCONST);
+                msg("You feel much healthier now.");
+            }
+            else
+                nothing_message(ISCURSED);
+            break;
+
+        case 5:
+            if (on(player, POWERSTR))
+            {
+                turn_off(player, POWERSTR);
+                chg_str(-10, FALSE, FALSE);
+                msg("Your muscles bulge less now.");
+            }
+            else
+                nothing_message(ISCURSED);
+            break;
+
+        case 6:
+            if (on(player, POWERINTEL))
+            {
+                pstats.s_intel = max(pstats.s_intel - 10,
+                             3 + ring_value(R_ADDINTEL));
+                turn_off(player, POWERINTEL);
+                msg("You feel less intelligent now.");
+            }
+            else
+                nothing_message(ISCURSED);
+            break;
+
+        case 7:
+            if (on(player, POWERWISDOM))
+            {
+                pstats.s_wisdom = max(pstats.s_wisdom - 10,
+                              3 + ring_value(R_ADDWISDOM));
+                turn_off(player, POWERWISDOM);
+                msg("You feel less wise now.");
+            }
+            else
+                nothing_message(ISCURSED);
+            break;
+
+        case 8:
+            if (on(player, POWERDEXT))
+            {
+                turn_off(player, POWERDEXT);
+                chg_dext(-10, FALSE, FALSE);
+                msg("You feel less dextrous now.");
+            }
+            else
+                nothing_message(ISCURSED);
+            break;
+
+        case 9:
+            if (on(player, POWERCONST))
+            {
+                pstats.s_const -= 10;
+                turn_off(player, POWERCONST);
+                msg("You feel less healthy now.");
+            }
+            else
+                nothing_message(ISCURSED);
+            break;
+
+        case 10: quaff(&player, P_DISGUISE, ISNORMAL);
+            break;
+
+        case 11: quaff(&player, P_SHERO, ISNORMAL);
+            break;
+
+        default:
+            msg("What a strange thing to do!!");
+            break;
+
+    }
+}
+
+/*
+    level_eval()
+        have amulet evaluate danger on this level
+*/
+
+void
+level_eval(void)
+{
+    int cnt = 0;
+    long max_nasty = 0;
+    struct linked_list  *item;
+    struct thing    *tp;
+    char    *colour, *temp;
+
+    for (item = mlist; item != NULL; item = next(item))
+    {
+        tp = THINGPTR(item);
+        cnt++;
+        max_nasty = max(max_nasty,(10L-tp->t_stats.s_arm) * tp->t_stats.s_hpt);
+    }
+
+    if (cnt < 3)
+        colour = "black";
+    else if (cnt < 6)
+        colour = "red";
+    else if (cnt < 9)
+        colour = "orange";
+    else if (cnt < 12)
+        colour = "yellow";
+    else if (cnt < 15)
+        colour = "green";
+    else if (cnt < 18)
+        colour = "blue";
+    else if (cnt < 25)
+        colour = "violet";
+    else
+        colour = "pink with purple polka dots";
+
+    if (max_nasty < 10)
+        temp = "feels cold and lifeless";
+    else if (max_nasty < 30)
+        temp = "feels cool";
+    else if (max_nasty < 200)
+        temp = "feels warm and soft";
+    else if (max_nasty < 1000)
+        temp = "feels warm and slippery";
+    else if (max_nasty < 5000)
+        temp = "feels hot and dry";
+    else if (max_nasty < 10000)
+        temp = "feels too hot to hold";
+    else if (max_nasty < 20000)
+        temp = "burns your hand";
+    else
+        temp = "jumps up and down shrieking 'DANGER! DANGER'";
+
+    msg("The amulet glows %s and %s.", colour, temp);
+
+    return;
+}