Пример #1
0
void
chase_it(coord *runner, struct thing *th)
{
    struct linked_list  *item;
    struct thing    *tp;

    /* If we couldn't find him, something is funny */

    if ((item = find_mons(runner->y, runner->x)) == NULL)
    {
        debug("CHASER '%s'", unctrl(winat(runner->y, runner->x)));
        return;
    }

    tp = THINGPTR(item);

    /* Start the beastie running */

    tp->t_ischasing = TRUE;
    tp->t_chasee    = th;

    turn_on(*tp, ISRUN);
    turn_off(*tp, ISDISGUISE);

    return;
}
Пример #2
0
int
hit_monster(int y, int x, struct object *weapon, struct thing *thrower)
{
    struct linked_list *mon;
    coord target;

    target.y = y;
    target.x = x;

    if (thrower == &player)
        return(fight(&target, weapon, THROWN));

    if (ce(target, hero))
    {
        if (good_monster(*thrower))
        {
            if (on(*thrower, ISFAMILIAR))
                msg("Please get out of the way, Master!  I nearly hit you.");
            else
                msg("Get out of the way %s!", whoami);

            return(FALSE);
        }

        return(attack(thrower, weapon, THROWN));
    }

    if ((mon = find_mons(y, x)) != NULL)
        return(mon_mon_attack(thrower, mon, weapon, THROWN));
    else
        return(FALSE);
}
Пример #3
0
coord   *
find_shoot(struct thing *tp, coord *dir)
{
    struct room *rtp;
    int ulx, uly, xmx, ymx, xmon, ymon, tpx, tpy, row, col;
    struct linked_list  *mon;
    struct thing    *ick;

    rtp = roomin(tp->t_pos);   /* Find room of chaser */

    if (rtp == NULL)
        return NULL;

    ulx = rtp->r_pos.x;
    uly = rtp->r_pos.y;
    xmx = rtp->r_max.x;
    ymx = rtp->r_max.y;

    tpx = tp->t_pos.x;
    tpy = tp->t_pos.y;

    for (col = ulx; col < (ulx + xmx); col++)
        for (row = uly; row < (uly + ymx); row++)
        {
            if (row > 0 && col > 0 && isalpha(mvwinch(mw, row, col)))
            {
		mon = find_mons(row, col);

                if (mon)
                {
                    ick = THINGPTR(mon);
                    xmon = ick->t_pos.x;
                    ymon = ick->t_pos.y;

                    if (!(good_monster(*ick)))
                    {
                        if (straight_shot(tpy, tpx, ymon, xmon, dir))
                            return(dir);
                    }
                }
            }
        }

    return(NULL);
}
/*
 * runto:
 *	Set a mosnter running after something
 *	or stop it from running (for when it dies)
 */
