view urogue/things.c @ 309:11aeff9acc07

Advanced Rogue 7: ignore file locations in the save file when restoring. The variables file_name, score_file, and home are no longer overwritten with the values stored in the save file. Those values could be inaccurate if the files have been moved or configuration has changed.
author John "Elwin" Edwards
date Sun, 02 May 2021 21:54:11 -0400
parents 5a94c9b3181e
children
line wrap: on
line source

/*
    things.c - functions for dealing with things like potions and scrolls
                    
    UltraRogue: The Ultimate Adventure in the Dungeons of Doom
    Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong
    All rights reserved.

    Based on "Advanced Rogue"
    Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka
    All rights reserved.

    Based on "Rogue: Exploring the Dungeons of Doom"
    Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
    All rights reserved.

    See the file LICENSE.TXT for full copyright and licensing information.
*/

#include <string.h>
#include <ctype.h>
#include "rogue.h"

/*
    inv_name()
        return the name of something as it would appear in an inventory.
*/

char *
inv_name(struct object *obj, int lowercase)
{
    char *pb;
    char buf[1024];

    switch(obj->o_type)
    {
        case SCROLL:
            if (obj->o_count == 1)
                sprintf(prbuf, "A %s%sscroll ",
                    obj->o_flags & CANRETURN ? "claimed " : "",
                    blesscurse(obj->o_flags));
            else
                sprintf(prbuf, "%d %s%sscrolls ",
                    obj->o_count,
                    obj->o_flags & CANRETURN ? "claimed " : "",
                    blesscurse(obj->o_flags));

            pb = &prbuf[strlen(prbuf)];

            if (know_items[TYP_SCROLL][obj->o_which])
                sprintf(pb, "of %s", s_magic[obj->o_which].mi_name);
            else if (guess_items[TYP_SCROLL][obj->o_which])
                sprintf(pb, "called %s", guess_items[TYP_SCROLL][obj->o_which]);
            else
                sprintf(pb, "titled '%s'", s_names[obj->o_which]);
            break;

        case POTION:
            if (obj->o_count == 1)
                sprintf(prbuf, "A %s%spotion ",
                    obj->o_flags & CANRETURN ? "claimed " : "",
                    blesscurse(obj->o_flags));
            else
                sprintf(prbuf, "%d %s%spotions ",
                    obj->o_count,
                    obj->o_flags & CANRETURN ? "claimed " : "",
                    blesscurse(obj->o_flags));

            pb = &prbuf[strlen(prbuf)];

            if (know_items[TYP_POTION][obj->o_which])
                sprintf(pb, "of %s(%s)", p_magic[obj->o_which].mi_name,
                    p_colors[obj->o_which]);
            else if (guess_items[TYP_POTION][obj->o_which])
                sprintf(pb, "called %s(%s)", guess_items[TYP_POTION][obj->o_which],
                    p_colors[obj->o_which]);
            else
            {
                if (obj->o_count == 1)
                    sprintf(prbuf, "A%s %s potion",
                         obj->o_flags & CANRETURN ? " claimed" :
                        (char *) vowelstr(p_colors[obj->o_which]),
                        p_colors[obj->o_which]);
                else
                    sprintf(prbuf, "%d %s%s potions",
                        obj->o_count,
                     obj->o_flags & CANRETURN ? "claimed " : "",
                        (char *) p_colors[obj->o_which]);
            }
            break;

        case FOOD:
            if (obj->o_count == 1)
                sprintf(prbuf, "A%s %s",
                    obj->o_flags & CANRETURN ? " claimed" :
                    (char *) vowelstr(fd_data[obj->o_which].mi_name),
                    fd_data[obj->o_which].mi_name);
            else
                sprintf(prbuf, "%d %s%ss", obj->o_count,
                    obj->o_flags & CANRETURN ? "claimed " : "",
                    fd_data[obj->o_which].mi_name);
            break;

        case WEAPON:
            if (obj->o_count > 1)
                sprintf(prbuf, "%d ", obj->o_count);
            else if ((obj->o_flags & (ISZAPPED | CANRETURN | ISPOISON | ISSILVER | ISTWOH)) ||
                 ((obj->o_flags & (ISKNOW | ISZAPPED)) == (ISKNOW | ISZAPPED)))
                strcpy(prbuf, "A ");
            else
                sprintf(prbuf, "A%s ", vowelstr(weaps[obj->o_which].w_name));

            pb = &prbuf[strlen(prbuf)];

            if ((obj->o_flags & ISKNOW) && (obj->o_flags & ISZAPPED))
                sprintf(pb, "charged%s ", charge_str(obj,buf));

            pb = &prbuf[strlen(prbuf)];

            if (obj->o_flags & CANRETURN)
                sprintf(pb, "claimed ");

            pb = &prbuf[strlen(prbuf)];

            if (obj->o_flags & ISPOISON)
                sprintf(pb, "poisoned ");

            pb = &prbuf[strlen(prbuf)];

            if (obj->o_flags & ISSILVER)
                sprintf(pb, "silver ");

            if (obj->o_flags & ISTWOH)
                sprintf(pb, "two-handed ");

            pb = &prbuf[strlen(prbuf)];

            if (obj->o_flags & ISKNOW)
                sprintf(pb, "%s %s", num(obj->o_hplus, obj->o_dplus, buf),
                weaps[obj->o_which].w_name);
            else
                sprintf(pb, "%s", weaps[obj->o_which].w_name);

            if (obj->o_count > 1)
                strcat(prbuf, "s");

            break;

        case ARMOR:
            if (obj->o_flags & ISKNOW)
                sprintf(prbuf, "%s%s %s",
                    obj->o_flags & CANRETURN ? "claimed " : "",
                   num(armors[obj->o_which].a_class - obj->o_ac, 0, buf),
                    armors[obj->o_which].a_name);
            else
                sprintf(prbuf, "%s%s",
                    obj->o_flags & CANRETURN ? "claimed " : "",
                    armors[obj->o_which].a_name);

            break;

        case ARTIFACT:
            sprintf(prbuf, "the %s", arts[obj->o_which].ar_name);

            if (obj->o_flags & CANRETURN)
                strcat(prbuf, " (claimed)");

            break;

        case STICK:
            sprintf(prbuf, "A %s%s%s ",
                obj->o_flags & CANRETURN ? "claimed " : "",
                blesscurse(obj->o_flags), ws_type[obj->o_which]);

            pb = &prbuf[strlen(prbuf)];

            if (know_items[TYP_STICK][obj->o_which])
                sprintf(pb, "of %s%s(%s)", ws_magic[obj->o_which].mi_name,
                    charge_str(obj,buf), ws_made[obj->o_which]);
            else if (guess_items[TYP_STICK][obj->o_which])
                sprintf(pb, "called %s(%s)", guess_items[TYP_STICK][obj->o_which],
                    ws_made[obj->o_which]);
            else
                sprintf(&prbuf[2], "%s%s %s",
                    obj->o_flags & CANRETURN ? "claimed " : "",
                    ws_made[obj->o_which],
                    ws_type[obj->o_which]);

            break;

        case RING:
            if (know_items[TYP_RING][obj->o_which])
                sprintf(prbuf, "A%s%s ring of %s(%s)",
                    obj->o_flags & CANRETURN ? " claimed" : "", ring_num(obj,buf),
                    r_magic[obj->o_which].mi_name, r_stones[obj->o_which]);
            else if (guess_items[TYP_RING][obj->o_which])
                sprintf(prbuf, "A %sring called %s(%s)",
                    obj->o_flags & CANRETURN ? "claimed " : "",
                    guess_items[TYP_RING][obj->o_which], r_stones[obj->o_which]);
            else
                sprintf(prbuf, "A%s %s ring",
                    obj->o_flags & CANRETURN ? "claimed " :
                    (char *)vowelstr(r_stones[obj->o_which]),
                    r_stones[obj->o_which]);
            break;

        case GOLD:
            sprintf(prbuf, "%d gold pieces", obj->o_count);
            break;

        default:
            debug("Picked up something funny.");
            sprintf(prbuf, "Something bizarre %s", unctrl(obj->o_type));
            break;
    }

    /* Is it marked? */

    if (obj->o_mark[0])
    {
        pb = &prbuf[strlen(prbuf)];
        sprintf(pb, " <%s>", obj->o_mark);
    }

    if (obj == cur_armor)
        strcat(prbuf, " (being worn)");

    if (obj == cur_weapon)
        strcat(prbuf, " (weapon in hand)");

    if (obj == cur_ring[LEFT_1])
        strcat(prbuf, " (on left hand)");
    else if (obj == cur_ring[LEFT_2])
        strcat(prbuf, " (on left hand)");
    else if (obj == cur_ring[LEFT_3])
        strcat(prbuf, " (on left hand)");
    else if (obj == cur_ring[LEFT_4])
        strcat(prbuf, " (on left hand)");
    else if (obj == cur_ring[LEFT_5])
        strcat(prbuf, " (on left hand)");
    else if (obj == cur_ring[RIGHT_1])
        strcat(prbuf, " (on right hand)");
    else if (obj == cur_ring[RIGHT_2])
        strcat(prbuf, " (on right hand)");
    else if (obj == cur_ring[RIGHT_3])
        strcat(prbuf, " (on right hand)");
    else if (obj == cur_ring[RIGHT_4])
        strcat(prbuf, " (on right hand)");
    else if (obj == cur_ring[RIGHT_5])
        strcat(prbuf, " (on right hand)");

    if (obj->o_flags & ISPROT)
        strcat(prbuf, " [protected]");

    if (lowercase && isupper(prbuf[0]))
        prbuf[0] = (char) tolower(prbuf[0]);
    else if (!lowercase && islower(*prbuf))
        *prbuf = (char) toupper(*prbuf);

    if (!lowercase)
        strcat(prbuf, ".");

    return(prbuf);
}

