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