Annotation of early-roguelike/rogue3/things.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: * Contains functions for dealing with things like
! 3: * potions and scrolls
! 4: *
! 5: * @(#)things.c 3.37 (Berkeley) 6/15/81
! 6: *
! 7: * Rogue: Exploring the Dungeons of Doom
! 8: * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
! 9: * All rights reserved.
! 10: *
! 11: * See the file LICENSE.TXT for full copyright and licensing information.
! 12: */
! 13:
! 14: #include "curses.h"
! 15: #include <ctype.h>
! 16: #include <string.h>
! 17: #include "rogue.h"
! 18:
! 19: /*
! 20: * inv_name:
! 21: * return the name of something as it would appear in an
! 22: * inventory.
! 23: */
! 24: char *
! 25: inv_name(struct object *obj, int drop)
! 26: {
! 27: char *pb;
! 28:
! 29: switch(obj->o_type)
! 30: {
! 31: case SCROLL:
! 32: if (obj->o_count == 1)
! 33: strcpy(prbuf, "A scroll ");
! 34: else
! 35: sprintf(prbuf, "%d scrolls ", obj->o_count);
! 36: pb = &prbuf[strlen(prbuf)];
! 37: if (s_know[obj->o_which])
! 38: sprintf(pb, "of %s", s_magic[obj->o_which].mi_name);
! 39: else if (s_guess[obj->o_which])
! 40: sprintf(pb, "called %s", s_guess[obj->o_which]);
! 41: else
! 42: sprintf(pb, "titled '%s'", s_names[obj->o_which]);
! 43: when POTION:
! 44: if (obj->o_count == 1)
! 45: strcpy(prbuf, "A potion ");
! 46: else
! 47: sprintf(prbuf, "%d potions ", obj->o_count);
! 48: pb = &prbuf[strlen(prbuf)];
! 49: if (p_know[obj->o_which])
! 50: sprintf(pb, "of %s(%s)", p_magic[obj->o_which].mi_name,
! 51: p_colors[obj->o_which]);
! 52: else if (p_guess[obj->o_which])
! 53: sprintf(pb, "called %s(%s)", p_guess[obj->o_which],
! 54: p_colors[obj->o_which]);
! 55: else if (obj->o_count == 1)
! 56: sprintf(prbuf, "A%s %s potion",
! 57: vowelstr(p_colors[obj->o_which]),
! 58: p_colors[obj->o_which]);
! 59: else
! 60: sprintf(prbuf, "%d %s potions", obj->o_count,
! 61: p_colors[obj->o_which]);
! 62: when FOOD:
! 63: if (obj->o_which == 1)
! 64: if (obj->o_count == 1)
! 65: sprintf(prbuf, "A%s %.76s", vowelstr(fruit), fruit);
! 66: else
! 67: sprintf(prbuf, "%d %.66ss", obj->o_count, fruit);
! 68: else
! 69: if (obj->o_count == 1)
! 70: strcpy(prbuf, "Some food");
! 71: else
! 72: sprintf(prbuf, "%d rations of food", obj->o_count);
! 73: when WEAPON:
! 74: if (obj->o_count > 1)
! 75: sprintf(prbuf, "%d ", obj->o_count);
! 76: else
! 77: strcpy(prbuf, "A ");
! 78: pb = &prbuf[strlen(prbuf)];
! 79: if (obj->o_flags & ISKNOW)
! 80: sprintf(pb, "%s %s", num(obj->o_hplus, obj->o_dplus),
! 81: w_names[obj->o_which]);
! 82: else
! 83: sprintf(pb, "%s", w_names[obj->o_which]);
! 84: if (obj->o_count > 1)
! 85: strcat(prbuf, "s");
! 86: when ARMOR:
! 87: if (obj->o_flags & ISKNOW)
! 88: sprintf(prbuf, "%s %s",
! 89: num(a_class[obj->o_which] - obj->o_ac, 0),
! 90: a_names[obj->o_which]);
! 91: else
! 92: sprintf(prbuf, "%s", a_names[obj->o_which]);
! 93: when AMULET:
! 94: strcpy(prbuf, "The Amulet of Yendor");
! 95: when STICK:
! 96: sprintf(prbuf, "A %s ", ws_type[obj->o_which]);
! 97: pb = &prbuf[strlen(prbuf)];
! 98: if (ws_know[obj->o_which])
! 99: sprintf(pb, "of %s%s(%s)", ws_magic[obj->o_which].mi_name,
! 100: charge_str(obj), ws_made[obj->o_which]);
! 101: else if (ws_guess[obj->o_which])
! 102: sprintf(pb, "called %s(%s)", ws_guess[obj->o_which],
! 103: ws_made[obj->o_which]);
! 104: else
! 105: sprintf(&prbuf[2], "%s %s", ws_made[obj->o_which],
! 106: ws_type[obj->o_which]);
! 107: when RING:
! 108: if (r_know[obj->o_which])
! 109: sprintf(prbuf, "A%s ring of %s(%s)", ring_num(obj),
! 110: r_magic[obj->o_which].mi_name, r_stones[obj->o_which]);
! 111: else if (r_guess[obj->o_which])
! 112: sprintf(prbuf, "A ring called %s(%s)",
! 113: r_guess[obj->o_which], r_stones[obj->o_which]);
! 114: else
! 115: sprintf(prbuf, "A%s %s ring", vowelstr(r_stones[obj->o_which]),
! 116: r_stones[obj->o_which]);
! 117: otherwise:
! 118: debug("Picked up something funny");
! 119: sprintf(prbuf, "Something bizarre %s", unctrl(obj->o_type));
! 120: }
! 121: if (obj == cur_armor)
! 122: strcat(prbuf, " (being worn)");
! 123: if (obj == cur_weapon)
! 124: strcat(prbuf, " (weapon in hand)");
! 125: if (obj == cur_ring[LEFT])
! 126: strcat(prbuf, " (on left hand)");
! 127: else if (obj == cur_ring[RIGHT])
! 128: strcat(prbuf, " (on right hand)");
! 129: if (drop && isupper(prbuf[0]))
! 130: prbuf[0] = tolower(prbuf[0]);
! 131: else if (!drop && islower(*prbuf))
! 132: *prbuf = toupper(*prbuf);
! 133: if (!drop)
! 134: strcat(prbuf, ".");
! 135: return prbuf;
! 136: }
! 137:
! 138: /*
! 139: * money:
! 140: * Add to characters purse
! 141: */
! 142: void
! 143: money()
! 144: {
! 145: struct room *rp;
! 146:
! 147: for (rp = rooms; rp <= &rooms[MAXROOMS-1]; rp++)
! 148: if (ce(hero, rp->r_gold))
! 149: {
! 150: if (notify)
! 151: {
! 152: if (!terse)
! 153: addmsg("You found ");
! 154: msg("%d gold pieces.", rp->r_goldval);
! 155: }
! 156: purse += rp->r_goldval;
! 157: rp->r_goldval = 0;
! 158: cmov(rp->r_gold);
! 159: addch(FLOOR);
! 160: return;
! 161: }
! 162: msg("That gold must have been counterfeit");
! 163: }
! 164:
! 165: /*
! 166: * drop:
! 167: * put something down
! 168: */
! 169: void
! 170: drop()
! 171: {
! 172: int ch;
! 173: struct linked_list *obj, *nobj;
! 174: struct object *op;
! 175:
! 176: ch = mvwinch(stdscr, hero.y, hero.x);
! 177: if (ch != FLOOR && ch != PASSAGE)
! 178: {
! 179: msg("There is something there already");
! 180: return;
! 181: }
! 182: if ((obj = get_item("drop", 0)) == NULL)
! 183: return;
! 184: op = (struct object *) ldata(obj);
! 185: if (!dropcheck(op))
! 186: return;
! 187: /*
! 188: * Take it out of the pack
! 189: */
! 190: if (op->o_count >= 2 && op->o_type != WEAPON)
! 191: {
! 192: nobj = new_item(sizeof *op);
! 193: op->o_count--;
! 194: op = (struct object *) ldata(nobj);
! 195: *op = *((struct object *) ldata(obj));
! 196: op->o_count = 1;
! 197: obj = nobj;
! 198: if (op->o_group != 0)
! 199: inpack++;
! 200: }
! 201: else
! 202: detach(pack, obj);
! 203: inpack--;
! 204: /*
! 205: * Link it into the level object list
! 206: */
! 207: attach(lvl_obj, obj);
! 208: mvaddch(hero.y, hero.x, op->o_type);
! 209: op->o_pos = hero;
! 210: msg("Dropped %s", inv_name(op, TRUE));
! 211: }
! 212:
! 213: /*
! 214: * do special checks for dropping or unweilding|unwearing|unringing
! 215: */
! 216: int
! 217: dropcheck(struct object *op)
! 218: {
! 219: str_t save_max;
! 220:
! 221: if (op == NULL)
! 222: return TRUE;
! 223: if (op != cur_armor && op != cur_weapon
! 224: && op != cur_ring[LEFT] && op != cur_ring[RIGHT])
! 225: return TRUE;
! 226: if (op->o_flags & ISCURSED)
! 227: {
! 228: msg("You can't. It appears to be cursed.");
! 229: return FALSE;
! 230: }
! 231: if (op == cur_weapon)
! 232: cur_weapon = NULL;
! 233: else if (op == cur_armor)
! 234: {
! 235: waste_time();
! 236: cur_armor = NULL;
! 237: }
! 238: else if (op == cur_ring[LEFT] || op == cur_ring[RIGHT])
! 239: {
! 240: switch (op->o_which)
! 241: {
! 242: case R_ADDSTR:
! 243: save_max = max_stats.s_str;
! 244: chg_str(-op->o_ac);
! 245: max_stats.s_str = save_max;
! 246: break;
! 247: case R_SEEINVIS:
! 248: player.t_flags &= ~CANSEE;
! 249: extinguish(unsee);
! 250: light(&hero);
! 251: mvwaddch(cw, hero.y, hero.x, PLAYER);
! 252: break;
! 253: }
! 254: cur_ring[op == cur_ring[LEFT] ? LEFT : RIGHT] = NULL;
! 255: }
! 256: return TRUE;
! 257: }
! 258:
! 259: /*
! 260: * return a new thing
! 261: */
! 262: struct linked_list *
! 263: new_thing()
! 264: {
! 265: struct linked_list *item;
! 266: struct object *cur;
! 267: int j, k;
! 268:
! 269: item = new_item(sizeof *cur);
! 270: cur = (struct object *) ldata(item);
! 271: cur->o_hplus = cur->o_dplus = 0;
! 272: strcpy(cur->o_damage,"0d0");
! 273: strcpy(cur->o_hurldmg,"0d0");
! 274: cur->o_ac = 11;
! 275: cur->o_count = 1;
! 276: cur->o_group = 0;
! 277: cur->o_flags = 0;
! 278: /*
! 279: * Decide what kind of object it will be
! 280: * If we haven't had food for a while, let it be food.
! 281: */
! 282: switch (no_food > 3 ? 2 : pick_one(things, NUMTHINGS))
! 283: {
! 284: case 0:
! 285: cur->o_type = POTION;
! 286: cur->o_which = pick_one(p_magic, MAXPOTIONS);
! 287: when 1:
! 288: cur->o_type = SCROLL;
! 289: cur->o_which = pick_one(s_magic, MAXSCROLLS);
! 290: when 2:
! 291: no_food = 0;
! 292: cur->o_type = FOOD;
! 293: if (rnd(100) > 10)
! 294: cur->o_which = 0;
! 295: else
! 296: cur->o_which = 1;
! 297: when 3:
! 298: cur->o_type = WEAPON;
! 299: cur->o_which = rnd(MAXWEAPONS);
! 300: init_weapon(cur, cur->o_which);
! 301: if ((k = rnd(100)) < 10)
! 302: {
! 303: cur->o_flags |= ISCURSED;
! 304: cur->o_hplus -= rnd(3)+1;
! 305: }
! 306: else if (k < 15)
! 307: cur->o_hplus += rnd(3)+1;
! 308: when 4:
! 309: cur->o_type = ARMOR;
! 310: for (j = 0, k = rnd(100); j < MAXARMORS; j++)
! 311: if (k < a_chances[j])
! 312: break;
! 313: if (j == MAXARMORS)
! 314: {
! 315: debug("Picked a bad armor %d", k);
! 316: j = 0;
! 317: }
! 318: cur->o_which = j;
! 319: cur->o_ac = a_class[j];
! 320: if ((k = rnd(100)) < 20)
! 321: {
! 322: cur->o_flags |= ISCURSED;
! 323: cur->o_ac += rnd(3)+1;
! 324: }
! 325: else if (k < 28)
! 326: cur->o_ac -= rnd(3)+1;
! 327: when 5:
! 328: cur->o_type = RING;
! 329: cur->o_which = pick_one(r_magic, MAXRINGS);
! 330: switch (cur->o_which)
! 331: {
! 332: case R_ADDSTR:
! 333: case R_PROTECT:
! 334: case R_ADDHIT:
! 335: case R_ADDDAM:
! 336: if ((cur->o_ac = rnd(3)) == 0)
! 337: {
! 338: cur->o_ac = -1;
! 339: cur->o_flags |= ISCURSED;
! 340: }
! 341: when R_AGGR:
! 342: case R_TELEPORT:
! 343: cur->o_flags |= ISCURSED;
! 344: }
! 345: when 6:
! 346: cur->o_type = STICK;
! 347: cur->o_which = pick_one(ws_magic, MAXSTICKS);
! 348: fix_stick(cur);
! 349: otherwise:
! 350: debug("Picked a bad kind of object");
! 351: wait_for(stdscr, ' ');
! 352: }
! 353: return item;
! 354: }
! 355:
! 356: /*
! 357: * pick an item out of a list of nitems possible magic items
! 358: */
! 359: int
! 360: pick_one(struct magic_item *magic, int nitems)
! 361: {
! 362: struct magic_item *end;
! 363: int i;
! 364: struct magic_item *start;
! 365:
! 366: start = magic;
! 367: for (end = &magic[nitems], i = rnd(100); magic < end; magic++)
! 368: if (i < magic->mi_prob)
! 369: break;
! 370: if (magic == end)
! 371: {
! 372: if (wizard)
! 373: {
! 374: msg("bad pick_one: %d from %d items", i, nitems);
! 375: for (magic = start; magic < end; magic++)
! 376: msg("%s: %d%%", magic->mi_name, magic->mi_prob);
! 377: }
! 378: magic = start;
! 379: }
! 380: return (int) (magic - start);
! 381: }
CVSweb