void
runto(coord *runner, coord *spot)
{
    register struct linked_list *item;
    register struct thing *tp;

    /*
     * If we couldn't find him, something is funny
     */
    if ((item = find_mons(runner->y, runner->x)) == NULL) {
	debug("CHASER '%s'", unctrl(winat(runner->y, runner->x)));
	return;
    }
    tp = (struct thing *) ldata(item);
    /*
     * Start the beastie running
     */
    tp->t_dest = spot;
    turn_on(*tp, ISRUN);
    turn_off(*tp, ISDISGUISE);
}
Пример #5
0
void
runto(coord *runner, coord *spot)
{
    struct linked_list *item;
    struct thing *tp;

    /*
     * If we couldn't find him, something is funny
     */
    if ((item = find_mons(runner->y, runner->x)) == NULL)
    {
	msg("CHASER '%s'", unctrl(winat(runner->y, runner->x)));
	return;
    }
    tp = (struct thing *) ldata(item);
    /*
     * Start the beastie running
     */
    tp->t_dest = spot;
    tp->t_flags |= ISRUN;
    tp->t_flags &= ~ISHELD;
}
Пример #6
0
struct linked_list  *
f_mons_a(int y, int x, int hit_bad)
{
    int row, col;
    struct linked_list  *item;
    struct thing    *tp;

    for (row = x - 1; row <= x + 1; row++)
        for (col = y - 1; col <= y + 1; col++)
            if (row == x && col == y)
                continue;
            else if (col > 0 && row > 0 &&
                isalpha(mvwinch(mw, col, row)) &&
                 ((item = find_mons(col, row)) != NULL))
            {
                tp = THINGPTR(item);
                if ((good_monster(*tp) && !hit_bad) ||
                    (!good_monster(*tp) && hit_bad))
                    return (item);
            }

    return (NULL);
}
Пример #7
0
struct linked_list *
wake_monster(int y, int x)
{
    struct thing    *tp;
    struct linked_list  *it;
    struct room *trp;
    char    *mname;

    if ((it = find_mons(y, x)) == NULL)
    {
        debug("Can't find monster in show.");
        return(NULL);
    }

    tp = THINGPTR(it);

    if ((good_monster(*tp)) || on(player, SUMMONING))
    {
        chase_it(&tp->t_pos, &player);
        turn_off(*tp, ISINVIS);
        turn_off(*tp, CANSURPRISE);
        return(it);
    }

    trp = roomin(tp->t_pos);   /* Current room for monster */
    mname = monsters[tp->t_index].m_name;

    /* Let greedy ones guard gold */

    if (on(*tp, ISGREED) && off(*tp, ISRUN))
        if ((trp != NULL) && (lvl_obj != NULL))
        {
            struct linked_list  *item;
            struct object   *cur;

            for (item = lvl_obj; item != NULL; item = next(item))
            {
                cur = OBJPTR(item);

                if ((cur->o_type == GOLD) &&
                    (roomin(cur->o_pos) == trp))
                {
                    /* Run to the gold */
                    tp->t_horde = cur;
                    turn_on(*tp, ISRUN);
                    turn_off(*tp, ISDISGUISE);
                    tp->t_ischasing = FALSE;
                    /* Make it worth protecting */
                    cur->o_count += roll(2, 3) * GOLDCALC;
                    break;
                }
            }
        }

    /*
     * Every time he sees mean monster, it might start chasing him unique
     * monsters always do
     */

    if (  (on(*tp, ISUNIQUE)) ||
          ( (rnd(100) > 33) &&
            on(*tp, ISMEAN) &&
            off(*tp, ISHELD) &&
            off(*tp, ISRUN) &&
            !is_stealth(&player) &&
            (off(player, ISINVIS) || on(*tp, CANSEE))
          )
       )
    {
        chase_it(&tp->t_pos, &player);
    }

    /* Handle gaze attacks */

    if (on(*tp, ISRUN) && cansee(tp->t_pos.y, tp->t_pos.x) &&
            off(player, ISINVIS))
    {
        if (on(*tp, CANHUH))    /* Confusion */
        {
            if (on(player, CANREFLECT))
            {
                msg("You reflect the bewildering stare of the %s.", mname);

                if (save_throw(VS_MAGIC, tp))
                {
                    msg("The %s is confused!", mname);
                    turn_on(*tp, ISHUH);
                }
                else
                    msg("The %s staggers for a moment.", mname);
            }
            else if (save(VS_MAGIC))
            {
                msg("You feel dizzy for a moment, but it quickly passes.");

                if (rnd(100) < 67)
                    turn_off(*tp, CANHUH);
            }
            else if (off(player, ISCLEAR))
            {
                if (off(player, ISHUH))
                {
                    light_fuse(FUSE_UNCONFUSE, 0, rnd(20) + HUHDURATION, AFTER);
                    msg("The %s's gaze has confused you.", mname);
                    turn_on(player, ISHUH);
                }
                else
                    lengthen_fuse(FUSE_UNCONFUSE, rnd(20) + HUHDURATION);
            }
        }

        if (on(*tp, CANSNORE))      /* Sleep */
        {
            if (on(player, CANREFLECT))
            {
                msg("You reflect the lethargic glance of the %s", mname);

                if (save_throw(VS_PARALYZATION, tp))
                {
                    msg("The %s falls asleep!", mname);
                    tp->t_no_move += SLEEPTIME;
                }
            }
            else if (no_command == 0 && !save(VS_PARALYZATION))
            {
                if (is_wearing(R_ALERT))
                    msg("You feel slightly drowsy for a moment.");
                else
                {
                    msg("The %s's gaze puts you to sleep.", mname);
                    no_command = SLEEPTIME;

                    if (rnd(100) < 50)
                        turn_off(*tp, CANSNORE);
                }
            }
        }

        if (on(*tp, CANFRIGHTEN))   /* Fear */
        {
            turn_off(*tp, CANFRIGHTEN);

            if (on(player, CANREFLECT))
            {
                msg("The %s sees its reflection. ", mname);

                if (save_throw(VS_MAGIC,tp))
                {
                    msg("The %s is terrified by its reflection!", mname);
                    turn_on(*tp, ISFLEE);
                }
            }
            else
            {
                if (!save(VS_WAND) && !(on(player, ISFLEE) &&
                       (player.t_chasee==tp)))
                {
                    if ((player.t_ctype != C_PALADIN) &&
                        off(player, SUPERHERO))
                    {
                        turn_on(player, ISFLEE);
                        player.t_ischasing = FALSE;
                        player.t_chasee    = tp;
                        msg("The sight of the %s terrifies you.", mname);
                    }
                    else
                        msg("My, the %s looks ugly.", mname);
                }
            }
        }

        if (on(*tp, LOOKSLOW))     /* Slow */
        {
            turn_off(*tp, LOOKSLOW);

            if (on(player, CANREFLECT))
            {
                msg("You reflect the mournful glare of the %s.", mname);

                if (save_throw(VS_MAGIC,tp))
                {
                    msg("The %s is slowing down!", mname);
                    turn_on(*tp, ISSLOW);
                }
            }
            else if (is_wearing(R_FREEDOM) || save(VS_MAGIC))
                msg("You feel run-down for a moment.");
            else
            {
                if (on(player, ISHASTE))    /* Already sped up */
                {
                    extinguish_fuse(FUSE_NOHASTE);
                    nohaste(NULL);
                }
                else
                {
                    msg("You feel yourself moving %sslower.",
                     on(player, ISSLOW) ? "even " : "");

                    if (on(player, ISSLOW))
                        lengthen_fuse(FUSE_NOSLOW, rnd(4) + 4);
                    else
                    {
                        turn_on(player, ISSLOW);
                        player.t_turn = TRUE;
                        light_fuse(FUSE_NOSLOW, 0, rnd(4) + 4, AFTER);
                    }
                }
            }
        }

        if (on(*tp, CANBLIND))  /* Blinding */
        {
            turn_off(*tp, CANBLIND);

            if (on(player, CANREFLECT))
            {
                msg("You reflect the blinding stare of the %s.", mname);

                if (save_throw(VS_WAND, tp))
                {
                    msg("The %s is blinded!", mname);
                    turn_on(*tp, ISHUH);
                }
            }
            else if (off(player, ISBLIND))
                if (save(VS_WAND) || is_wearing(R_TRUESEE) || is_wearing(R_SEEINVIS))
                    msg("Your eyes film over for a moment.");
                else
                {
                    msg("The gaze of the %s blinds you.", mname);
                    turn_on(player, ISBLIND);
                    light_fuse(FUSE_SIGHT, 0, rnd(30) + 20, AFTER);
                    look(FALSE);
                }
        }

        if (on(*tp, LOOKSTONE))  /* Stoning */
        {
            turn_off(*tp, LOOKSTONE);

            if (on(player, CANREFLECT))
            {
                msg("You reflect the flinty look of the %s.", mname);

                if (save_throw(VS_PETRIFICATION,tp))
                {
                    msg("The %s suddenly stiffens", mname);
                    tp->t_no_move += STONETIME;
                }
                else
                {
                    msg("The %s is turned to stone!", mname);
                    killed(&player, it, NOMESSAGE, POINTS);
                }
            }
            else
            {
                if (on(player, CANINWALL))
                    msg("The %s cannot focus on you.", mname);
                else
                {
                    msg("The gaze of the %s stiffens your limbs.", mname);

                    if (save(VS_PETRIFICATION))
                        no_command = STONETIME;
                    else if (rnd(100))
                        no_command = STONETIME * 3;
                    else
                    {
                        msg("The gaze of the %s petrifies you.", mname);
                        msg("You are turned to stone!!! --More--");
                        wait_for(' ');
                        death(D_PETRIFY);
                        return(it);
                    }
                }
            }
        }
    }

    /*
     * True Sight sees all Never see ISINWALL or CANSURPRISE See ISSHADOW
     * 80% See ISINVIS with See Invisibilty
     */

    if (off(player, CANTRUESEE) &&
        on(*tp, ISINWALL) || on(*tp, CANSURPRISE) ||
        (on(*tp, ISSHADOW) && rnd(100) < 80) ||
        (on(*tp, ISINVIS) && off(player, CANSEE)))
	{
	    /* 
	    TODO: incomplete - need to finish logic
	    int ch = mvwinch(stdscr, y, x); 
	    */
	}
	

    /* hero might be able to hear or smell monster if he can't see it */

    if ((rnd(player.t_ctype == C_THIEF ? 40 : 200) == 0 ||
            on(player, CANHEAR)) && !cansee(tp->t_pos.y, tp->t_pos.x))
        msg("You hear a %s nearby.", mname);
    else if ((rnd(player.t_ctype == C_THIEF ? 40 : 200) == 0 ||
            on(player, CANSCENT)) && !cansee(tp->t_pos.y, tp->t_pos.x))
        msg("You smell a %s nearby.", mname);

    return(it);
}
Пример #8
0
void
sell(struct thing *tp)
{
    struct linked_list  *item;
    int i, j, min_worth, nitems, chance, which_item, w;
    char goods;
    struct object   *obj;
    char    buffer[2 * LINELEN];
    char    dbuf[2 * LINELEN];

    struct
    {
        int which;
        int plus1, plus2;
        int count;
        int worth;
        int flags;
        char    *name;
    }
    selection[SELL_ITEMS];

    int effective_purse = ((player.t_ctype == C_PALADIN) ?
                   (9 * purse / 10) : purse);

    min_worth = -1;     /* hope item is never worth less than this */
    item = find_mons(tp->t_pos.y, tp->t_pos.x); /* Get pointer to monster */

    /* Select the items */

    nitems = rnd(6) + 5;

    switch (rnd(6))
    {
        /* Armor */
        case 0:
        case 1:
            goods = ARMOR;
            for (i = 0; i < nitems; i++)
            {
                chance = rnd(100);

                for (j = 0; j < maxarmors; j++)
                    if (chance < armors[j].a_prob)
                        break;

                if (j == maxarmors)
                {
                    debug("Picked a bad armor %d", chance);
                    j = 0;
                }

                selection[i].which = j;
                selection[i].count = 1;

                if (rnd(100) < 40)
                    selection[i].plus1 = rnd(5) + 1;
                else
                    selection[i].plus1 = 0;

                selection[i].name = armors[j].a_name;

                switch (luck)
                {
                    case 0: break;
                    case 1:
                        if (rnd(3) == 0)
                        {
                            selection[i].flags |=  ISCURSED;
                            selection[i].plus1 =  -1 - rnd(5);
                        }
                        break;

                    default:
                        if (rnd(luck))
                        {
                            selection[i].flags |= ISCURSED;
                            selection[i].plus1 =  -1 - rnd(5);
                        }
                        break;
                }

                /* Calculate price */

                w = armors[j].a_worth;
                w *= (1 + luck + (10 * selection[i].plus1));
                w = (w / 2) + (roll(6, w) / 6);
                selection[i].worth = max(w, 25);

                if (min_worth > selection[i].worth || i == 1)
                    min_worth = selection[i].worth;
            }
            break;

            /* Weapon */
        case 2:
        case 3:
            goods = WEAPON;
            for (i = 0; i < nitems; i++)
            {
                selection[i].which = rnd(maxweapons);
                selection[i].count = 1;

                if (rnd(100) < 35)
                {
                    selection[i].plus1 = rnd(3);
                    selection[i].plus2 = rnd(3);
                }
                else
                {
                    selection[i].plus1 = 0;
                    selection[i].plus2 = 0;
                }

                if (weaps[selection[i].which].w_flags & ISMANY)
                    selection[i].count = rnd(15) + 8;

                selection[i].name = weaps[selection[i].which].w_name;

                switch (luck)
                {
                    case 0: break;
                    case 1:
                        if (rnd(3) == 0)
                        {
                            selection[i].flags |= ISCURSED;
                            selection[i].plus1 =  -rnd(3);
                            selection[i].plus2 =  -rnd(3);
                        }
                        break;

                    default:
                        if (rnd(luck))
                        {
                            selection[i].flags |= ISCURSED;
                            selection[i].plus1 =  -rnd(3);
                            selection[i].plus2 =  -rnd(3);
                        }
                        break;
                }

                w = weaps[selection[i].which].w_worth * selection[i].count;
                w *= (1 + luck + (10 * selection[i].plus1 +
                          10 * selection[i].plus2));
                w = (w / 2) + (roll(6, w) / 6);
                selection[i].worth = max(w, 25);

                if (min_worth > selection[i].worth || i == 1)
                    min_worth = selection[i].worth;
            }
            break;

            /* Staff or wand */
        case 4:
            goods = STICK;

            for (i = 0; i < nitems; i++)
            {
                selection[i].which = pick_one(ws_magic, maxsticks);
                selection[i].plus1 = rnd(11) + 5;
                selection[i].count = 1;
                selection[i].name = ws_magic[selection[i].which].mi_name;

                switch (luck)
                {
                    case 0: break;
                    case 1:
                        if (rnd(3) == 0)
                        {
                            selection[i].flags |= ISCURSED;
                            selection[i].plus1 = 1;
                        }
                        break;

                    default:
                        if (rnd(luck))
                        {
                            selection[i].flags |= ISCURSED;
                            selection[i].plus1 = 1;
                        }
                }

                w = ws_magic[selection[i].which].mi_worth;
                w += (luck + 1) * 20 * selection[i].plus1;
                w = (w / 2) + (roll(6, w) / 6);
                selection[i].worth = max(w, 25);

                if (min_worth > selection[i].worth || i == 1)
                    min_worth = selection[i].worth;
            }
            break;

            /* Ring */

        case 5:
            goods = RING;
            for (i = 0; i < nitems; i++)
            {
                selection[i].which = pick_one(r_magic, maxrings);
                selection[i].plus1 = rnd(2) + 1;
                selection[i].count = 1;

                if (rnd(100) < r_magic[selection[i].which].mi_bless + 10)
                    selection[i].plus1 += rnd(2) + 1;

                selection[i].name = r_magic[selection[i].which].mi_name;

                switch (luck)
                {
                    case 0: break;
                    case 1:
                        if (rnd(3) == 0)
                        {
                            selection[i].flags |= ISCURSED;
                            selection[i].plus1 =  -1 - rnd(2);
                        }
                        break;

                    default:
                        if (rnd(luck))
                        {
                            selection[i].flags |= ISCURSED;
                            selection[i].plus1 =  -1 - rnd(2);
                        }
                }

                w = r_magic[selection[i].which].mi_worth;

                switch(selection[i].which)
                {
                    case R_DIGEST:
                        if (selection[i].plus1 > 2)
                            selection[i].plus1 = 2;
                        else if (selection[i].plus1 < 1)
                            selection[i].plus1 = 1;
                    /* fall thru here to other cases */
                    case R_ADDSTR:
                    case R_ADDDAM:
                    case R_PROTECT:
                    case R_ADDHIT:
                    case R_ADDINTEL:
                    case R_ADDWISDOM:
                        if (selection[i].plus1 > 0)
                            w += selection[i].plus1 * 50;
                }

                w *= (1 + luck);
                w = (w / 2) + (roll(6, w) / 6);
                selection[i].worth = max(w, 25);

                if (min_worth > selection[i].worth * selection[i].count)
                    min_worth = selection[i].worth;
            }
    }

    /* See if player can afford an item */

    if (min_worth > effective_purse)
    {
        msg("The %s eyes your small purse and departs.",
            monsters[nummonst].m_name);

        /* Get rid of the monster */

        killed(NULL, item, NOMESSAGE, NOPOINTS);

        return;
    }

    /* Display the goods */

    msg("The %s shows you his wares.", monsters[nummonst].m_name);
    wstandout(cw);
    mvwaddstr(cw, 0, mpos, morestr);
    wstandend(cw);
    wrefresh(cw);
    wait_for(' ');
    msg("");
    clearok(cw, TRUE);
    touchwin(cw);

    wclear(hw);
    touchwin(hw);

    for (i = 0; i < nitems; i++)
    {
        if (selection[i].worth > effective_purse)
            continue;

        wmove(hw, i + 2, 0);
        sprintf(dbuf, "[%c] ", ('a' + i));

        switch(goods)
        {
            case ARMOR:
                strcat(dbuf, "Some ");
                break;
            case WEAPON:
                if (selection[i].count == 1)
                    strcat(dbuf, "A ");
                else
                {
                    sprintf(buffer, "%2d ", selection[i].count);
                    strcat(dbuf, buffer);
                }
                break;

            case STICK:
                strcat(dbuf, "A ");
                strcat(dbuf, ws_type[selection[i].which]);
                strcat(dbuf, " of ");
                break;

            case RING:
                strcat(dbuf, "A ring of ");
                break;
        }

        strcat(dbuf, selection[i].name);

        if (selection[i].count > 1)
            strcat(dbuf, "s");

        sprintf(buffer, "%-50s Price:  %d", dbuf, selection[i].worth);
        waddstr(hw, buffer);
    }

    sprintf(buffer, "Purse:  %d", purse);
    mvwaddstr(hw, nitems + 3, 0, buffer);
    mvwaddstr(hw, 0, 0, "How about one of the following goods? ");
    wrefresh(hw);

    /* Get rid of the monster */

    killed(NULL, item, NOMESSAGE, NOPOINTS);

    which_item = (short) ((readchar() & 0177) - 'a');

    while (which_item < 0 || which_item >= nitems ||
        selection[which_item].worth > effective_purse)
    {
        if (which_item == (short) ESCAPE - (short) 'a')
            return;

        mvwaddstr(hw, 0, 0, "Please enter one of the listed items: ");
        wrefresh(hw);
        which_item = (short) ((readchar() & 0177) - 'a');
    }

    if (purse > selection[which_item].worth)
         purse -= selection[which_item].worth;
    else
         purse = 0L;

    item = spec_item(goods, selection[which_item].which,
          selection[which_item].plus1, selection[which_item].plus2);

    obj = OBJPTR(item);

    if (selection[which_item].count > 1)
    {
        obj->o_count = selection[which_item].count;
        obj->o_group = ++group;
    }

    /* If a stick or ring, let player know the type */

    switch (goods)
    {
        case STICK: know_items[TYP_STICK][selection[which_item].which] = TRUE;
                    break;
        case RING:  know_items[TYP_RING][selection[which_item].which] = TRUE;
                    break;
    }

    if (add_pack(item, MESSAGE) == FALSE)
    {
        obj->o_pos = hero;
        fall(&player, item, TRUE, FALSE);
    }
}
Пример #9
0
void
look(int wakeup)
{
    int     x, y;
    char   ch, och;
    int  oldx, oldy;
    int inpass, horizontal, vertical, do_light = FALSE, do_blank = FALSE;
    int passcount = 0;
    struct room *rp;
    int ey, ex;

    /* Are we moving vertically or horizontally? */

    if (runch == 'h' || runch == 'l')
        horizontal = TRUE;
    else
        horizontal = FALSE;

    if (runch == 'j' || runch == 'k')
        vertical = TRUE;
    else
        vertical = FALSE;

    getyx(cw, oldy, oldx);  /* Save current position */

    /*
     * Blank out the floor around our last position and check for moving
     * out of a corridor in a maze.
    */

    if (oldrp != NULL && (oldrp->r_flags & ISDARK) &&
            !(oldrp->r_flags & HASFIRE) && off(player, ISBLIND))
        do_blank = TRUE;

    for (x = player.t_oldpos.x - 1; x <= player.t_oldpos.x + 1; x++)
        for (y = player.t_oldpos.y - 1; y <= player.t_oldpos.y + 1;
                y++)
        {
            ch = show(y, x);

            if (do_blank && (y != hero.y || x != hero.x) && ch == FLOOR)
                mvwaddch(cw, y, x, ' ');

            /* Moving out of a corridor? */

            if (levtype == MAZELEV &&
                    (ch != '|' && ch != '-') && /* Not a wall */
                    ((vertical && x != player.t_oldpos.x &&
                      y == player.t_oldpos.y) ||
                     (horizontal && y != player.t_oldpos.y &&
                      x == player.t_oldpos.x)))
                do_light = TRUE;    /* Just came to a turn */
        }

    inpass = ((rp = roomin(hero)) == NULL);    /* Are we in a passage? */

    /* Are we coming out of a wall into a corridor in a maze? */
    och = show(player.t_oldpos.y, player.t_oldpos.x);
    ch = show(hero.y, hero.x);

    if (levtype == MAZELEV && (och == '|' || och == '-' ||
                               och == SECRETDOOR) && (ch != '|' && ch != '-' && ch != SECRETDOOR))
    {
        do_light = off(player, ISBLIND);    /* Light it up if not blind */
    }

    /* Look around the player */

    ey = hero.y + 1;
    ex = hero.x + 1;

    for (x = hero.x - 1; x <= ex; x++)
        if (x >= 0 && x < COLS)
            for (y = hero.y - 1; y <= ey; y++)
            {
                if (y <= 0 || y >= LINES - 2)
                    continue;

                if (isalpha(mvwinch(mw, y, x)))
                {
                    struct linked_list  *it;
                    struct thing    *tp;

                    if (wakeup)
                        it = wake_monster(y, x);
                    else
                        it = find_mons(y, x);

                    if (it == NULL)
                        continue;

                    tp = THINGPTR(it);
                    tp->t_oldch = CCHAR( mvinch(y, x) );

                    if (isatrap(tp->t_oldch))
                    {
                        struct trap *trp = trap_at(y, x);

                        tp->t_oldch = (trp->tr_flags & ISFOUND) ? tp->t_oldch
                                      : trp->tr_show;
                    }

                    if (tp->t_oldch == FLOOR &&
                            (rp->r_flags & ISDARK)
                            && !(rp->r_flags & HASFIRE) &&
                            off(player, ISBLIND))
                        tp->t_oldch = ' ';
                }

                /* Secret doors show as walls */

                if ((ch = show(y, x)) == SECRETDOOR)
                    ch = secretdoor(y, x);

                /*
                 * Don't show room walls if he is in a
                 * passage and check for maze turns
                */

                if (off(player, ISBLIND))
                {
                    if (y == hero.y && x == hero.x || (inpass && (ch == '-' ||
                                                       ch == '|')))
                        continue;

                    /* Are we at a crossroads in a maze? */

                    if (levtype == MAZELEV && (ch != '|' && ch != '-') &&
                            /* Not a wall */
                            ((vertical && x != hero.x && y == hero.y) ||
                             (horizontal && y != hero.y && x == hero.x)))
                        do_light = TRUE;
                    /* Just came to a turn */
                }
                else if (y != hero.y || x != hero.x)
                    continue;

                wmove(cw, y, x);
                waddch(cw, ch);

                if (door_stop && !firstmove && running)
                {
                    switch (runch)
                    {
                    case 'h':
                        if (x == ex)
                            continue;
                        break;
                    case 'j':
                        if (y == hero.y - 1)
                            continue;
                        break;
                    case 'k':
                        if (y == ey)
                            continue;
                        break;
                    case 'l':
                        if (x == hero.x - 1)
                            continue;
                        break;
                    case 'y':
                        if ((x + y) - (hero.x + hero.y) >= 1)
                            continue;
                        break;
                    case 'u':
                        if ((y - x) - (hero.y - hero.x) >= 1)
                            continue;
                        break;
                    case 'n':
                        if ((x + y) - (hero.x + hero.y) <= -1)
                            continue;
                        break;
                    case 'b':
                        if ((y - x) - (hero.y - hero.x) <= -1)
                            continue;
                        break;
                    }

                    switch (ch)
                    {
                    case DOOR:
                        if (x == hero.x || y == hero.y)
                            running = FALSE;
                        break;
                    case PASSAGE:
                        if (x == hero.x || y == hero.y)
                            passcount++;
                        break;
                    case FLOOR:

                        /*
                         * Stop by new passages in a
                         * maze (floor next to us)
                         */
                        if ((levtype == MAZELEV) &&
                                ((horizontal && x == hero.x && y != hero.y) ||
                                 (vertical &&   y == hero.y && x != hero.x)))
                            running = FALSE;

                    case '|':
                    case '-':
                    case ' ':
                        break;

                    default:
                        running = FALSE;
                        break;
                    }
                }
            }

    if (door_stop && !firstmove && passcount > 1)
        running = FALSE;

    /*
     * Do we have to light up the area (just stepped into a new
     * corridor)?
     */

    if (do_light && wakeup &&   /* wakeup will be true on a normal move */
            !(rp->r_flags & ISDARK) &&  /* We have some light */
            !ce(hero, player.t_oldpos)) /* Don't do anything if we didn't move */
        light(&hero);

    mvwaddch(cw, hero.y, hero.x, PLAYER);
    wmove(cw, oldy, oldx);

    if (wakeup)
    {
        player.t_oldpos = hero; /* Don't change if we didn't move */
        oldrp = rp;
    }
}
Пример #10
0
/*
 * read_scroll:
 *	Let the hero read a scroll
 */
