view urogue/artifact.c @ 297:317166b49d8a

Ultra-Rogue: add a NULL check.
author John "Elwin" Edwards
date Thu, 08 Feb 2018 18:56:15 -0500
parents c495a4f288c6
children
line wrap: on
line source

/*
    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);