/*
    rem_obj()
        Remove an object from the level.
*/

void
rem_obj(struct linked_list *item, int dis)
{
    struct linked_list  *llptr;
    struct object *objptr, *op;
    int x, y;

    if (item == NULL)
        return;

    detach(lvl_obj, item);
    objptr = OBJPTR(item);

    if ( (llptr = objptr->next_obj) != NULL )
    {
        detach((objptr->next_obj), llptr);
        attach(lvl_obj, llptr);

        op = OBJPTR(llptr);
	
	op->next_obj = objptr->next_obj;
        
	if (op->next_obj)
            objptr->next_obj->l_prev = NULL;

        objptr->next_obj = NULL;

        y = op->o_pos.y;
        x = op->o_pos.x;

        if (cansee(y, x))
            mvwaddch(cw, y, x, op->o_type);

        mvaddch(y, x, op->o_type);
    }
    else
    {
        y = objptr->o_pos.y;
        x = objptr->o_pos.x;

        /* problems if dropped in rock */

        mvaddch(y,x,(roomin((objptr->o_pos)) == NULL ? PASSAGE : FLOOR));
    }

    if (dis)
        discard(item);
}

/*
    add_obj()
        adds an object to the level
*/

void
add_obj(struct linked_list *item, int y, int x)
{
    struct linked_list  *llptr;
    struct object*objptr;

    llptr = find_obj(y, x);

    if (llptr)
    {
        objptr = OBJPTR(llptr);
        attach((objptr->next_obj), item);
    }
    else
    {
        attach(lvl_obj, item);
        objptr = OBJPTR(item);
        objptr->next_obj = NULL;
        objptr->o_pos.y = y;
        objptr->o_pos.x = x;
        mvaddch(y, x, objptr->o_type);
    }
}

/*
    drop()
        put something down
*/

int
drop(struct linked_list *item)
{
    char    ch = CCHAR( mvwinch(stdscr, hero.y, hero.x) );
    struct object   *obj;

    switch (ch)
    {
        case GOLD:
        case POTION:
        case SCROLL:
        case FOOD:
        case WEAPON:
        case ARMOR:
        case RING:
        case STICK:
        case FLOOR:
        case PASSAGE:
        case POOL:
        case ARTIFACT:
            if (item == NULL && (item = get_item("drop", 0)) == NULL)