int read_scroll()
{
	struct object *obj;
	struct linked_list *item;
	int i, j, wh;
	unsigned long ch, nch;
	struct room *rp;
	struct linked_list *titem;
	char buf[LINLEN];
	bool bless, curse;

	if ((item = get_item("read", SCROLL)) == NULL)
		return 0;
	obj = OBJPTR(item);
	if (obj->o_type != SCROLL) {
		msg("Nothing to read.");
		after = FALSE;
		return 0;
	}
	msg("As you read the scroll, it vanishes.");
	wh = obj->o_which;
	bless = o_on(obj, ISBLESS);
	curse = o_on(obj, ISCURSED);
	del_pack(item);		/* Get rid of the thing */

	/*
	 * Calculate the effect it has on the hero
	 */
	switch(wh) {
	case S_KNOWALL:
		if (!curse) {
			idenpack();				/* identify all the pack */
			msg("You feel more knowledgable.");
			chg_abil(WIS,1,TRUE);
			s_know[S_KNOWALL] = TRUE;
		}
	when S_CONFUSE:
		if (!curse) {
			/*
			 * Scroll of monster confusion.  Give him that power.
			 */
			msg("Your hands begin to glow red.");
			player.t_flags |= CANHUH;
			s_know[S_CONFUSE] = TRUE;
		}
	when S_LIGHT:
		rp = player.t_room;
		if (!curse) {
			if (rp == NULL) {
				s_know[S_LIGHT] = TRUE;
				msg("The corridor glows and then fades.");
			}
			else {
				if (rf_on(rp,ISDARK)) {
					s_know[S_LIGHT] = TRUE;
					msg("The room is lit.");
					rp->r_flags &= ~ISDARK;
				}
				light(&hero);
				mvwaddch(cw, hero.y, hero.x, PLAYER);
			}
		}
	when S_ARMOR:
		if (!curse) {
			if (cur_armor != NULL && o_off(cur_armor,ISPROT)) {
				s_know[S_ARMOR] = TRUE;
				msg("Your armor glows faintly for a moment.");
				if (o_on(cur_armor,ISCURSED))
					cur_armor->o_ac = armors[cur_armor->o_which].a_class;
				else
					cur_armor->o_ac--;
				resoflg(cur_armor,ISCURSED);
			}
		}
	when S_HOLD:
		if (!curse) {
			/*
			 * Hold monster scroll.  Stop all monsters within 3 spaces
			 * from chasing after the hero.
			 */
			int x,y;
			struct linked_list *mon;

			for (x = hero.x - 3; x <= hero.x + 3; x++) {
				for (y = hero.y - 3; y <= hero.y + 3; y++) {
					if (y > 0 && x > 0 && isalpha(mvwinch(mw, y, x))) {
						if ((mon = find_mons(y, x)) != NULL) {
							struct thing *th;

							th = THINGPTR(mon);
							th->t_flags &= ~ISRUN;
							th->t_flags |= ISHELD;
							th->t_flags |= ISSTUCK;
						}
					}
				}
			}
		}
	when S_SLEEP:
		/*
		 * Scroll which makes you fall asleep
		 */
		if (!bless) {
			s_know[S_SLEEP] = TRUE;
			msg("You fall asleep.");
			player.t_nocmd += 4 + rnd(SLEEPTIME);
		}
	when S_CREATE:
		if (!bless) {
			if (makemons(mtlev[rnd(levcount)]->m_show))
				s_know[S_CREATE] = TRUE;
			else
				msg("You hear a faint cry of anguish in the distance.");
		}
	when S_IDENT:
		if (!curse) {
			msg("This scroll is an identify scroll");
			s_know[S_IDENT] = TRUE;
			whatis(NULL);
		}
	when S_MAP:
		if (curse)
			break;
		s_know[S_MAP] = TRUE;
		addmsg("Oh, now this scroll has a ");
		if (rnd(100) < 10 || bless) {
			addmsg("very detailed map on it.");
			endmsg();
			displevl();
		}
		else {
			addmsg("map on it.");
			endmsg();
			overwrite(stdscr, hw);
			for (i = 1; i < LINES - 2; i++) {
				for (j = 0; j < COLS; j++) {
					switch (nch = ch = mvwinch(hw, i, j)) {
						case SECRETDOOR:
							nch = DOOR;
							mvaddch(i, j, nch);
						case '-':
						case '|':
						case DOOR:
						case PASSAGE:
						case ' ':
						case STAIRS:
							if (mvwinch(mw, i, j) != ' ') {
								struct thing *it;
								struct linked_list *blah;

								blah = find_mons(i, j);
								if (blah != NULL) {
									it = THINGPTR(blah);
									if (it->t_oldch == ' ')
										it->t_oldch = nch;
								}
							}
							break;
						default:
							nch = ' ';
					}
					if (nch != ch)
						waddch(hw, nch);
				}
			}
			overlay(cw, hw);
			overwrite(hw, cw);
		}
	when S_GFIND:
		if (!curse) {
			int gtotal = 0;
			struct room *rp;

			wclear(hw);
			for (rp = rooms; rp < &rooms[MAXROOMS]; rp++) {
				gtotal += rp->r_goldval;
				if (rp->r_goldval != 0 &&
				  mvinch(rp->r_gold.y,rp->r_gold.x) == GOLD)
					mvwaddch(hw,rp->r_gold.y,rp->r_gold.x,GOLD);
			}
			if (gtotal) {
				s_know[S_GFIND] = TRUE;
				msg("You begin to feel greedy and sense gold.");
				overlay(hw,cw);
			}
			else
				msg("You begin to feel a pull downward.");
		}
	when S_TELEP:
		if (!curse) {
			int rm;
			struct room *cur_room;

			cur_room = player.t_room;
			rm = teleport(rndspot, &player);
			if (cur_room != &rooms[rm])
				s_know[S_TELEP] = TRUE;
		}
	when S_ENCH:
		if (!curse) {
			if (cur_weapon == NULL || (cur_weapon != NULL &&
			  (o_on(cur_weapon,ISPROT) || cur_weapon->o_type != WEAPON)))
				msg("You feel a strange sense of loss.");
			else {
				s_know[S_ENCH] = TRUE;
				if (o_on(cur_weapon,ISCURSED)) {
					resoflg(cur_weapon,ISCURSED);
					cur_weapon->o_hplus = rnd(2);
					cur_weapon->o_dplus = rnd(2);
				}
				else {		/* weapon was not cursed here */
					if (rnd(100) < 50)
						cur_weapon->o_hplus += 1;
					else
						cur_weapon->o_dplus += 1;
				}
				setoflg(cur_weapon, ISKNOW);
				msg("Your %s glows blue for a moment.",
				  w_magic[cur_weapon->o_which].mi_name);
			}
		}
	when S_SCARE:
		/*
		 * A monster will refuse to step on a scare monster scroll
		 * if it is dropped.  Thus reading it is a mistake and produces
		 * laughter at the poor rogue's boo boo.
		 */
		msg("You hear maniacal laughter in the distance.");
	when S_REMOVE:
		if (!curse) {
			if (cur_armor != NULL && o_off(cur_armor,ISPROT))
				resoflg(cur_armor,ISCURSED);
			if (cur_weapon != NULL && o_off(cur_weapon,ISPROT))
				resoflg(cur_weapon,ISCURSED);
			if (cur_ring[LEFT]!=NULL && o_off(cur_ring[LEFT],ISPROT))
				resoflg(cur_ring[LEFT],ISCURSED);
			if (cur_ring[RIGHT]!=NULL && o_off(cur_ring[RIGHT],ISPROT))
				resoflg(cur_ring[RIGHT],ISCURSED);
			msg("You feel as if somebody is watching over you.");
			s_know[S_REMOVE] = TRUE;
		}
	when S_AGGR:
		if (!bless) {
			if (mlist != NULL) {
				aggravate();
				msg("You hear a high pitched humming noise.");
				s_know[S_AGGR] = TRUE;
			}
		}
	when S_NOP:
		msg("This scroll seems to be blank.");
	when S_GENOCIDE:
		if (!curse) {
			msg("You have been granted the boon of genocide.");
			genocide();
			s_know[S_GENOCIDE] = TRUE;
		}
	when S_DCURSE:
		if (!bless) {
			struct linked_list *ll;
			struct object *lb;

			msg("Your pack shudders.");
			for (ll = pack ; ll != NULL ; ll = next(ll)) {
				lb = OBJPTR(ll);
				if (o_off(lb,ISPROT)) {
					resoflg(lb, ISBLESS);
					setoflg(lb, ISCURSED);
				}
			}
		}
	when S_DLEVEL:
		if (!bless) {
			int much = rnd(9) - 4;

			if (much != 0) {
				level += much;
				if (level < 1)
					level = 1;
				mpos = 0;
				new_level(NORMLEV);		/* change levels */
				msg("You are whisked away to another region.");
				s_know[S_DLEVEL] = TRUE;
			}
		}
	when S_PROTECT:
		if (!curse) {
			struct linked_list *ll;
			struct object *lb;

			msg("You are granted the power of protection.");
			if ((ll = get_item("protect",0)) != NULL) {
				lb = OBJPTR(ll);
				setoflg(lb,ISPROT);
				mpos = 0;
				msg("Protected %s.",inv_name(lb,TRUE));
			}
			s_know[S_PROTECT] = TRUE;
		}
	when S_ALLENCH:
		if (!curse) {
			struct linked_list *ll;
			struct object *lb;
			int howmuch, ac, good;

			msg("You are granted the power of enchantment.");
			good = TRUE;
			if ((ll = get_item("enchant",0)) != NULL) {
				lb = OBJPTR(ll);
				resoflg(lb,ISCURSED);
				resoflg(lb,ISPROT);
				howmuch = rnd(3) + 1;
				switch(lb->o_type) {
					case RING:
						if (lb->o_ac < 0)
							lb->o_ac = 0;
						lb->o_ac += howmuch;
					when ARMOR:
						ac = armors[lb->o_which].a_class;
						if (lb->o_ac > ac)
							lb->o_ac = ac;
						lb->o_ac -= howmuch;
					when STICK:
						lb->o_charges += howmuch + 10;
					when WEAPON:
						if (lb->o_dplus < 0)
							lb->o_dplus = 0;
						if (lb->o_hplus < 0)
							lb->o_hplus = 0;
						lb->o_hplus += howmuch;
						lb->o_dplus += howmuch;
					otherwise:
						msg("You are injured as the scroll flashes & bursts into flames !!!");
						chg_hpt(-roll(6,6),FALSE,K_SCROLL);
						good = FALSE;
				}
				if (good) {
					mpos = 0;
					msg("Enchanted %s.",inv_name(lb,TRUE));
				}
			}
			s_know[S_ALLENCH] = TRUE;
		}
	when S_BLESS:
		if (!curse) {
			struct linked_list *ll;
			struct object *lb;

			msg("Your pack glistens brightly.");
			for (ll = pack ; ll != NULL ; ll = next(ll)) {
				whatis(ll);
				lb = OBJPTR(ll);
				resoflg(lb,ISCURSED);
				setoflg(lb,ISBLESS);
			}
		}
	when S_MAKEIT:
		if (!curse) {
			msg("You have been endowed with the power of creation.");
			s_know[S_MAKEIT] = TRUE;
			create_obj(TRUE);
		}
	when S_BAN: {
		int howdeep;
		char *ptr;

		if (bless) {
			if (level > 6) {
				howdeep = 1 + rnd(5);
				ptr = "elevated to the upper";
			}
			else {
				howdeep = -1;
				bless = FALSE;
			}
		}
		else {
			howdeep = level + 10 + rnd(20) + (curse * 20);
			ptr = "banished to the lower";
		}
		if ((!bless && level < howdeep) || bless) {
			level = howdeep;
			new_level(NORMLEV);
			mpos = 0;
			msg("You are %s regions.", ptr);
			s_know[S_BAN] = TRUE;
		}
	}
	when S_CWAND:
		if (!curse) {
			struct linked_list *ll;
			struct object *lb;
			bool wands = FALSE;

			for (ll = pack ; ll != NULL ; ll = next(ll)) {
				lb = OBJPTR(ll);
				if (lb->o_type == STICK) {
					whatis(ll);
					setoflg(lb, ISKNOW);
					resoflg(lb, ISCURSED);
					lb->o_charges += rnd(11) + 5;
					wands = TRUE;
				}
			}
			if (wands) {
				msg("Your sticks gleam.");
				s_know[wh] = TRUE;
			}
		}
	when S_LOCTRAP: {
		struct trap *trp;

		if (ntraps > 0) {
			for (trp = &traps[0]; trp < &traps[ntraps]; trp++)
				trp->tr_flags |= ISFOUND;
			look(FALSE);
			msg("You now recognize pitfalls.");
			s_know[S_LOCTRAP] = TRUE;
		}
	}
	otherwise:
		msg("What a puzzling scroll!");
		return 0;
	}
Пример #11
0
read_scroll()
{
    register struct object *obj;
    register struct linked_list *item;
    register struct room *rp;
    register int i,j;
    register char ch, nch;
    register struct linked_list *titem;
    char buf[80];

    item = get_item("run", SCROLL);
    if (item == NULL)
	return;
    obj = (struct object *) ldata(item);
    if (obj->o_type != SCROLL)
    {
	if (!terse)
	    msg("There is no way to run it");
	else
	    msg("Nothing to run");
	return;
    }
    msg("As you run the device, it self-destructs.");
    /*
     * Calculate the effect it has on the poor guy.
     */
    if (obj == cur_weapon)
	cur_weapon = NULL;
    switch(obj->o_which)
    {
	when S_CONFUSE:
	    /*
	     * Scroll of monster confusion.  Give him that power.
	     */
	    msg("Your hands begin to glow red");
	    player.t_flags |= CANHUH;
	when S_LIGHT:
	    s_know[S_LIGHT] = TRUE;
	    if ((rp = roomin(&hero)) == NULL)
		msg("The corridor glows and then fades");
	    else
	    {
		addmsg("The room is lit");
		if (!terse)
		    addmsg(" by a shimmering blue light.");
		endmsg();
		rp->r_flags &= ~ISDARK;
		/*
		 * Light the room and put the player back up
		 */
		light(&hero);
		mvwaddch(cw, hero.y, hero.x, PLAYER);
	    }
	when S_ARMOR:
	    if (cur_armor != NULL)
	    {
		msg("Your armor glows faintly for a moment");
		cur_armor->o_ac--;
		cur_armor->o_flags &= ~ISCURSED;
	    }
	when S_HOLD:
	    /*
	     * Hold monster scroll.  Stop all monsters within two spaces
	     * from chasing after the hero.
	     */
	    {
		register int x,y;
		register struct linked_list *mon;

		for (x = hero.x-2; x <= hero.x+2; x++)
		    for (y = hero.y-2; y <= hero.y+2; y++)
			if (y > 0 && x > 0 && isupper(mvwinch(mw, y, x)))
			    if ((mon = find_mons(y, x)) != NULL)
			    {
				register struct thing *th;

				th = (struct thing *) ldata(mon);
				th->t_flags &= ~ISRUN;
				th->t_flags |= ISHELD;
			    }
	    }
	when S_SLEEP:
	    /*
	     * Scroll which makes you fall asleep
	     */
	    s_know[S_SLEEP] = TRUE;
	    msg("You fall asleep.");
	    no_command += 4 + rnd(SLEEPTIME);
	when S_CREATE:
	    /*
	     * Create a monster
	     * First look in a circle around him, next try his room
	     * otherwise give up
	     */
	    {
		register int x, y;
		register bool appear = 0;
		coord mp;

		/*
		 * Search for an open place
		 */
		for (y = hero.y; y <= hero.y+1; y++)
		    for (x = hero.x; x <= hero.x+1; x++)
		    {
			/*
			 * Don't put a monster in top of the player.
			 */
			if (y == hero.y && x == hero.x)
			    continue;
			/*
			 * Or anything else nasty
			 */
			if (step_ok(winat(y, x)))
			{
			    if (rnd(++appear) == 0)
			    {
				mp.y = y;
				mp.x = x;
			    }
			}
		    }
		if (appear)
		{
		    titem = new_item(sizeof (struct thing));
		    new_monster(titem, randmonster(FALSE), &mp);
		}
		else
		    msg("You hear a faint cry of anguish in the distance.");
	    }
	when S_IDENT:
	    /*
	     * Identify, let the rogue figure something out
	     */
	    msg("This nanodevice is an identify nanodevice");
	    s_know[S_IDENT] = TRUE;
	    whatis();
	when S_MAP:
	    /*
	     * Scroll of magic mapping.
	     */
	    s_know[S_MAP] = TRUE;
	    msg("Oh, now this nanodevice has a map on it.");
	    overwrite(stdscr, hw);
	    /*
	     * Take all the things we want to keep hidden out of the window
	     */
	    for (i = 0; i < lines(); i++)
		for (j = 0; j < cols(); j++)
		{
		    switch (nch = ch = mvwinch(hw, i, j))
		    {
			case SECRETDOOR:
			    mvaddch(i, j, nch = DOOR);
			case '-':
			case '|':
			case DOOR:
			case PASSAGE:
			case ' ':
			case STAIRS:
			    if (mvwinch(mw, i, j) != ' ')
			    {
				register struct thing *it;

				it = (struct thing *) ldata(find_mons(i, j));
				if (it->t_oldch == ' ')
				    it->t_oldch = nch;
			    }
			    break;
			default:
			    nch = ' ';
		    }
		    if (nch != ch)
			waddch(hw, nch);
		}
	    /*
	     * Copy in what he has discovered
	     */
	    overlay(cw, hw);
	    /*
	     * And set up for display
	     */
	    overwrite(hw, cw);
	when S_GFIND:
	    /*
	     * Potion of gold detection
	     */
	    {
		int gtotal = 0;

		wclear(hw);
		for (i = 0; i < MAXROOMS; i++)
		{
		    gtotal += rooms[i].r_goldval;
		    if (rooms[i].r_goldval != 0 &&
			mvwinch(stdscr, rooms[i].r_gold.y, rooms[i].r_gold.x)
			== GOLD)
			mvwaddch(hw,rooms[i].r_gold.y,rooms[i].r_gold.x,GOLD);
		}
		if (gtotal)
		{
		    s_know[S_GFIND] = TRUE;
		    show_win(hw,
			"You connect to the Net and detect credits locations.--More--");
		}
		else msg("You begin to feel a pull downward");
	    }
	when S_TELEP:
	    /*
	     * Scroll of teleportation:
	     * Make him dissapear and reappear
	     */
	    {
		int rm;
		struct room *cur_room;

		cur_room = roomin(&hero);
		rm = teleport();
		if (cur_room != &rooms[rm])
		    s_know[S_TELEP] = TRUE;
	    }
	when S_ENCH:
	    if (cur_weapon == NULL)
		msg("You feel a strange sense of loss.");
	    else
	    {
		cur_weapon->o_flags &= ~ISCURSED;
		if (rnd(100) > 50)
		    cur_weapon->o_hplus++;
		else
		    cur_weapon->o_dplus++;
		msg("Your %s glows blue for a moment.", w_names[cur_weapon->o_which]);
	    }
	when S_SCARE:
	    /*
	     * A monster will refuse to step on a scare monster scroll
	     * if it is dropped.  Thus reading it is a mistake and produces
	     * laughter at the poor rogue's boo boo.
	     */
	    msg("You hear maniacal laughter in the distance.");
	when S_REMOVE:
	    if (cur_armor != NULL)
		cur_armor->o_flags &= ~ISCURSED;
	    if (cur_weapon != NULL)
		cur_weapon->o_flags &= ~ISCURSED;
	    if (cur_ring[LEFT] != NULL)
		cur_ring[LEFT]->o_flags &= ~ISCURSED;
	    if (cur_ring[RIGHT] != NULL)
		cur_ring[RIGHT]->o_flags &= ~ISCURSED;
	    msg("You feel as if somebody is watching over you.");
	when S_AGGR:
	    /*
	     * This scroll aggravates all the monsters on the current
	     * level and sets them running towards the hero
	     */
	    aggravate();
	    msg("You hear a high pitched humming noise.");
	when S_NOP:
	    msg("This nanodevice seems to be empty.");
	when S_GENOCIDE:
	    msg("You have been granted the boon of genocide");
	    genocide();
	    s_know[S_GENOCIDE] = TRUE;
	otherwise:
	    msg("What a puzzling nanodevice!");
	    return;
    }
    look(TRUE);	/* put the result of the scroll on the screen */
    status();
    if (s_know[obj->o_which] && s_guess[obj->o_which])
    {
	cfree(s_guess[obj->o_which]);
	s_guess[obj->o_which] = NULL;
    }
    else if (!s_know[obj->o_which] && askme && s_guess[obj->o_which] == NULL)
    {
	msg(terse ? "Call it: " : "What do you want to call it? ");
	if (get_str(buf, cw) == NORM)
	{
	    s_guess[obj->o_which] = malloc((unsigned int) strlen(buf) + 1);
	    strcpy(s_guess[obj->o_which], buf);
	}
    }
    /*
     * Get rid of the thing
     */
    inpack--;
    if (obj->o_count > 1)
	obj->o_count--;
    else
    {
	detach(pack, item);
        discard(item);
    }
}