/* * Contains functions for dealing with things like * potions and scrolls * * @(#)things.c 3.37 (Berkeley) 6/15/81 * * 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 "curses.h" #include #include #include "rogue.h" /* * inv_name: * return the name of something as it would appear in an * inventory. */ char * inv_name(struct object *obj, int drop) { char *pb; switch(obj->o_type) { case SCROLL: if (obj->o_count == 1) strcpy(prbuf, "A scroll "); else sprintf(prbuf, "%d scrolls ", obj->o_count); pb = &prbuf[strlen(prbuf)]; if (s_know[obj->o_which]) sprintf(pb, "of %s", s_magic[obj->o_which].mi_name); else if (s_guess[obj->o_which]) sprintf(pb, "called %s", s_guess[obj->o_which]); else sprintf(pb, "titled '%s'", s_names[obj->o_which]); when POTION: if (obj->o_count == 1) strcpy(prbuf, "A potion "); else sprintf(prbuf, "%d potions ", obj->o_count); pb = &prbuf[strlen(prbuf)]; if (p_know[obj->o_which]) sprintf(pb, "of %s(%s)", p_magic[obj->o_which].mi_name, p_colors[obj->o_which]); else if (p_guess[obj->o_which]) sprintf(pb, "called %s(%s)", p_guess[obj->o_which], p_colors[obj->o_which]); else if (obj->o_count == 1) sprintf(prbuf, "A%s %s potion", vowelstr(p_colors[obj->o_which]), p_colors[obj->o_which]); else sprintf(prbuf, "%d %s potions", obj->o_count, p_colors[obj->o_which]); when FOOD: if (obj->o_which == 1) if (obj->o_count == 1) sprintf(prbuf, "A%s %.76s", vowelstr(fruit), fruit); else sprintf(prbuf, "%d %.66ss", obj->o_count, fruit); else if (obj->o_count == 1) strcpy(prbuf, "Some food"); else sprintf(prbuf, "%d rations of food", obj->o_count); when WEAPON: if (obj->o_count > 1) sprintf(prbuf, "%d ", obj->o_count); else strcpy(prbuf, "A "); pb = &prbuf[strlen(prbuf)]; if (obj->o_flags & ISKNOW) sprintf(pb, "%s %s", num(obj->o_hplus, obj->o_dplus), w_names[obj->o_which]); else sprintf(pb, "%s", w_names[obj->o_which]); if (obj->o_count > 1) strcat(prbuf, "s"); when ARMOR: if (obj->o_flags & ISKNOW) sprintf(prbuf, "%s %s", num(a_class[obj->o_which] - obj->o_ac, 0), a_names[obj->o_which]); else sprintf(prbuf, "%s", a_names[obj->o_which]); when AMULET: strcpy(prbuf, "The Amulet of Yendor"); when STICK: sprintf(prbuf, "A %s ", ws_type[obj->o_which]); pb = &prbuf[strlen(prbuf)]; if (ws_know[obj->o_which]) sprintf(pb, "of %s%s(%s)", ws_magic[obj->o_which].mi_name, charge_str(obj), ws_made[obj->o_which]); else if (ws_guess[obj->o_which]) sprintf(pb, "called %s(%s)", ws_guess[obj->o_which], ws_made[obj->o_which]); else sprintf(&prbuf[2], "%s %s", ws_made[obj->o_which], ws_type[obj->o_which]); when RING: if (r_know[obj->o_which]) sprintf(prbuf, "A%s ring of %s(%s)", ring_num(obj), r_magic[obj->o_which].mi_name, r_stones[obj->o_which]); else if (r_guess[obj->o_which]) sprintf(prbuf, "A ring called %s(%s)", r_guess[obj->o_which], r_stones[obj->o_which]); else sprintf(prbuf, "A%s %s ring", vowelstr(r_stones[obj->o_which]), r_stones[obj->o_which]); otherwise: debug("Picked up something funny"); sprintf(prbuf, "Something bizarre %s", unctrl(obj->o_type)); } if (obj == cur_armor) strcat(prbuf, " (being worn)"); if (obj == cur_weapon) strcat(prbuf, " (weapon in hand)"); if (obj == cur_ring[LEFT]) strcat(prbuf, " (on left hand)"); else if (obj == cur_ring[RIGHT]) strcat(prbuf, " (on right hand)"); if (drop && isupper(prbuf[0])) prbuf[0] = tolower(prbuf[0]); else if (!drop && islower(*prbuf)) *prbuf = toupper(*prbuf); if (!drop) strcat(prbuf, "."); return prbuf; } /* * money: * Add to characters purse */ void money() { struct room *rp; for (rp = rooms; rp <= &rooms[MAXROOMS-1]; rp++) if (ce(hero, rp->r_gold)) { if (notify) { if (!terse) addmsg("You found "); msg("%d gold pieces.", rp->r_goldval); } purse += rp->r_goldval; rp->r_goldval = 0; cmov(rp->r_gold); addch(FLOOR); return; } msg("That gold must have been counterfeit"); } /* * drop: * put something down */ void drop() { int ch; struct linked_list *obj, *nobj; struct object *op; ch = mvwinch(stdscr, hero.y, hero.x); if (ch != FLOOR && ch != PASSAGE) { msg("There is something there already"); return; } if ((obj = get_item("drop", 0)) == NULL) return; op = (struct object *) ldata(obj); if (!dropcheck(op)) return; /* * Take it out of the pack */ if (op->o_count >= 2 && op->o_type != WEAPON) { nobj = new_item(sizeof *op); op->o_count--; op = (struct object *) ldata(nobj); *op = *((struct object *) ldata(obj)); op->o_count = 1; obj = nobj; if (op->o_group != 0) inpack++; } else detach(pack, obj); inpack--; /* * Link it into the level object list */ attach(lvl_obj, obj); mvaddch(hero.y, hero.x, op->o_type); op->o_pos = hero; msg("Dropped %s", inv_name(op, TRUE)); } /* * do special checks for dropping or unweilding|unwearing|unringing */ int dropcheck(struct object *op) { str_t save_max; if (op == NULL) return TRUE; if (op != cur_armor && op != cur_weapon && op != cur_ring[LEFT] && op != cur_ring[RIGHT]) return TRUE; if (op->o_flags & ISCURSED) { msg("You can't. It appears to be cursed."); return FALSE; } if (op == cur_weapon) cur_weapon = NULL; else if (op == cur_armor) { waste_time(); cur_armor = NULL; } else if (op == cur_ring[LEFT] || op == cur_ring[RIGHT]) { switch (op->o_which) { case R_ADDSTR: save_max = max_stats.s_str; chg_str(-op->o_ac); max_stats.s_str = save_max; break; case R_SEEINVIS: player.t_flags &= ~CANSEE; extinguish(unsee); light(&hero); mvwaddch(cw, hero.y, hero.x, PLAYER); break; } cur_ring[op == cur_ring[LEFT] ? LEFT : RIGHT] = NULL; } return TRUE; } /* * return a new thing */ struct linked_list * new_thing() { struct linked_list *item; struct object *cur; int j, k; item = new_item(sizeof *cur); cur = (struct object *) ldata(item); cur->o_hplus = cur->o_dplus = 0; strcpy(cur->o_damage,"0d0"); strcpy(cur->o_hurldmg,"0d0"); cur->o_ac = 11; cur->o_count = 1; cur->o_group = 0; cur->o_flags = 0; /* * Decide what kind of object it will be * If we haven't had food for a while, let it be food. */ switch (no_food > 3 ? 2 : pick_one(things, NUMTHINGS)) { case 0: cur->o_type = POTION; cur->o_which = pick_one(p_magic, MAXPOTIONS); when 1: cur->o_type = SCROLL; cur->o_which = pick_one(s_magic, MAXSCROLLS); when 2: no_food = 0; cur->o_type = FOOD; if (rnd(100) > 10) cur->o_which = 0; else cur->o_which = 1; when 3: cur->o_type = WEAPON; cur->o_which = rnd(MAXWEAPONS); init_weapon(cur, cur->o_which); if ((k = rnd(100)) < 10) { cur->o_flags |= ISCURSED; cur->o_hplus -= rnd(3)+1; } else if (k < 15) cur->o_hplus += rnd(3)+1; when 4: cur->o_type = ARMOR; for (j = 0, k = rnd(100); j < MAXARMORS; j++) if (k < a_chances[j]) break; if (j == MAXARMORS) { debug("Picked a bad armor %d", k); j = 0; } cur->o_which = j; cur->o_ac = a_class[j]; if ((k = rnd(100)) < 20) { cur->o_flags |= ISCURSED; cur->o_ac += rnd(3)+1; } else if (k < 28) cur->o_ac -= rnd(3)+1; when 5: cur->o_type = RING; cur->o_which = pick_one(r_magic, MAXRINGS); switch (cur->o_which) { case R_ADDSTR: case R_PROTECT: case R_ADDHIT: case R_ADDDAM: if ((cur->o_ac = rnd(3)) == 0) { cur->o_ac = -1; cur->o_flags |= ISCURSED; } when R_AGGR: case R_TELEPORT: cur->o_flags |= ISCURSED; } when 6: cur->o_type = STICK; cur->o_which = pick_one(ws_magic, MAXSTICKS); fix_stick(cur); otherwise: debug("Picked a bad kind of object"); wait_for(stdscr, ' '); } return item; } /* * pick an item out of a list of nitems possible magic items */ int pick_one(struct magic_item *magic, int nitems) { struct magic_item *end; int i; struct magic_item *start; start = magic; for (end = &magic[nitems], i = rnd(100); magic < end; magic++) if (i < magic->mi_prob) break; if (magic == end) { if (wizard) { msg("bad pick_one: %d from %d items", i, nitems); for (magic = start; magic < end; magic++) msg("%s: %d%%", magic->mi_name, magic->mi_prob); } magic = start; } return (int) (magic - start); }