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