Annotation of early-roguelike/arogue7/things.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: * things.c - functions for dealing with things like potions and scrolls
! 3: *
! 4: * Advanced Rogue
! 5: * Copyright (C) 1984, 1985, 1986 Michael Morgan, Ken Dalka and AT&T
! 6: * All rights reserved.
! 7: *
! 8: * Based on "Rogue: Exploring the Dungeons of Doom"
! 9: * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
! 10: * All rights reserved.
! 11: *
! 12: * See the file LICENSE.TXT for full copyright and licensing information.
! 13: */
! 14:
! 15: /*
! 16: * Contains functions for dealing with things like
! 17: * potions and scrolls
! 18: *
! 19: */
! 20:
! 21: #include "curses.h"
! 22: #include <ctype.h>
! 23: #include <string.h>
! 24: #include "rogue.h"
! 25:
! 26: int pick_one(struct magic_item *magic, int nitems);
! 27: char *blesscurse(int flags);
! 28: char *p_kind(struct object *obj);
! 29: int extras(void);
! 30:
! 31: /*
! 32: * print out the number of charges on a stick
! 33: */
! 34: char *
! 35: charge_str(struct object *obj)
! 36: {
! 37: static char buf[20];
! 38:
! 39: if (!(obj->o_flags & ISKNOW))
! 40: buf[0] = '\0';
! 41: else if (terse)
! 42: sprintf(buf, " [%d]", obj->o_charges);
! 43: else
! 44: sprintf(buf, " [%d charges]", obj->o_charges);
! 45: return buf;
! 46: }
! 47: /*
! 48: * inv_name:
! 49: * return the name of something as it would appear in an
! 50: * inventory.
! 51: */
! 52: char *
! 53: inv_name(struct object *obj, bool drop)
! 54: {
! 55: register char *pb;
! 56:
! 57: pb = prbuf;
! 58: pb[0] = '\0';
! 59: switch(obj->o_type) {
! 60: case SCROLL:
! 61: if (obj->o_count == 1)
! 62: sprintf(pb, "A %sscroll ", blesscurse(obj->o_flags));
! 63: else
! 64: sprintf(pb, "%d %sscrolls ",
! 65: obj->o_count, blesscurse(obj->o_flags));
! 66: pb = &pb[strlen(pb)];
! 67: if (s_know[obj->o_which] || (obj->o_flags & ISPOST))
! 68: sprintf(pb, "of %s", s_magic[obj->o_which].mi_name);
! 69: else if (s_guess[obj->o_which])
! 70: sprintf(pb, "named %s", s_guess[obj->o_which]);
! 71: else
! 72: sprintf(pb, "titled '%s'", s_names[obj->o_which]);
! 73: when POTION:
! 74: if (obj->o_count == 1)
! 75: sprintf(pb, "A %spotion ", blesscurse(obj->o_flags));
! 76: else
! 77: sprintf(pb, "%d %spotions ",
! 78: obj->o_count, blesscurse(obj->o_flags));
! 79: pb = &pb[strlen(pb)];
! 80: if (p_know[obj->o_which])
! 81: sprintf(pb, "of %s (%s)", p_magic[obj->o_which].mi_name,
! 82: p_kind(obj));
! 83: else if (obj->o_flags & ISPOST)
! 84: sprintf(pb, "of %s", p_magic[obj->o_which].mi_name);
! 85: else if (p_guess[obj->o_which])
! 86: sprintf(pb, "named %s (%s)", p_guess[obj->o_which],
! 87: p_colors[obj->o_which]);
! 88: else {
! 89: pb = prbuf;
! 90: if (obj->o_count == 1)
! 91: sprintf(pb, "A%s %s potion",
! 92: vowelstr(p_colors[obj->o_which]),
! 93: p_colors[obj->o_which]);
! 94: else
! 95: sprintf(pb, "%d %s potions",
! 96: obj->o_count, p_colors[obj->o_which]);
! 97: }
! 98: when FOOD:
! 99: if (obj->o_count == 1)
! 100: sprintf(pb, "A%s %s", vowelstr(foods[obj->o_which].mi_name),
! 101: foods[obj->o_which].mi_name);
! 102: else
! 103: sprintf(pb, "%d %ss", obj->o_count,foods[obj->o_which].mi_name);
! 104: when WEAPON:
! 105: if (obj->o_count > 1)
! 106: sprintf(pb, "%d ", obj->o_count);
! 107: else
! 108: strcpy(pb, "A ");
! 109: pb = &pb[strlen(pb)];
! 110: if (obj->o_flags & ISKNOW) {
! 111: strcat(pb, num(obj->o_hplus, obj->o_dplus));
! 112: strcat (pb, " ");
! 113: }
! 114: strcat(pb, weaps[obj->o_which].w_name);
! 115: if (obj->o_count > 1)
! 116: strcat(pb, "s");
! 117: if (obj == cur_weapon)
! 118: strcat(pb, " (weapon in hand)");
! 119: if (obj->o_flags & ISPOISON)
! 120: strcat(pb, " {Poisoned}");
! 121: when ARMOR:
! 122: if (obj->o_flags & ISKNOW) {
! 123: strcat(pb, num(armors[obj->o_which].a_class - obj->o_ac, 0));
! 124: strcat(pb, " ");
! 125: }
! 126: strcat(pb, armors[obj->o_which].a_name);
! 127: if (obj == cur_armor)
! 128: strcat(pb, " (being worn)");
! 129: when STICK:
! 130: sprintf(pb, "A %s%s ",
! 131: blesscurse(obj->o_flags), ws_type[obj->o_which]);
! 132: pb = &pb[strlen(pb)];
! 133: if (ws_know[obj->o_which] || obj->o_flags & ISKNOW)
! 134: sprintf(pb, "of %s%s (%s)", ws_magic[obj->o_which].mi_name,
! 135: charge_str(obj), ws_made[obj->o_which]);
! 136: else if (obj->o_flags & ISPOST)
! 137: sprintf(pb, "of %s", ws_magic[obj->o_which].mi_name);
! 138: else if (ws_guess[obj->o_which])
! 139: sprintf(pb, "named %s (%s)", ws_guess[obj->o_which],
! 140: ws_made[obj->o_which]);
! 141: else {
! 142: pb = prbuf;
! 143: sprintf(pb, "A %s %s", ws_made[obj->o_which],
! 144: ws_type[obj->o_which]);
! 145: }
! 146: if (obj == cur_weapon)
! 147: strcat(prbuf, " (weapon in hand)");
! 148: when RING:
! 149: if (r_know[obj->o_which] || obj->o_flags & ISKNOW)
! 150: sprintf(pb, "A%s ring of %s (%s)", ring_num(obj),
! 151: r_magic[obj->o_which].mi_name, r_stones[obj->o_which]);
! 152: else if (obj->o_flags & ISPOST)
! 153: sprintf(pb, "A ring of %s", r_magic[obj->o_which].mi_name);
! 154: else if (r_guess[obj->o_which])
! 155: sprintf(pb, "A ring named %s (%s)",
! 156: r_guess[obj->o_which], r_stones[obj->o_which]);
! 157: else
! 158: sprintf(pb, "A%s %s ring", vowelstr(r_stones[obj->o_which]),
! 159: r_stones[obj->o_which]);
! 160: if (obj == cur_ring[LEFT_1] || obj == cur_ring[LEFT_2] ||
! 161: obj == cur_ring[LEFT_3] || obj == cur_ring[LEFT_4])
! 162: strcat(pb, " (on left hand)");
! 163: if (obj == cur_ring[RIGHT_1] || obj == cur_ring[RIGHT_2] ||
! 164: obj == cur_ring[RIGHT_3] || obj == cur_ring[RIGHT_4])
! 165: strcat(pb, " (on right hand)");
! 166: when RELIC:
! 167: if (obj->o_flags & ISKNOW)
! 168: switch(obj->o_which) {
! 169: case QUILL_NAGROM:
! 170: sprintf(pb, "%s%s", rel_magic[obj->o_which].mi_name,
! 171: charge_str(obj));
! 172: otherwise:
! 173: strcpy(pb, rel_magic[obj->o_which].mi_name);
! 174: }
! 175: else switch(obj->o_which) {
! 176: case MUSTY_DAGGER:
! 177: strcpy(pb, "Two very fine daggers marked MDDE");
! 178: when EMORI_CLOAK:
! 179: strcpy(pb, "A silk cloak");
! 180: when HEIL_ANKH:
! 181: strcpy(pb, "A golden ankh");
! 182: when MING_STAFF:
! 183: strcpy(pb, "A finely carved staff");
! 184: when ORCUS_WAND:
! 185: strcpy(pb, "A sparkling ivory wand");
! 186: when ASMO_ROD:
! 187: strcpy(pb, "A glistening ebony rod");
! 188: when YENDOR_AMULET:
! 189: strcpy(pb, "A silver amulet");
! 190: when STONEBONES_AMULET:
! 191: strcpy(pb, "A stone amulet");
! 192: when BRIAN_MANDOLIN:
! 193: strcpy(pb, "A gleaming mandolin");
! 194: when HRUGGEK_MSTAR:
! 195: strcpy(pb, "A huge morning star");
! 196: when AXE_AKLAD:
! 197: strcpy(pb, "A jewel encrusted axe");
! 198: when QUILL_NAGROM:
! 199: strcpy(pb, "A bright white feather");
! 200: when GERYON_HORN:
! 201: strcpy(pb, "A jet black horn");
! 202: when YEENOGHU_FLAIL:
! 203: strcpy(pb, "A shimmering flail");
! 204: when SURTUR_RING:
! 205: strcpy(pb, "A fiery red ring");
! 206: otherwise:
! 207: strcpy(pb, "A magical item");
! 208: }
! 209:
! 210: /* Take care of wielding and wearing */
! 211: switch (obj->o_which) {
! 212: case EMORI_CLOAK:
! 213: if (cur_armor == NULL && cur_misc[WEAR_CLOAK] == NULL)
! 214: strcat(pb, " (being worn)");
! 215: if (obj->o_charges)
! 216: strcat(pb, " [charged]");
! 217: else
! 218: strcat(pb, " [discharged]");
! 219: when HEIL_ANKH:
! 220: if (cur_relic[HEIL_ANKH]) strcat(pb, " (in hand)");
! 221: when EYE_VECNA:
! 222: if (cur_relic[EYE_VECNA]) strcat(pb, " (in eye socket)");
! 223: when STONEBONES_AMULET:
! 224: if (cur_relic[STONEBONES_AMULET])
! 225: strcat(pb, " (in chest)");
! 226: when YENDOR_AMULET:
! 227: if (cur_relic[YENDOR_AMULET])
! 228: strcat(pb, " (in chest)");
! 229: when MUSTY_DAGGER:
! 230: case HRUGGEK_MSTAR:
! 231: case AXE_AKLAD:
! 232: case YEENOGHU_FLAIL:
! 233: case MING_STAFF:
! 234: case ASMO_ROD:
! 235: case ORCUS_WAND:
! 236: if (cur_weapon == obj) strcat(pb, " (weapon in hand)");
! 237: when SURTUR_RING:
! 238: if (cur_relic[SURTUR_RING])
! 239: strcat(pb, " (in nose)");
! 240: }
! 241: when MM:
! 242: if (m_know[obj->o_which])
! 243: strcpy(pb, misc_name(obj));
! 244: else {
! 245: switch (obj->o_which) {
! 246: case MM_JUG:
! 247: case MM_BEAKER:
! 248: strcpy(pb, "A bottle");
! 249: when MM_KEOGHTOM:
! 250: strcpy(pb, "A jar");
! 251: when MM_JEWEL:
! 252: strcpy(pb, "An amulet");
! 253: when MM_BOOK:
! 254: case MM_SKILLS:
! 255: strcpy(pb, "A book");
! 256: when MM_ELF_BOOTS:
! 257: case MM_DANCE:
! 258: strcpy(pb, "A pair of boots");
! 259: when MM_BRACERS:
! 260: strcpy(pb, "A pair of bracers");
! 261: when MM_OPEN:
! 262: case MM_HUNGER:
! 263: strcpy(pb, "A chime");
! 264: when MM_DISP:
! 265: case MM_R_POWERLESS:
! 266: case MM_PROTECT:
! 267: strcpy(pb, "A cloak");
! 268: when MM_DRUMS:
! 269: strcpy(pb, "A set of drums");
! 270: when MM_DISAPPEAR:
! 271: case MM_CHOKE:
! 272: strcpy(pb, "A pouch of dust");
! 273: when MM_G_DEXTERITY:
! 274: case MM_G_OGRE:
! 275: case MM_FUMBLE:
! 276: strcpy(pb, "A pair of gauntlets");
! 277: when MM_ADAPTION:
! 278: case MM_STRANGLE:
! 279: strcpy(pb, "A necklace");
! 280: otherwise:
! 281: strcpy(pb, "A magical item");
! 282: }
! 283: if (m_guess[obj->o_which]) {
! 284: strcat(pb, " named: ");
! 285: strcat(pb, m_guess[obj->o_which]);
! 286: }
! 287: }
! 288: if (obj == cur_misc[WEAR_BOOTS] ||
! 289: obj == cur_misc[WEAR_BRACERS] ||
! 290: obj == cur_misc[WEAR_CLOAK] ||
! 291: obj == cur_misc[WEAR_GAUNTLET] ||
! 292: obj == cur_misc[WEAR_NECKLACE] ||
! 293: obj == cur_misc[WEAR_JEWEL])
! 294: strcat(pb, " (being worn)");
! 295: when GOLD:
! 296: sprintf(pb, "%d Pieces of Gold", obj->o_count);
! 297: otherwise:
! 298: debug("Picked up something funny");
! 299: sprintf(pb, "Something bizarre %s", unctrl(obj->o_type));
! 300: }
! 301:
! 302: /* Is it marked? */
! 303: if (obj->o_mark[0]) {
! 304: pb = &pb[strlen(pb)];
! 305: sprintf(pb, " <%s>", obj->o_mark);
! 306: }
! 307:
! 308: if (obj->o_flags & ISPROT)
! 309: strcat(pb, " [protected]");
! 310: if (drop && isupper(prbuf[0]))
! 311: prbuf[0] = tolower(prbuf[0]);
! 312: else if (!drop && islower(*prbuf))
! 313: *prbuf = toupper(*prbuf);
! 314: if (!drop)
! 315: strcat(pb, ".");
! 316: /*
! 317: * Truncate if long. Use cols-4 to offset the "pack letter" of a normal
! 318: * inventory listing.
! 319: */
! 320: prbuf[cols-4] = '\0';
! 321: return prbuf;
! 322: }
! 323:
! 324: /*
! 325: * weap_name:
! 326: * Return the name of a weapon.
! 327: */
! 328: char *
! 329: weap_name(struct object *obj)
! 330: {
! 331: switch (obj->o_type) {
! 332: case WEAPON:
! 333: return(weaps[obj->o_which].w_name);
! 334: when MISSILE:
! 335: return(ws_magic[obj->o_which].mi_name);
! 336: when RELIC:
! 337: switch (obj->o_which) {
! 338: case MUSTY_DAGGER:
! 339: return("daggers");
! 340: when YEENOGHU_FLAIL:
! 341: return("flail");
! 342: when AXE_AKLAD:
! 343: return("axe");
! 344: when HRUGGEK_MSTAR:
! 345: return("morning star");
! 346: when MING_STAFF:
! 347: return("staff");
! 348: when ORCUS_WAND:
! 349: return("wand");
! 350: when ASMO_ROD:
! 351: return("rod");
! 352: }
! 353: }
! 354: return("weapon");
! 355: }
! 356:
! 357: /*
! 358: * drop:
! 359: * put something down
! 360: */
! 361: bool
! 362: drop(struct linked_list *item)
! 363: {
! 364: register char ch;
! 365: register struct linked_list *obj, *nobj;
! 366: register struct object *op;
! 367:
! 368: if (item == NULL) {
! 369: /* We charge 2 movement times to drop something */
! 370: if (player.t_action == C_DROP && player.t_using != NULL) {
! 371: obj = player.t_using;
! 372: player.t_using = NULL;
! 373: player.t_action = A_NIL;
! 374: }
! 375:
! 376: /* t_action == C_DROP always when called from command() */
! 377: else {
! 378: if ((obj = get_item(pack, "drop", ALL, FALSE, FALSE)) == NULL) {
! 379: player.t_action = A_NIL;
! 380: player.t_using = NULL;
! 381: return(FALSE);
! 382: }
! 383: if (player.t_action == C_DROP) {
! 384: player.t_using = obj;
! 385: player.t_no_move = 2 * movement(&player);
! 386: return(FALSE); /* We'll come back after we've waited */
! 387: }
! 388: }
! 389:
! 390: switch(ch = CCHAR(mvwinch(stdscr, hero.y, hero.x))) {
! 391: case PASSAGE:
! 392: case SCROLL:
! 393: case POTION:
! 394: case WEAPON:
! 395: case FLOOR:
! 396: case STICK:
! 397: case ARMOR:
! 398: case POOL:
! 399: case RELIC:
! 400: case GOLD:
! 401: case FOOD:
! 402: case RING:
! 403: case MM:
! 404: break;
! 405: default:
! 406: msg("Can't leave it here");
! 407: return(FALSE);
! 408: }
! 409: }
! 410: else {
! 411: obj = item;
! 412: }
! 413: op = OBJPTR(obj);
! 414: if (!dropcheck(op))
! 415: return(FALSE);
! 416:
! 417: /*
! 418: * If it is a scare monster scroll, curse it
! 419: */
! 420: if (op->o_type == SCROLL && op->o_which == S_SCARE) {
! 421: if (op->o_flags & ISBLESSED)
! 422: op->o_flags &= ~ISBLESSED;
! 423: else op->o_flags |= ISCURSED;
! 424: }
! 425:
! 426: /*
! 427: * Take it out of the pack
! 428: */
! 429: if (op->o_count >= 2 && op->o_group == 0)
! 430: {
! 431: nobj = new_item(sizeof *op);
! 432: op->o_count--;
! 433: op = OBJPTR(nobj);
! 434: *op = *(OBJPTR(obj));
! 435: op->o_count = 1;
! 436: obj = nobj;
! 437: }
! 438: else {
! 439: detach(pack, obj);
! 440: inpack--;
! 441: }
! 442: if(ch == POOL) {
! 443: msg("Your %s sinks out of sight.",inv_name(op,TRUE));
! 444: o_discard(obj);
! 445: }
! 446: else if (levtype == POSTLEV) {
! 447: op->o_pos = hero; /* same place as hero */
! 448: fall(obj,FALSE);
! 449: if (item == NULL) /* if item wasn't sold */
! 450: msg("Thanks for your donation to the fiend's flea market.");
! 451: }
! 452: else {
! 453: /*
! 454: * Link it into the level object list
! 455: */
! 456: attach(lvl_obj, obj);
! 457: mvaddch(hero.y, hero.x, op->o_type);
! 458: op->o_pos = hero;
! 459: msg("Dropped %s", inv_name(op, TRUE));
! 460: }
! 461: updpack(FALSE, &player);
! 462: return (TRUE);
! 463: }
! 464:
! 465: /*
! 466: * do special checks for dropping or unweilding|unwearing|unringing
! 467: */
! 468: bool
! 469: dropcheck(struct object *op)
! 470: {
! 471: int save_max;
! 472:
! 473: if (op == NULL)
! 474: return TRUE;
! 475: if (levtype == POSTLEV) {
! 476: if ((op->o_flags & ISCURSED) && (op->o_flags & ISKNOW)) {
! 477: msg("The trader does not accept your shoddy merchandise");
! 478: return(FALSE);
! 479: }
! 480: }
! 481:
! 482: /* Player will not drop a relic */
! 483: if (op->o_type == RELIC) {
! 484: /*
! 485: * There is a 1% cumulative chance per relic that trying to get
! 486: * rid of it will cause the relic to turn on the player.
! 487: */
! 488: if (rnd(100) < cur_relic[op->o_which]++) {
! 489: msg("The artifact turns on you.");
! 490: msg("It crushes your mind!!! -- More --");
! 491: pstats.s_hpt = -1;
! 492: wait_for (' ');
! 493: death(D_RELIC);
! 494: }
! 495: else {
! 496: if (terse) msg("Can't release it.");
! 497: else msg("You cannot bring yourself to release it.");
! 498: return FALSE;
! 499: }
! 500: }
! 501:
! 502: /* If we aren't wearing it, we can drop it */
! 503: if (!is_current(op)) return TRUE;
! 504:
! 505: /* At this point, we know we are wearing the item */
! 506: if (op->o_flags & ISCURSED) {
! 507: msg("You can't. It appears to be cursed.");
! 508: return FALSE;
! 509: }
! 510: if (op->o_type == RING && cur_misc[WEAR_GAUNTLET] != NULL) {
! 511: msg ("You have to remove your gauntlets first!");
! 512: return FALSE;
! 513: }
! 514: cur_null(op); /* set current to NULL */
! 515: if (op->o_type == RING) {
! 516: switch (op->o_which) {
! 517: case R_ADDSTR: save_max = max_stats.s_str;
! 518: chg_str(-op->o_ac);
! 519: max_stats.s_str = save_max;
! 520: when R_ADDHIT: pstats.s_dext -= op->o_ac;
! 521: when R_ADDINTEL: pstats.s_intel -= op->o_ac;
! 522: when R_ADDWISDOM: pstats.s_wisdom -= op->o_ac;
! 523: when R_SEEINVIS: if (!ISWEARING(R_SEEINVIS) &&
! 524: find_slot(unsee) == 0) {
! 525: turn_off(player, CANSEE);
! 526: msg("The tingling feeling leaves your eyes");
! 527: }
! 528: light(&hero);
! 529: mvwaddch(cw, hero.y, hero.x, PLAYER);
! 530: when R_WARMTH: if (!ISWEARING(R_WARMTH) && !find_slot(nocold))
! 531: turn_off(player, NOCOLD);
! 532: when R_FIRE: if (!ISWEARING(R_FIRE) &&
! 533: !cur_relic[SURTUR_RING] &&
! 534: !find_slot(nofire))
! 535: turn_off(player, NOFIRE);
! 536: when R_LIGHT: {
! 537: if(roomin(&hero) != NULL) {
! 538: light(&hero);
! 539: mvwaddch(cw, hero.y, hero.x, PLAYER);
! 540: }
! 541: }
! 542: when R_SEARCH: kill_daemon(ring_search);
! 543: when R_TELEPORT: kill_daemon(ring_teleport);
! 544: }
! 545: }
! 546: else if (op->o_type == MM) {
! 547: switch (op->o_which) {
! 548: case MM_ADAPTION:
! 549: turn_off(player, NOGAS);
! 550:
! 551: when MM_STRANGLE:
! 552: msg("You can breathe again.....whew!");
! 553: kill_daemon(strangle);
! 554:
! 555: when MM_DANCE:
! 556: turn_off(player, ISDANCE);
! 557: msg ("Your feet take a break.....whew!");
! 558:
! 559: when MM_FUMBLE:
! 560: kill_daemon(fumble);
! 561: }
! 562: }
! 563: return TRUE;
! 564: }
! 565:
! 566: /*
! 567: * return a new thing
! 568: */
! 569: struct linked_list *
! 570: new_thing(int thing_type, bool allow_curse)
! 571: {
! 572: register struct linked_list *item;
! 573: register struct object *cur;
! 574: register int j;
! 575: register int blesschance, cursechance;
! 576:
! 577: item = new_item(sizeof *cur);
! 578: cur = OBJPTR(item);
! 579: cur->o_hplus = cur->o_dplus = 0;
! 580: strncpy(cur->o_damage, "0d0", sizeof(cur->o_damage));
! 581: strncpy(cur->o_hurldmg, "0d0", sizeof(cur->o_hurldmg));
! 582: cur->o_ac = 0;
! 583: cur->o_count = 1;
! 584: cur->o_group = 0;
! 585: cur->contents = NULL;
! 586: cur->o_flags = 0;
! 587: cur->o_weight = 0;
! 588: cur->o_mark[0] = '\0';
! 589: /*
! 590: * Decide what kind of object it will be
! 591: * If we haven't had food for a while, let it be food.
! 592: */
! 593: blesschance = rnd(100);
! 594: if (allow_curse) cursechance = rnd(100);
! 595: else cursechance = 100; /* No chance of curse */
! 596:
! 597: /* Get the type of item (pick one if 'any' is specified) */
! 598: if (thing_type == ALL) j = pick_one(things, NUMTHINGS);
! 599: else j = thing_type;
! 600:
! 601: /*
! 602: * make sure he gets his vitamins
! 603: */
! 604: if (thing_type == ALL && no_food > 3)
! 605: j = 2;
! 606: /*
! 607: * limit the number of foods on a level because it sometimes
! 608: * gets out of hand in the "deep" levels where there is a
! 609: * treasure room on most every level with lots of food in it
! 610: */
! 611: while (thing_type == ALL && levtype != POSTLEV && foods_this_level > 2 &&
! 612: j == 2)
! 613: j = pick_one(things, NUMTHINGS); /* not too many.... */
! 614: switch (j)
! 615: {
! 616: case TYP_POTION:
! 617: cur->o_type = POTION;
! 618: do {
! 619: cur->o_which = pick_one(p_magic, MAXPOTIONS);
! 620: } while (!allow_curse && p_magic[cur->o_which].mi_curse == 100);
! 621: cur->o_weight = things[TYP_POTION].mi_wght;
! 622: if (cursechance < p_magic[cur->o_which].mi_curse)
! 623: cur->o_flags |= ISCURSED;
! 624: else if (blesschance < p_magic[cur->o_which].mi_bless)
! 625: cur->o_flags |= ISBLESSED;
! 626:
! 627: /* If we made a gain ability potion, see what kind it is */
! 628: if (cur->o_which == P_ABIL) cur->o_kind = rnd(NUMABILITIES);
! 629:
! 630: when TYP_SCROLL:
! 631: cur->o_type = SCROLL;
! 632: do {
! 633: cur->o_which = pick_one(s_magic, MAXSCROLLS);
! 634: } while (!allow_curse && s_magic[cur->o_which].mi_curse == 100);
! 635: cur->o_weight = things[TYP_SCROLL].mi_wght;
! 636: if (cursechance < s_magic[cur->o_which].mi_curse)
! 637: cur->o_flags |= ISCURSED;
! 638: else if (blesschance < s_magic[cur->o_which].mi_bless)
! 639: cur->o_flags |= ISBLESSED;
! 640: when TYP_FOOD:
! 641: no_food = 0;
! 642: cur->o_type = FOOD;
! 643: cur->o_weight = things[TYP_FOOD].mi_wght;
! 644: cur->o_count += extras();
! 645: foods_this_level += cur->o_count;
! 646: cur->o_which = pick_one(foods, MAXFOODS);
! 647: when TYP_WEAPON:
! 648: cur->o_type = WEAPON;
! 649: cur->o_which = rnd(MAXWEAPONS);
! 650: init_weapon(cur, cur->o_which);
! 651: if (cursechance < 20)
! 652: {
! 653:
! 654: cur->o_flags |= ISCURSED;
! 655: cur->o_hplus -= rnd(2) + 1;
! 656: cur->o_dplus -= rnd(2) + 1;
! 657: }
! 658: else if (blesschance < 50) {
! 659:
! 660: cur->o_hplus += rnd(5) + 1;
! 661: cur->o_dplus += rnd(5) + 1;
! 662: }
! 663: when TYP_ARMOR:
! 664: cur->o_type = ARMOR;
! 665: for (j = 0; j < MAXARMORS; j++)
! 666: if (blesschance < armors[j].a_prob)
! 667: break;
! 668: if (j == MAXARMORS)
! 669: {
! 670: debug("Picked a bad armor %d", blesschance);
! 671: j = 0;
! 672: }
! 673: cur->o_which = j;
! 674: cur->o_ac = armors[j].a_class;
! 675: cur->o_weight = armors[j].a_wght;
! 676: if (cursechance < 20)
! 677: {
! 678: cur->o_flags |= ISCURSED;
! 679: cur->o_ac += rnd(3)+1;
! 680: }
! 681: else if (blesschance < 35)
! 682: cur->o_ac -= rnd(3)+1;
! 683: when TYP_RING:
! 684: cur->o_type = RING;
! 685: do {
! 686: cur->o_which = pick_one(r_magic, MAXRINGS);
! 687: } while (!allow_curse && r_magic[cur->o_which].mi_curse == 100);
! 688: cur->o_weight = things[TYP_RING].mi_wght;
! 689: if (cursechance < r_magic[cur->o_which].mi_curse)
! 690: cur->o_flags |= ISCURSED;
! 691: else if (blesschance < r_magic[cur->o_which].mi_bless)
! 692: cur->o_flags |= ISBLESSED;
! 693: switch (cur->o_which)
! 694: {
! 695: case R_ADDSTR:
! 696: case R_ADDWISDOM:
! 697: case R_ADDINTEL:
! 698: case R_PROTECT:
! 699: case R_ADDHIT:
! 700: case R_ADDDAM:
! 701: cur->o_ac = rnd(2) + 1; /* From 1 to 3 */
! 702: if (cur->o_flags & ISCURSED)
! 703: cur->o_ac = -cur->o_ac;
! 704: if (cur->o_flags & ISBLESSED) cur->o_ac++;
! 705: when R_DIGEST:
! 706: if (cur->o_flags & ISCURSED) cur->o_ac = -1;
! 707: else if (cur->o_flags & ISBLESSED) cur->o_ac = 2;
! 708: else cur->o_ac = 1;
! 709: }
! 710: when TYP_STICK:
! 711: cur->o_type = STICK;
! 712: do {
! 713: cur->o_which = pick_one(ws_magic, MAXSTICKS);
! 714: } while (!allow_curse && ws_magic[cur->o_which].mi_curse == 100);
! 715: fix_stick(cur);
! 716: if (cursechance < ws_magic[cur->o_which].mi_curse)
! 717: cur->o_flags |= ISCURSED;
! 718: else if (blesschance < ws_magic[cur->o_which].mi_bless)
! 719: cur->o_flags |= ISBLESSED;
! 720: when TYP_MM:
! 721: cur->o_type = MM;
! 722: do {
! 723: cur->o_which = pick_one(m_magic, MAXMM);
! 724: } while (!allow_curse && m_magic[cur->o_which].mi_curse == 100);
! 725: cur->o_weight = things[TYP_MM].mi_wght;
! 726: if (cursechance < m_magic[cur->o_which].mi_curse)
! 727: cur->o_flags |= ISCURSED;
! 728: else if (blesschance < m_magic[cur->o_which].mi_bless)
! 729: cur->o_flags |= ISBLESSED;
! 730: switch (cur->o_which) {
! 731: case MM_JUG:
! 732: switch(rnd(11)) {
! 733: case 0: cur->o_ac = P_PHASE;
! 734: when 1: cur->o_ac = P_CLEAR;
! 735: when 2: cur->o_ac = P_SEEINVIS;
! 736: when 3: cur->o_ac = P_HEALING;
! 737: when 4: cur->o_ac = P_MFIND;
! 738: when 5: cur->o_ac = P_TFIND;
! 739: when 6: cur->o_ac = P_HASTE;
! 740: when 7: cur->o_ac = P_RESTORE;
! 741: when 8: cur->o_ac = P_FLY;
! 742: when 9: cur->o_ac = P_SKILL;
! 743: when 10:cur->o_ac = P_FFIND;
! 744: }
! 745: when MM_OPEN:
! 746: cur->o_ac = (4 + rnd(5)) * 5;
! 747: when MM_HUNGER:
! 748: case MM_DRUMS:
! 749: case MM_DISAPPEAR:
! 750: case MM_CHOKE:
! 751: case MM_KEOGHTOM:
! 752: cur->o_ac = 3 + (rnd(3)+1) * 3;
! 753: when MM_BRACERS:
! 754: if (cur->o_flags & ISCURSED)
! 755: cur->o_ac = -(rnd(3)+1);
! 756: else
! 757: cur->o_ac = rnd(8)+1;
! 758: when MM_PROTECT:
! 759: if (cur->o_flags & ISCURSED)
! 760: cur->o_ac = -(rnd(3)+1);
! 761: else
! 762: cur->o_ac = rnd(5)+1;
! 763: when MM_DISP:
! 764: cur->o_ac = 2;
! 765: when MM_SKILLS: /* set it to a character class */
! 766: cur->o_ac = rnd(NUM_CHARTYPES-1);
! 767: otherwise:
! 768: cur->o_ac = 0;
! 769: }
! 770: otherwise:
! 771: debug("Picked a bad kind of object");
! 772: wait_for(' ');
! 773: }
! 774: return item;
! 775: }
! 776:
! 777: /*
! 778: * provide a new item tailored to specification
! 779: */
! 780: struct linked_list *
! 781: spec_item(int type, int which, int hit, int damage)
! 782: {
! 783: register struct linked_list *item;
! 784: register struct object *obj;
! 785:
! 786: item = new_item(sizeof *obj);
! 787: obj = OBJPTR(item);
! 788: obj->o_count = 1;
! 789: obj->o_group = 0;
! 790: obj->contents = NULL;
! 791: obj->o_type = type;
! 792: obj->o_which = which;
! 793: strncpy(obj->o_damage, "0d0", sizeof(obj->o_damage));
! 794: strncpy(obj->o_hurldmg, "0d0", sizeof(obj->o_hurldmg));
! 795: obj->o_hplus = 0;
! 796: obj->o_dplus = 0;
! 797: obj->o_flags = 0;
! 798: obj->o_mark[0] = '\0';
! 799: obj->o_text = NULL;
! 800: obj->o_launch = 0;
! 801: obj->o_weight = 0;
! 802:
! 803: /* Handle special characteristics */
! 804: switch (type) {
! 805: case WEAPON:
! 806: init_weapon(obj, which);
! 807: obj->o_hplus = hit;
! 808: obj->o_dplus = damage;
! 809: obj->o_ac = 10;
! 810:
! 811: if (hit > 0 || damage > 0) obj->o_flags |= ISBLESSED;
! 812: else if (hit < 0 || damage < 0) obj->o_flags |= ISCURSED;
! 813:
! 814: when ARMOR:
! 815: obj->o_ac = armors[which].a_class - hit;
! 816: if (hit > 0) obj->o_flags |= ISBLESSED;
! 817: else if (hit < 0) obj->o_flags |= ISCURSED;
! 818:
! 819: when RING:
! 820: obj->o_ac = hit;
! 821: switch (obj->o_which) {
! 822: case R_ADDSTR:
! 823: case R_ADDWISDOM:
! 824: case R_ADDINTEL:
! 825: case R_PROTECT:
! 826: case R_ADDHIT:
! 827: case R_ADDDAM:
! 828: case R_DIGEST:
! 829: if (hit > 1) obj->o_flags |= ISBLESSED;
! 830: else if (hit < 0) obj->o_flags |= ISCURSED;
! 831: }
! 832:
! 833: when STICK:
! 834: fix_stick(obj);
! 835: obj->o_charges = hit;
! 836:
! 837: when GOLD:
! 838: obj->o_type = GOLD;
! 839: obj->o_count = GOLDCALC;
! 840: obj->o_ac = 11;
! 841:
! 842: when MM:
! 843: obj->o_type = MM;
! 844: obj->o_ac = hit;
! 845:
! 846: when RELIC:
! 847: /* Handle weight here since these are all created uniquely */
! 848: obj->o_weight = things[TYP_RELIC].mi_wght;
! 849: if (obj->o_which == EMORI_CLOAK)
! 850: obj->o_charges = 1;
! 851:
! 852: }
! 853: return(item);
! 854: }
! 855:
! 856: /*
! 857: * pick an item out of a list of nitems possible magic items
! 858: */
! 859: int
! 860: pick_one(struct magic_item *magic, int nitems)
! 861: {
! 862: register struct magic_item *end;
! 863: register int i;
! 864: register struct magic_item *start;
! 865:
! 866: start = magic;
! 867: for (end = &magic[nitems], i = rnd(1000); magic < end; magic++)
! 868: if (i < magic->mi_prob)
! 869: break;
! 870: if (magic == end)
! 871: {
! 872: if (wizard)
! 873: {
! 874: msg("bad pick_one: %d from %d items", i, nitems);
! 875: for (magic = start; magic < end; magic++)
! 876: msg("%s: %d%%", magic->mi_name, magic->mi_prob);
! 877: }
! 878: magic = start;
! 879: }
! 880: return (int) (magic - start);
! 881: }
! 882:
! 883:
! 884: /* blesscurse returns whether, according to the flag, the object is
! 885: * blessed, cursed, or neither
! 886: */
! 887:
! 888: char *
! 889: blesscurse(int flags)
! 890: {
! 891: if (flags & ISKNOW) {
! 892: if (flags & ISCURSED) return("cursed ");
! 893: if (flags & ISBLESSED) return("blessed ");
! 894: return("normal ");
! 895: }
! 896: return("");
! 897: }
! 898:
! 899: /*
! 900: * p_kind returns the type of potion for some types of identified potions;
! 901: * otherwise, it returns the color.
! 902: * We assume that obj points to a potion
! 903: */
! 904:
! 905: char *
! 906: p_kind(struct object *obj)
! 907: {
! 908: if (obj->o_which == P_ABIL) return(abilities[obj->o_kind]);
! 909: else return(p_colors[obj->o_which]);
! 910: }
! 911:
! 912: /*
! 913: * extras:
! 914: * Return the number of extra items to be created
! 915: */
! 916: int
! 917: extras(void)
! 918: {
! 919: reg int i;
! 920:
! 921: i = rnd(100);
! 922: if (i < 4) /* 4% for 2 more */
! 923: return (2);
! 924: else if (i < 11) /* 7% for 1 more */
! 925: return (1);
! 926: else /* otherwise no more */
! 927: return (0);
! 928: }
CVSweb