Annotation of early-roguelike/urogue/things.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: things.c - functions for dealing with things like potions and scrolls
! 3:
! 4: UltraRogue: The Ultimate Adventure in the Dungeons of Doom
! 5: Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong
! 6: All rights reserved.
! 7:
! 8: Based on "Advanced Rogue"
! 9: Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka
! 10: All rights reserved.
! 11:
! 12: Based on "Rogue: Exploring the Dungeons of Doom"
! 13: Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
! 14: All rights reserved.
! 15:
! 16: See the file LICENSE.TXT for full copyright and licensing information.
! 17: */
! 18:
! 19: #include <string.h>
! 20: #include <ctype.h>
! 21: #include "rogue.h"
! 22:
! 23: /*
! 24: inv_name()
! 25: return the name of something as it would appear in an inventory.
! 26: */
! 27:
! 28: char *
! 29: inv_name(struct object *obj, int lowercase)
! 30: {
! 31: char *pb;
! 32: char buf[1024];
! 33:
! 34: switch(obj->o_type)
! 35: {
! 36: case SCROLL:
! 37: if (obj->o_count == 1)
! 38: sprintf(prbuf, "A %s%sscroll ",
! 39: obj->o_flags & CANRETURN ? "claimed " : "",
! 40: blesscurse(obj->o_flags));
! 41: else
! 42: sprintf(prbuf, "%d %s%sscrolls ",
! 43: obj->o_count,
! 44: obj->o_flags & CANRETURN ? "claimed " : "",
! 45: blesscurse(obj->o_flags));
! 46:
! 47: pb = &prbuf[strlen(prbuf)];
! 48:
! 49: if (know_items[TYP_SCROLL][obj->o_which])
! 50: sprintf(pb, "of %s", s_magic[obj->o_which].mi_name);
! 51: else if (guess_items[TYP_SCROLL][obj->o_which])
! 52: sprintf(pb, "called %s", guess_items[TYP_SCROLL][obj->o_which]);
! 53: else
! 54: sprintf(pb, "titled '%s'", s_names[obj->o_which]);
! 55: break;
! 56:
! 57: case POTION:
! 58: if (obj->o_count == 1)
! 59: sprintf(prbuf, "A %s%spotion ",
! 60: obj->o_flags & CANRETURN ? "claimed " : "",
! 61: blesscurse(obj->o_flags));
! 62: else
! 63: sprintf(prbuf, "%d %s%spotions ",
! 64: obj->o_count,
! 65: obj->o_flags & CANRETURN ? "claimed " : "",
! 66: blesscurse(obj->o_flags));
! 67:
! 68: pb = &prbuf[strlen(prbuf)];
! 69:
! 70: if (know_items[TYP_POTION][obj->o_which])
! 71: sprintf(pb, "of %s(%s)", p_magic[obj->o_which].mi_name,
! 72: p_colors[obj->o_which]);
! 73: else if (guess_items[TYP_POTION][obj->o_which])
! 74: sprintf(pb, "called %s(%s)", guess_items[TYP_POTION][obj->o_which],
! 75: p_colors[obj->o_which]);
! 76: else
! 77: {
! 78: if (obj->o_count == 1)
! 79: sprintf(prbuf, "A%s %s potion",
! 80: obj->o_flags & CANRETURN ? " claimed" :
! 81: (char *) vowelstr(p_colors[obj->o_which]),
! 82: p_colors[obj->o_which]);
! 83: else
! 84: sprintf(prbuf, "%d %s%s potions",
! 85: obj->o_count,
! 86: obj->o_flags & CANRETURN ? "claimed " : "",
! 87: (char *) p_colors[obj->o_which]);
! 88: }
! 89: break;
! 90:
! 91: case FOOD:
! 92: if (obj->o_count == 1)
! 93: sprintf(prbuf, "A%s %s",
! 94: obj->o_flags & CANRETURN ? " claimed" :
! 95: (char *) vowelstr(fd_data[obj->o_which].mi_name),
! 96: fd_data[obj->o_which].mi_name);
! 97: else
! 98: sprintf(prbuf, "%d %s%ss", obj->o_count,
! 99: obj->o_flags & CANRETURN ? "claimed " : "",
! 100: fd_data[obj->o_which].mi_name);
! 101: break;
! 102:
! 103: case WEAPON:
! 104: if (obj->o_count > 1)
! 105: sprintf(prbuf, "%d ", obj->o_count);
! 106: else if ((obj->o_flags & (ISZAPPED | CANRETURN | ISPOISON | ISSILVER | ISTWOH)) ||
! 107: ((obj->o_flags & (ISKNOW | ISZAPPED)) == (ISKNOW | ISZAPPED)))
! 108: strcpy(prbuf, "A ");
! 109: else
! 110: sprintf(prbuf, "A%s ", vowelstr(weaps[obj->o_which].w_name));
! 111:
! 112: pb = &prbuf[strlen(prbuf)];
! 113:
! 114: if ((obj->o_flags & ISKNOW) && (obj->o_flags & ISZAPPED))
! 115: sprintf(pb, "charged%s ", charge_str(obj,buf));
! 116:
! 117: pb = &prbuf[strlen(prbuf)];
! 118:
! 119: if (obj->o_flags & CANRETURN)
! 120: sprintf(pb, "claimed ");
! 121:
! 122: pb = &prbuf[strlen(prbuf)];
! 123:
! 124: if (obj->o_flags & ISPOISON)
! 125: sprintf(pb, "poisoned ");
! 126:
! 127: pb = &prbuf[strlen(prbuf)];
! 128:
! 129: if (obj->o_flags & ISSILVER)
! 130: sprintf(pb, "silver ");
! 131:
! 132: if (obj->o_flags & ISTWOH)
! 133: sprintf(pb, "two-handed ");
! 134:
! 135: pb = &prbuf[strlen(prbuf)];
! 136:
! 137: if (obj->o_flags & ISKNOW)
! 138: sprintf(pb, "%s %s", num(obj->o_hplus, obj->o_dplus, buf),
! 139: weaps[obj->o_which].w_name);
! 140: else
! 141: sprintf(pb, "%s", weaps[obj->o_which].w_name);
! 142:
! 143: if (obj->o_count > 1)
! 144: strcat(prbuf, "s");
! 145:
! 146: break;
! 147:
! 148: case ARMOR:
! 149: if (obj->o_flags & ISKNOW)
! 150: sprintf(prbuf, "%s%s %s",
! 151: obj->o_flags & CANRETURN ? "claimed " : "",
! 152: num(armors[obj->o_which].a_class - obj->o_ac, 0, buf),
! 153: armors[obj->o_which].a_name);
! 154: else
! 155: sprintf(prbuf, "%s%s",
! 156: obj->o_flags & CANRETURN ? "claimed " : "",
! 157: armors[obj->o_which].a_name);
! 158:
! 159: break;
! 160:
! 161: case ARTIFACT:
! 162: sprintf(prbuf, "the %s", arts[obj->o_which].ar_name);
! 163:
! 164: if (obj->o_flags & CANRETURN)
! 165: strcat(prbuf, " (claimed)");
! 166:
! 167: break;
! 168:
! 169: case STICK:
! 170: sprintf(prbuf, "A %s%s%s ",
! 171: obj->o_flags & CANRETURN ? "claimed " : "",
! 172: blesscurse(obj->o_flags), ws_type[obj->o_which]);
! 173:
! 174: pb = &prbuf[strlen(prbuf)];
! 175:
! 176: if (know_items[TYP_STICK][obj->o_which])
! 177: sprintf(pb, "of %s%s(%s)", ws_magic[obj->o_which].mi_name,
! 178: charge_str(obj,buf), ws_made[obj->o_which]);
! 179: else if (guess_items[TYP_STICK][obj->o_which])
! 180: sprintf(pb, "called %s(%s)", guess_items[TYP_STICK][obj->o_which],
! 181: ws_made[obj->o_which]);
! 182: else
! 183: sprintf(&prbuf[2], "%s%s %s",
! 184: obj->o_flags & CANRETURN ? "claimed " : "",
! 185: ws_made[obj->o_which],
! 186: ws_type[obj->o_which]);
! 187:
! 188: break;
! 189:
! 190: case RING:
! 191: if (know_items[TYP_RING][obj->o_which])
! 192: sprintf(prbuf, "A%s%s ring of %s(%s)",
! 193: obj->o_flags & CANRETURN ? " claimed" : "", ring_num(obj,buf),
! 194: r_magic[obj->o_which].mi_name, r_stones[obj->o_which]);
! 195: else if (guess_items[TYP_RING][obj->o_which])
! 196: sprintf(prbuf, "A %sring called %s(%s)",
! 197: obj->o_flags & CANRETURN ? "claimed " : "",
! 198: guess_items[TYP_RING][obj->o_which], r_stones[obj->o_which]);
! 199: else
! 200: sprintf(prbuf, "A%s %s ring",
! 201: obj->o_flags & CANRETURN ? "claimed " :
! 202: (char *)vowelstr(r_stones[obj->o_which]),
! 203: r_stones[obj->o_which]);
! 204: break;
! 205:
! 206: case GOLD:
! 207: sprintf(prbuf, "%d gold pieces", obj->o_count);
! 208: break;
! 209:
! 210: default:
! 211: debug("Picked up something funny.");
! 212: sprintf(prbuf, "Something bizarre %s", unctrl(obj->o_type));
! 213: break;
! 214: }
! 215:
! 216: /* Is it marked? */
! 217:
! 218: if (obj->o_mark[0])
! 219: {
! 220: pb = &prbuf[strlen(prbuf)];
! 221: sprintf(pb, " <%s>", obj->o_mark);
! 222: }
! 223:
! 224: if (obj == cur_armor)
! 225: strcat(prbuf, " (being worn)");
! 226:
! 227: if (obj == cur_weapon)
! 228: strcat(prbuf, " (weapon in hand)");
! 229:
! 230: if (obj == cur_ring[LEFT_1])
! 231: strcat(prbuf, " (on left hand)");
! 232: else if (obj == cur_ring[LEFT_2])
! 233: strcat(prbuf, " (on left hand)");
! 234: else if (obj == cur_ring[LEFT_3])
! 235: strcat(prbuf, " (on left hand)");
! 236: else if (obj == cur_ring[LEFT_4])
! 237: strcat(prbuf, " (on left hand)");
! 238: else if (obj == cur_ring[LEFT_5])
! 239: strcat(prbuf, " (on left hand)");
! 240: else if (obj == cur_ring[RIGHT_1])
! 241: strcat(prbuf, " (on right hand)");
! 242: else if (obj == cur_ring[RIGHT_2])
! 243: strcat(prbuf, " (on right hand)");
! 244: else if (obj == cur_ring[RIGHT_3])
! 245: strcat(prbuf, " (on right hand)");
! 246: else if (obj == cur_ring[RIGHT_4])
! 247: strcat(prbuf, " (on right hand)");
! 248: else if (obj == cur_ring[RIGHT_5])
! 249: strcat(prbuf, " (on right hand)");
! 250:
! 251: if (obj->o_flags & ISPROT)
! 252: strcat(prbuf, " [protected]");
! 253:
! 254: if (lowercase && isupper(prbuf[0]))
! 255: prbuf[0] = (char) tolower(prbuf[0]);
! 256: else if (!lowercase && islower(*prbuf))
! 257: *prbuf = (char) toupper(*prbuf);
! 258:
! 259: if (!lowercase)
! 260: strcat(prbuf, ".");
! 261:
! 262: return(prbuf);
! 263: }
! 264:
! 265: /*
! 266: rem_obj()
! 267: Remove an object from the level.
! 268: */
! 269:
! 270: void
! 271: rem_obj(struct linked_list *item, int dis)
! 272: {
! 273: struct linked_list *llptr;
! 274: struct object *objptr, *op;
! 275: int x, y;
! 276:
! 277: if (item == NULL)
! 278: return;
! 279:
! 280: detach(lvl_obj, item);
! 281: objptr = OBJPTR(item);
! 282:
! 283: if ( (llptr = objptr->next_obj) != NULL )
! 284: {
! 285: detach((objptr->next_obj), llptr);
! 286: attach(lvl_obj, llptr);
! 287:
! 288: op = OBJPTR(llptr);
! 289:
! 290: op->next_obj = objptr->next_obj;
! 291:
! 292: if (op->next_obj)
! 293: objptr->next_obj->l_prev = NULL;
! 294:
! 295: objptr->next_obj = NULL;
! 296:
! 297: y = op->o_pos.y;
! 298: x = op->o_pos.x;
! 299:
! 300: if (cansee(y, x))
! 301: mvwaddch(cw, y, x, op->o_type);
! 302:
! 303: mvaddch(y, x, op->o_type);
! 304: }
! 305: else
! 306: {
! 307: y = objptr->o_pos.y;
! 308: x = objptr->o_pos.x;
! 309:
! 310: /* problems if dropped in rock */
! 311:
! 312: mvaddch(y,x,(roomin((objptr->o_pos)) == NULL ? PASSAGE : FLOOR));
! 313: }
! 314:
! 315: if (dis)
! 316: discard(item);
! 317: }
! 318:
! 319: /*
! 320: add_obj()
! 321: adds an object to the level
! 322: */
! 323:
! 324: void
! 325: add_obj(struct linked_list *item, int y, int x)
! 326: {
! 327: struct linked_list *llptr;
! 328: struct object*objptr;
! 329:
! 330: llptr = find_obj(y, x);
! 331:
! 332: if (llptr)
! 333: {
! 334: objptr = OBJPTR(llptr);
! 335: attach((objptr->next_obj), item);
! 336: }
! 337: else
! 338: {
! 339: attach(lvl_obj, item);
! 340: objptr = OBJPTR(item);
! 341: objptr->next_obj = NULL;
! 342: objptr->o_pos.y = y;
! 343: objptr->o_pos.x = x;
! 344: mvaddch(y, x, objptr->o_type);
! 345: }
! 346: }
! 347:
! 348: /*
! 349: drop()
! 350: put something down
! 351: */
! 352:
! 353: int
! 354: drop(struct linked_list *item)
! 355: {
! 356: char ch = CCHAR( mvwinch(stdscr, hero.y, hero.x) );
! 357: struct object *obj;
! 358:
! 359: switch (ch)
! 360: {
! 361: case GOLD:
! 362: case POTION:
! 363: case SCROLL:
! 364: case FOOD:
! 365: case WEAPON:
! 366: case ARMOR:
! 367: case RING:
! 368: case STICK:
! 369: case FLOOR:
! 370: case PASSAGE:
! 371: case POOL:
! 372: case ARTIFACT:
! 373: if (item == NULL && (item = get_item("drop", 0)) == NULL)
! 374: return(FALSE);
! 375: break;
! 376:
! 377: default:
! 378: msg("You can't drop something here.");
! 379: return(FALSE);
! 380: }
! 381:
! 382: obj = OBJPTR(item);
! 383:
! 384: if (!dropcheck(obj))
! 385: return(FALSE);
! 386:
! 387: /* Curse a dropped scare monster scroll */
! 388:
! 389: if (obj->o_type == SCROLL && obj->o_which == S_SCARE)
! 390: {
! 391: if (obj->o_flags & ISBLESSED)
! 392: obj->o_flags &= ~ISBLESSED;
! 393: else
! 394: obj->o_flags |= ISCURSED;
! 395: }
! 396:
! 397: /* Take it out of the pack */
! 398:
! 399: if (obj->o_count >= 2 && obj->o_group == 0)
! 400: {
! 401: struct linked_list *nitem = new_item(sizeof *obj);
! 402:
! 403: obj->o_count--;
! 404: obj = OBJPTR(nitem);
! 405: *obj = *(OBJPTR(item));
! 406: obj->o_count = 1;
! 407: item = nitem;
! 408: }
! 409: else
! 410: rem_pack(obj);
! 411:
! 412: if (ch == POOL)
! 413: {
! 414: msg("The pool bubbles briefly as your %s sinks out of sight.",
! 415: inv_name(obj, TRUE));
! 416: discard(item);
! 417: item = NULL;
! 418: }
! 419: else /* Link it into the level object list */
! 420: {
! 421: add_obj(item, hero.y, hero.x);
! 422: mvaddch(hero.y, hero.x, obj->o_type);
! 423: }
! 424:
! 425: if (obj->o_type == ARTIFACT)
! 426: has_artifact &= ~(1 << obj->o_which);
! 427:
! 428: updpack();
! 429: return(TRUE);
! 430: }
! 431:
! 432: /*
! 433: dropcheck()
! 434: do special checks for dropping or unweilding|unwearing|unringing
! 435: */
! 436:
! 437: int
! 438: dropcheck(struct object *op)
! 439: {
! 440: if (op == NULL)
! 441: return(TRUE);
! 442:
! 443: if (op != cur_armor && op != cur_weapon &&
! 444: op != cur_ring[LEFT_1] && op != cur_ring[LEFT_2] &&
! 445: op != cur_ring[LEFT_3] && op != cur_ring[LEFT_4] &&
! 446: op != cur_ring[LEFT_5] &&
! 447: op != cur_ring[RIGHT_1] && op != cur_ring[RIGHT_2] &&
! 448: op != cur_ring[RIGHT_3] && op != cur_ring[RIGHT_4] &&
! 449: op != cur_ring[RIGHT_5])
! 450: return(TRUE);
! 451:
! 452: if (op->o_flags & ISCURSED)
! 453: {
! 454: msg("You can't. It appears to be cursed.");
! 455: return(FALSE);
! 456: }
! 457:
! 458: if (op == cur_weapon)
! 459: cur_weapon = NULL;
! 460: else if (op == cur_armor)
! 461: {
! 462: waste_time();
! 463: cur_armor = NULL;
! 464: }
! 465: else if (op == cur_ring[LEFT_1] || op == cur_ring[LEFT_2] ||
! 466: op == cur_ring[LEFT_3] || op == cur_ring[LEFT_4] ||
! 467: op == cur_ring[LEFT_5] ||
! 468: op == cur_ring[RIGHT_1] || op == cur_ring[RIGHT_2] ||
! 469: op == cur_ring[RIGHT_3] || op == cur_ring[RIGHT_4] ||
! 470: op == cur_ring[RIGHT_5])
! 471: {
! 472: if (op == cur_ring[LEFT_1])
! 473: cur_ring[LEFT_1] = NULL;
! 474: else if (op == cur_ring[LEFT_2])
! 475: cur_ring[LEFT_2] = NULL;
! 476: else if (op == cur_ring[LEFT_3])
! 477: cur_ring[LEFT_3] = NULL;
! 478: else if (op == cur_ring[LEFT_4])
! 479: cur_ring[LEFT_4] = NULL;
! 480: else if (op == cur_ring[LEFT_5])
! 481: cur_ring[LEFT_5] = NULL;
! 482: else if (op == cur_ring[RIGHT_1])
! 483: cur_ring[RIGHT_1] = NULL;
! 484: else if (op == cur_ring[RIGHT_2])
! 485: cur_ring[RIGHT_2] = NULL;
! 486: else if (op == cur_ring[RIGHT_3])
! 487: cur_ring[RIGHT_3] = NULL;
! 488: else if (op == cur_ring[RIGHT_4])
! 489: cur_ring[RIGHT_4] = NULL;
! 490: else if (op == cur_ring[RIGHT_5])
! 491: cur_ring[RIGHT_5] = NULL;
! 492:
! 493: switch (op->o_which)
! 494: {
! 495: case R_ADDSTR:
! 496: chg_str(-op->o_ac, FALSE, FALSE);
! 497: break;
! 498: case R_ADDHIT:
! 499: chg_dext(-op->o_ac, FALSE, FALSE);
! 500: break;
! 501: case R_ADDINTEL:
! 502: pstats.s_intel -= op->o_ac;
! 503: break;
! 504: case R_ADDWISDOM:
! 505: pstats.s_wisdom -= op->o_ac;
! 506: break;
! 507:
! 508: case R_SEEINVIS:
! 509: if (find_slot(FUSE_UNSEE,FUSE) == NULL)
! 510: {
! 511: turn_off(player, CANSEE);
! 512: msg("The tingling feeling leaves your eyes.");
! 513: }
! 514:
! 515: light(&hero);
! 516: mvwaddch(cw, hero.y, hero.x, PLAYER);
! 517: break;
! 518:
! 519: case R_LIGHT:
! 520: if (roomin(hero) != NULL)
! 521: {
! 522: light(&hero);
! 523: mvwaddch(cw, hero.y, hero.x, PLAYER);
! 524: }
! 525: break;
! 526: }
! 527: }
! 528: return(TRUE);
! 529: }
! 530:
! 531: /*
! 532: new_thing()
! 533: return a new thing
! 534: */
! 535:
! 536: struct linked_list *
! 537: new_thing(void)
! 538: {
! 539: int j, k;
! 540: struct linked_list *item;
! 541: struct object *cur;
! 542: short blesschance = srnd(100);
! 543: short cursechance = srnd(100);
! 544:
! 545: item = new_item(sizeof *cur);
! 546: cur = OBJPTR(item);
! 547: cur->o_hplus = cur->o_dplus = 0;
! 548: cur->o_damage = cur->o_hurldmg = "0d0";
! 549: cur->o_ac = 11;
! 550: cur->o_count = 1;
! 551: cur->o_group = 0;
! 552: cur->o_flags = 0;
! 553: cur->o_weight = 0;
! 554: cur->o_mark[0] = '\0';
! 555:
! 556: /*
! 557: * Decide what kind of object it will be If we haven't had food for a
! 558: * while, let it be food.
! 559: */
! 560:
! 561: switch (no_food > 3 ? TYP_FOOD : pick_one(things, numthings))
! 562: {
! 563: case TYP_POTION:
! 564: cur->o_type = POTION;
! 565: cur->o_which = pick_one(p_magic, maxpotions);
! 566: cur->o_weight = things[TYP_POTION].mi_wght;
! 567:
! 568: if (cursechance < p_magic[cur->o_which].mi_curse)
! 569: cur->o_flags |= ISCURSED;
! 570: else if (blesschance < p_magic[cur->o_which].mi_bless)
! 571: cur->o_flags |= ISBLESSED;
! 572: break;
! 573:
! 574: case TYP_SCROLL:
! 575: cur->o_type = SCROLL;
! 576: cur->o_which = pick_one(s_magic, maxscrolls);
! 577: cur->o_weight = things[TYP_SCROLL].mi_wght;
! 578:
! 579: if (cursechance < s_magic[cur->o_which].mi_curse)
! 580: cur->o_flags |= ISCURSED;
! 581: else if (blesschance < s_magic[cur->o_which].mi_bless)
! 582: cur->o_flags |= ISBLESSED;
! 583: break;
! 584:
! 585: case TYP_FOOD:
! 586: no_food = 0;
! 587: cur->o_type = FOOD;
! 588: cur->o_which = pick_one(fd_data, maxfoods);
! 589: cur->o_weight = 2;
! 590: cur->o_count += extras();
! 591: break;
! 592:
! 593: case TYP_WEAPON:
! 594: cur->o_type = WEAPON;
! 595: cur->o_which = rnd(maxweapons);
! 596: init_weapon(cur, cur->o_which);
! 597:
! 598: if (cursechance < 10)
! 599: {
! 600: short bad = (rnd(10) < 1) ? 2 : 1;
! 601:
! 602: cur->o_flags |= ISCURSED;
! 603: cur->o_hplus -= bad;
! 604: cur->o_dplus -= bad;
! 605: }
! 606: else if (blesschance < 15)
! 607: {
! 608: short good = (rnd(10) < 1) ? 2 : 1;
! 609:
! 610: cur->o_hplus += good;
! 611: cur->o_dplus += good;
! 612: }
! 613: break;
! 614:
! 615: case TYP_ARMOR:
! 616: cur->o_type = ARMOR;
! 617:
! 618: for (j = 0; j < maxarmors; j++)
! 619: if (blesschance < armors[j].a_prob)
! 620: break;
! 621:
! 622: if (j == maxarmors)
! 623: {
! 624: debug("Picked a bad armor %d", blesschance);
! 625: j = 0;
! 626: }
! 627:
! 628: cur->o_which = j;
! 629: cur->o_ac = armors[j].a_class;
! 630:
! 631: if (((k = rnd(100)) < 20) && j != MITHRIL)
! 632: {
! 633: cur->o_flags |= ISCURSED;
! 634: cur->o_ac += rnd(3) + 1;
! 635: }
! 636: else if (k < 28 || j == MITHRIL)
! 637: cur->o_ac -= rnd(3) + 1;
! 638:
! 639: if (j == MITHRIL)
! 640: cur->o_flags |= ISPROT;
! 641:
! 642: cur->o_weight = armors[j].a_wght;
! 643:
! 644: break;
! 645:
! 646: case TYP_RING:
! 647: cur->o_type = RING;
! 648: cur->o_which = pick_one(r_magic, maxrings);
! 649: cur->o_weight = things[TYP_RING].mi_wght;
! 650:
! 651: if (cursechance < r_magic[cur->o_which].mi_curse)
! 652: cur->o_flags |= ISCURSED;
! 653: else if (blesschance < r_magic[cur->o_which].mi_bless)
! 654: cur->o_flags |= ISBLESSED;
! 655:
! 656: switch (cur->o_which)
! 657: {
! 658: case R_ADDSTR:
! 659: case R_ADDWISDOM:
! 660: case R_ADDINTEL:
! 661: case R_PROTECT:
! 662: case R_ADDHIT:
! 663: case R_ADDDAM:
! 664: case R_CARRYING:
! 665: cur->o_ac = rnd(2) + 1; /* From 1 to 3 */
! 666:
! 667: if (cur->o_flags & ISCURSED)
! 668: cur->o_ac = -cur->o_ac;
! 669:
! 670: if (cur->o_flags & ISBLESSED)
! 671: cur->o_ac++;
! 672:
! 673: break;
! 674:
! 675: case R_RESURRECT:
! 676: case R_TELCONTROL:
! 677: case R_VREGEN:
! 678: case R_REGEN:
! 679: case R_PIETY:
! 680: case R_WIZARD:
! 681: cur->o_ac = 0;
! 682:
! 683: if (cur->o_flags & ISCURSED)
! 684: cur->o_ac = -1;
! 685:
! 686: if (cur->o_flags & ISBLESSED)
! 687: cur->o_ac = 1;
! 688:
! 689: break;
! 690:
! 691: case R_DIGEST:
! 692:
! 693: if (cur->o_flags & ISCURSED)
! 694: cur->o_ac = -1;
! 695: else if (cur->o_flags & ISBLESSED)
! 696: cur->o_ac = 2;
! 697: else
! 698: cur->o_ac = 1;
! 699: break;
! 700:
! 701: default:
! 702: cur->o_ac = 0;
! 703: break;
! 704: }
! 705: break;
! 706:
! 707: case TYP_STICK:
! 708: cur->o_type = STICK;
! 709: cur->o_which = pick_one(ws_magic, maxsticks);
! 710: fix_stick(cur);
! 711:
! 712: if (cursechance < ws_magic[cur->o_which].mi_curse)
! 713: cur->o_flags |= ISCURSED;
! 714: else if (blesschance < ws_magic[cur->o_which].mi_bless)
! 715: cur->o_flags |= ISBLESSED;
! 716:
! 717: break;
! 718:
! 719: default:
! 720: debug("Picked a bad kind of object");
! 721: wait_for(' ');
! 722: }
! 723:
! 724: return(item);
! 725: }
! 726:
! 727: /*
! 728: spec_item()
! 729: provide a new item tailored to specification
! 730: */
! 731:
! 732: struct linked_list *
! 733: spec_item(char type, int which, int hitp, int damage)
! 734: {
! 735: struct linked_list *item;
! 736: struct object *obj;
! 737:
! 738: item = new_item(sizeof *obj);
! 739: obj = OBJPTR(item);
! 740:
! 741: obj->o_count = 1;
! 742: obj->o_group = 0;
! 743: obj->o_type = type;
! 744: obj->o_which = which;
! 745: obj->o_damage = obj->o_hurldmg = "0d0";
! 746: obj->o_hplus = 0;
! 747: obj->o_dplus = 0;
! 748: obj->o_flags = 0;
! 749: obj->o_mark[0] = '\0';
! 750: obj->o_text = NULL;
! 751: obj->o_launch = 0;
! 752: obj->o_weight = 0;
! 753:
! 754: switch(type) /* Handle special characteristics */
! 755: {
! 756: case WEAPON:
! 757: init_weapon(obj, which);
! 758: obj->o_hplus = hitp;
! 759: obj->o_dplus = damage;
! 760: obj->o_ac = 10;
! 761: break;
! 762:
! 763: case ARMOR:
! 764: obj->o_ac = armors[which].a_class - hitp;
! 765: break;
! 766:
! 767: case RING:
! 768: obj->o_ac = hitp;
! 769: break;
! 770:
! 771: case STICK:
! 772: fix_stick(obj);
! 773: obj->o_charges = hitp;
! 774: break;
! 775:
! 776: case GOLD:
! 777: obj->o_type = GOLD;
! 778: obj->o_count = GOLDCALC;
! 779: obj->o_ac = 11;
! 780: break;
! 781: }
! 782:
! 783: if (hitp > 0 || damage > 0)
! 784: obj->o_flags |= ISBLESSED;
! 785: else if (hitp < 0 || damage < 0)
! 786: obj->o_flags |= ISCURSED;
! 787:
! 788: return(item);
! 789: }
! 790:
! 791: /*
! 792: pick_one()
! 793: pick an item out of a list of nitems possible magic items
! 794: */
! 795:
! 796: int
! 797: pick_one(struct magic_item *magic, int nitems)
! 798: {
! 799: int i;
! 800: struct magic_item *end;
! 801: struct magic_item *start = magic;
! 802:
! 803: for (end = &magic[nitems], i = rnd(1000); magic < end; magic++)
! 804: if (i <= magic->mi_prob)
! 805: break;
! 806:
! 807: if (magic == end)
! 808: {
! 809: if (wizard)
! 810: {
! 811: add_line("Bad pick_one: %d from %d items", i, nitems);
! 812:
! 813: for (magic = start; magic < end; magic++)
! 814: add_line("%s: %d%%", magic->mi_name, magic->mi_prob);
! 815:
! 816: end_line();
! 817: }
! 818: magic = start;
! 819: }
! 820:
! 821: return((int)(magic - start));
! 822: }
! 823:
! 824:
! 825: /*
! 826: blesscurse()
! 827: returns whether the object is blessed or cursed
! 828: */
! 829:
! 830: char *
! 831: blesscurse(long flags)
! 832: {
! 833: if (flags & ISKNOW)
! 834: {
! 835: if (flags & ISCURSED)
! 836: return("cursed ");
! 837:
! 838: if (flags & ISBLESSED)
! 839: return("blessed ");
! 840:
! 841: return("normal ");
! 842: }
! 843:
! 844: return("");
! 845: }
! 846:
! 847: /*
! 848: extras()
! 849: Return the number of extra food items to be created
! 850: */
! 851:
! 852: int
! 853: extras(void)
! 854: {
! 855: int i = rnd(100);
! 856:
! 857: if (i < 10)
! 858: return(2);
! 859: else if (i < 20)
! 860: return(1);
! 861: else
! 862: return(0);
! 863: }
! 864:
! 865: /*
! 866: name_type()
! 867: Returns a string identifying a pack item's type
! 868: */
! 869:
! 870: char *
! 871: name_type(int type)
! 872: {
! 873: switch(type)
! 874: {
! 875: case ARMOR:
! 876: return ("armor");
! 877:
! 878: case WEAPON:
! 879: return ("weapons");
! 880:
! 881: case SCROLL:
! 882: return ("scrolls");
! 883:
! 884: case RING:
! 885: return ("rings");
! 886:
! 887: case STICK:
! 888: return ("staffs");
! 889:
! 890: case POTION:
! 891: return ("potions");
! 892:
! 893: case FOOD:
! 894: return ("food");
! 895:
! 896: case GOLD:
! 897: return ("gold");
! 898:
! 899: default:
! 900: return ("items");
! 901: }
! 902: }
! 903:
! 904: /*
! 905: make_item()
! 906: adds a linked_list structure to the top of an object for interfacing
! 907: with other routines
! 908: */
! 909:
! 910: linked_list *
! 911: make_item(object *obj_p)
! 912: {
! 913: linked_list *item_p = new_list();
! 914:
! 915: item_p->l_next = item_p->l_prev = NULL;
! 916:
! 917: item_p->data.obj = obj_p;
! 918:
! 919: return(item_p);
! 920: }
! 921:
! 922: /*
! 923: is_member()
! 924: Checks to see if a character is a member of an array
! 925: */
! 926:
! 927: int
! 928: is_member(char *list_p, int member)
! 929: {
! 930: while (*list_p != 0)
! 931: {
! 932: if (*list_p++ == member)
! 933: return(TRUE);
! 934: }
! 935:
! 936: return(FALSE);
! 937: }
CVSweb