Mercurial > hg > early-roguelike
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; +}