comparison arogue7/things.c @ 125:adfa37e67084

Import Advanced Rogue 7.7 from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Fri, 08 May 2015 15:24:40 -0400
parents
children b786053d2f37
comparison
equal deleted inserted replaced
124:d10fc4a065ac 125:adfa37e67084
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 "rogue.h"
24
25 /*
26 * print out the number of charges on a stick
27 */
28 char *
29 charge_str(obj)
30 register struct object *obj;
31 {
32 static char buf[20];
33
34 if (!(obj->o_flags & ISKNOW))
35 buf[0] = '\0';
36 else if (terse)
37 sprintf(buf, " [%d]", obj->o_charges);
38 else
39 sprintf(buf, " [%d charges]", obj->o_charges);
40 return buf;
41 }
42 /*
43 * inv_name:
44 * return the name of something as it would appear in an
45 * inventory.
46 */
47 char *
48 inv_name(obj, drop)
49 register struct object *obj;
50 bool drop;
51 {
52 register char *pb;
53
54 pb = prbuf;
55 pb[0] = '\0';
56 switch(obj->o_type) {
57 case SCROLL:
58 if (obj->o_count == 1)
59 sprintf(pb, "A %sscroll ", blesscurse(obj->o_flags));
60 else
61 sprintf(pb, "%d %sscrolls ",
62 obj->o_count, blesscurse(obj->o_flags));
63 pb = &pb[strlen(pb)];
64 if (s_know[obj->o_which] || (obj->o_flags & ISPOST))
65 sprintf(pb, "of %s", s_magic[obj->o_which].mi_name);
66 else if (s_guess[obj->o_which])
67 sprintf(pb, "named %s", s_guess[obj->o_which]);
68 else
69 sprintf(pb, "titled '%s'", s_names[obj->o_which]);
70 when POTION:
71 if (obj->o_count == 1)
72 sprintf(pb, "A %spotion ", blesscurse(obj->o_flags));
73 else
74 sprintf(pb, "%d %spotions ",
75 obj->o_count, blesscurse(obj->o_flags));
76 pb = &pb[strlen(pb)];
77 if (p_know[obj->o_which])
78 sprintf(pb, "of %s (%s)", p_magic[obj->o_which].mi_name,
79 p_kind(obj));
80 else if (obj->o_flags & ISPOST)
81 sprintf(pb, "of %s", p_magic[obj->o_which].mi_name);
82 else if (p_guess[obj->o_which])
83 sprintf(pb, "named %s (%s)", p_guess[obj->o_which],
84 p_colors[obj->o_which]);
85 else {
86 pb = prbuf;
87 if (obj->o_count == 1)
88 sprintf(pb, "A%s %s potion",
89 vowelstr(p_colors[obj->o_which]),
90 p_colors[obj->o_which]);
91 else
92 sprintf(pb, "%d %s potions",
93 obj->o_count, p_colors[obj->o_which]);
94 }
95 when FOOD:
96 if (obj->o_count == 1)
97 sprintf(pb, "A%s %s", vowelstr(foods[obj->o_which].mi_name),
98 foods[obj->o_which].mi_name);
99 else
100 sprintf(pb, "%d %ss", obj->o_count,foods[obj->o_which].mi_name);
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 if (obj->o_flags & ISPOISON)
117 strcat(pb, " {Poisoned}");
118 when ARMOR:
119 if (obj->o_flags & ISKNOW) {
120 strcat(pb, num(armors[obj->o_which].a_class - obj->o_ac, 0));
121 strcat(pb, " ");
122 }
123 strcat(pb, armors[obj->o_which].a_name);
124 if (obj == cur_armor)
125 strcat(pb, " (being worn)");
126 when STICK:
127 sprintf(pb, "A %s%s ",
128 blesscurse(obj->o_flags), ws_type[obj->o_which]);
129 pb = &pb[strlen(pb)];
130 if (ws_know[obj->o_which] || obj->o_flags & ISKNOW)
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 (obj->o_flags & ISPOST)
134 sprintf(pb, "of %s", ws_magic[obj->o_which].mi_name);
135 else if (ws_guess[obj->o_which])
136 sprintf(pb, "named %s (%s)", ws_guess[obj->o_which],
137 ws_made[obj->o_which]);
138 else {
139 pb = prbuf;
140 sprintf(pb, "A %s %s", ws_made[obj->o_which],
141 ws_type[obj->o_which]);
142 }
143 if (obj == cur_weapon)
144 strcat(prbuf, " (weapon in hand)");
145 when RING:
146 if (r_know[obj->o_which] || obj->o_flags & ISKNOW)
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 (obj->o_flags & ISPOST)
150 sprintf(pb, "A ring of %s", r_magic[obj->o_which].mi_name);
151 else if (r_guess[obj->o_which])
152 sprintf(pb, "A ring named %s (%s)",
153 r_guess[obj->o_which], r_stones[obj->o_which]);
154 else
155 sprintf(pb, "A%s %s ring", vowelstr(r_stones[obj->o_which]),
156 r_stones[obj->o_which]);
157 if (obj == cur_ring[LEFT_1] || obj == cur_ring[LEFT_2] ||
158 obj == cur_ring[LEFT_3] || obj == cur_ring[LEFT_4])
159 strcat(pb, " (on left hand)");
160 if (obj == cur_ring[RIGHT_1] || obj == cur_ring[RIGHT_2] ||
161 obj == cur_ring[RIGHT_3] || obj == cur_ring[RIGHT_4])
162 strcat(pb, " (on right hand)");
163 when RELIC:
164 if (obj->o_flags & ISKNOW)
165 switch(obj->o_which) {
166 case QUILL_NAGROM:
167 sprintf(pb, "%s%s", rel_magic[obj->o_which].mi_name,
168 charge_str(obj));
169 otherwise:
170 strcpy(pb, rel_magic[obj->o_which].mi_name);
171 }
172 else switch(obj->o_which) {
173 case MUSTY_DAGGER:
174 strcpy(pb, "Two very fine daggers marked MDDE");
175 when EMORI_CLOAK:
176 strcpy(pb, "A silk cloak");
177 when HEIL_ANKH:
178 strcpy(pb, "A golden ankh");
179 when MING_STAFF:
180 strcpy(pb, "A finely carved staff");
181 when ORCUS_WAND:
182 strcpy(pb, "A sparkling ivory wand");
183 when ASMO_ROD:
184 strcpy(pb, "A glistening ebony rod");
185 when YENDOR_AMULET:
186 strcpy(pb, "A silver amulet");
187 when STONEBONES_AMULET:
188 strcpy(pb, "A stone amulet");
189 when BRIAN_MANDOLIN:
190 strcpy(pb, "A gleaming mandolin");
191 when HRUGGEK_MSTAR:
192 strcpy(pb, "A huge morning star");
193 when AXE_AKLAD:
194 strcpy(pb, "A jewel encrusted axe");
195 when QUILL_NAGROM:
196 strcpy(pb, "A bright white feather");
197 when GERYON_HORN:
198 strcpy(pb, "A jet black horn");
199 when YEENOGHU_FLAIL:
200 strcpy(pb, "A shimmering flail");
201 when SURTUR_RING:
202 strcpy(pb, "A fiery red ring");
203 otherwise:
204 strcpy(pb, "A magical item");
205 }
206
207 /* Take care of wielding and wearing */
208 switch (obj->o_which) {
209 case EMORI_CLOAK:
210 if (cur_armor == NULL && cur_misc[WEAR_CLOAK] == NULL)
211 strcat(pb, " (being worn)");
212 if (obj->o_charges)
213 strcat(pb, " [charged]");
214 else
215 strcat(pb, " [discharged]");
216 when HEIL_ANKH:
217 if (cur_relic[HEIL_ANKH]) strcat(pb, " (in hand)");
218 when EYE_VECNA:
219 if (cur_relic[EYE_VECNA]) strcat(pb, " (in eye socket)");
220 when STONEBONES_AMULET:
221 if (cur_relic[STONEBONES_AMULET])
222 strcat(pb, " (in chest)");
223 when YENDOR_AMULET:
224 if (cur_relic[YENDOR_AMULET])
225 strcat(pb, " (in chest)");
226 when MUSTY_DAGGER:
227 case HRUGGEK_MSTAR:
228 case AXE_AKLAD:
229 case YEENOGHU_FLAIL:
230 case MING_STAFF:
231 case ASMO_ROD:
232 case ORCUS_WAND:
233 if (cur_weapon == obj) strcat(pb, " (weapon in hand)");
234 when SURTUR_RING:
235 if (cur_relic[SURTUR_RING])
236 strcat(pb, " (in nose)");
237 }
238 when MM:
239 if (m_know[obj->o_which])
240 strcpy(pb, misc_name(obj));
241 else {
242 switch (obj->o_which) {
243 case MM_JUG:
244 case MM_BEAKER:
245 strcpy(pb, "A bottle");
246 when MM_KEOGHTOM:
247 strcpy(pb, "A jar");
248 when MM_JEWEL:
249 strcpy(pb, "An amulet");
250 when MM_BOOK:
251 case MM_SKILLS:
252 strcpy(pb, "A book");
253 when MM_ELF_BOOTS:
254 case MM_DANCE:
255 strcpy(pb, "A pair of boots");
256 when MM_BRACERS:
257 strcpy(pb, "A pair of bracers");
258 when MM_OPEN:
259 case MM_HUNGER:
260 strcpy(pb, "A chime");
261 when MM_DISP:
262 case MM_R_POWERLESS:
263 case MM_PROTECT:
264 strcpy(pb, "A cloak");
265 when MM_DRUMS:
266 strcpy(pb, "A set of drums");
267 when MM_DISAPPEAR:
268 case MM_CHOKE:
269 strcpy(pb, "A pouch of dust");
270 when MM_G_DEXTERITY:
271 case MM_G_OGRE:
272 case MM_FUMBLE:
273 strcpy(pb, "A pair of gauntlets");
274 when MM_ADAPTION:
275 case MM_STRANGLE:
276 strcpy(pb, "A necklace");
277 otherwise:
278 strcpy(pb, "A magical item");
279 }
280 if (m_guess[obj->o_which]) {
281 strcat(pb, " named: ");
282 strcat(pb, m_guess[obj->o_which]);
283 }
284 }
285 if (obj == cur_misc[WEAR_BOOTS] ||
286 obj == cur_misc[WEAR_BRACERS] ||
287 obj == cur_misc[WEAR_CLOAK] ||
288 obj == cur_misc[WEAR_GAUNTLET] ||
289 obj == cur_misc[WEAR_NECKLACE] ||
290 obj == cur_misc[WEAR_JEWEL])
291 strcat(pb, " (being worn)");
292 when GOLD:
293 sprintf(pb, "%d Pieces of Gold", obj->o_count);
294 otherwise:
295 debug("Picked up something funny");
296 sprintf(pb, "Something bizarre %s", unctrl(obj->o_type));
297 }
298
299 /* Is it marked? */
300 if (obj->o_mark[0]) {
301 pb = &pb[strlen(pb)];
302 sprintf(pb, " <%s>", obj->o_mark);
303 }
304
305 if (obj->o_flags & ISPROT)
306 strcat(pb, " [protected]");
307 if (drop && isupper(prbuf[0]))
308 prbuf[0] = tolower(prbuf[0]);
309 else if (!drop && islower(*prbuf))
310 *prbuf = toupper(*prbuf);
311 if (!drop)
312 strcat(pb, ".");
313 /*
314 * Truncate if long. Use cols-4 to offset the "pack letter" of a normal
315 * inventory listing.
316 */
317 prbuf[cols-4] = '\0';
318 return prbuf;
319 }
320
321 /*
322 * weap_name:
323 * Return the name of a weapon.
324 */
325 char *
326 weap_name(obj)
327 register struct object *obj;
328 {
329 switch (obj->o_type) {
330 case WEAPON:
331 return(weaps[obj->o_which].w_name);
332 when MISSILE:
333 return(ws_magic[obj->o_which].mi_name);
334 when RELIC:
335 switch (obj->o_which) {
336 case MUSTY_DAGGER:
337 return("daggers");
338 when YEENOGHU_FLAIL:
339 return("flail");
340 when AXE_AKLAD:
341 return("axe");
342 when HRUGGEK_MSTAR:
343 return("morning star");
344 when MING_STAFF:
345 return("staff");
346 when ORCUS_WAND:
347 return("wand");
348 when ASMO_ROD:
349 return("rod");
350 }
351 }
352 return("weapon");
353 }
354
355 /*
356 * drop:
357 * put something down
358 */
359 drop(item)
360 struct linked_list *item;
361 {
362 register char ch;
363 register struct linked_list *obj, *nobj;
364 register struct object *op;
365
366 if (item == NULL) {
367 /* We charge 2 movement times to drop something */
368 if (player.t_action == C_DROP && player.t_using != NULL) {
369 obj = player.t_using;
370 player.t_using = NULL;
371 player.t_action = A_NIL;
372 }
373
374 /* t_action == C_DROP always when called from command() */
375 else {
376 if ((obj = get_item(pack, "drop", ALL, FALSE, FALSE)) == NULL) {
377 player.t_action = A_NIL;
378 player.t_using = NULL;
379 return(FALSE);
380 }
381 if (player.t_action == C_DROP) {
382 player.t_using = obj;
383 player.t_no_move = 2 * movement(&player);
384 return(FALSE); /* We'll come back after we've waited */
385 }
386 }
387
388 switch(ch = CCHAR(mvwinch(stdscr, hero.y, hero.x))) {
389 case PASSAGE:
390 case SCROLL:
391 case POTION:
392 case WEAPON:
393 case FLOOR:
394 case STICK:
395 case ARMOR:
396 case POOL:
397 case RELIC:
398 case GOLD:
399 case FOOD:
400 case RING:
401 case MM:
402 break;
403 default:
404 msg("Can't leave it here");
405 return(FALSE);
406 }
407 }
408 else {
409 obj = item;
410 }
411 op = OBJPTR(obj);
412 if (!dropcheck(op))
413 return(FALSE);
414
415 /*
416 * If it is a scare monster scroll, curse it
417 */
418 if (op->o_type == SCROLL && op->o_which == S_SCARE) {
419 if (op->o_flags & ISBLESSED)
420 op->o_flags &= ~ISBLESSED;
421 else op->o_flags |= ISCURSED;
422 }
423
424 /*
425 * Take it out of the pack
426 */
427 if (op->o_count >= 2 && op->o_group == 0)
428 {
429 nobj = new_item(sizeof *op);
430 op->o_count--;
431 op = OBJPTR(nobj);
432 *op = *(OBJPTR(obj));
433 op->o_count = 1;
434 obj = nobj;
435 }
436 else {
437 detach(pack, obj);
438 inpack--;
439 }
440 if(ch == POOL) {
441 msg("Your %s sinks out of sight.",inv_name(op,TRUE));
442 o_discard(obj);
443 }
444 else if (levtype == POSTLEV) {
445 op->o_pos = hero; /* same place as hero */
446 fall(obj,FALSE);
447 if (item == NULL) /* if item wasn't sold */
448 msg("Thanks for your donation to the fiend's flea market.");
449 }
450 else {
451 /*
452 * Link it into the level object list
453 */
454 attach(lvl_obj, obj);
455 mvaddch(hero.y, hero.x, op->o_type);
456 op->o_pos = hero;
457 msg("Dropped %s", inv_name(op, TRUE));
458 }
459 updpack(FALSE, &player);
460 return (TRUE);
461 }
462
463 /*
464 * do special checks for dropping or unweilding|unwearing|unringing
465 */
466 dropcheck(op)
467 register struct object *op;
468 {
469 int save_max;
470
471 if (op == NULL)
472 return TRUE;
473 if (levtype == POSTLEV) {
474 if ((op->o_flags & ISCURSED) && (op->o_flags & ISKNOW)) {
475 msg("The trader does not accept your shoddy merchandise");
476 return(FALSE);
477 }
478 }
479
480 /* Player will not drop a relic */
481 if (op->o_type == RELIC) {
482 /*
483 * There is a 1% cumulative chance per relic that trying to get
484 * rid of it will cause the relic to turn on the player.
485 */
486 if (rnd(100) < cur_relic[op->o_which]++) {
487 msg("The artifact turns on you.");
488 msg("It crushes your mind!!! -- More --");
489 pstats.s_hpt = -1;
490 wait_for (' ');
491 death(D_RELIC);
492 }
493 else {
494 if (terse) msg("Can't release it.");
495 else msg("You cannot bring yourself to release it.");
496 return FALSE;
497 }
498 }
499
500 /* If we aren't wearing it, we can drop it */
501 if (!is_current(op)) return TRUE;
502
503 /* At this point, we know we are wearing the item */
504 if (op->o_flags & ISCURSED) {
505 msg("You can't. It appears to be cursed.");
506 return FALSE;
507 }
508 if (op->o_type == RING && cur_misc[WEAR_GAUNTLET] != NULL) {
509 msg ("You have to remove your gauntlets first!");
510 return FALSE;
511 }
512 cur_null(op); /* set current to NULL */
513 if (op->o_type == RING) {
514 switch (op->o_which) {
515 case R_ADDSTR: save_max = max_stats.s_str;
516 chg_str(-op->o_ac);
517 max_stats.s_str = save_max;
518 when R_ADDHIT: pstats.s_dext -= op->o_ac;
519 when R_ADDINTEL: pstats.s_intel -= op->o_ac;
520 when R_ADDWISDOM: pstats.s_wisdom -= op->o_ac;
521 when R_SEEINVIS: if (!ISWEARING(R_SEEINVIS) &&
522 find_slot(unsee) == 0) {
523 turn_off(player, CANSEE);
524 msg("The tingling feeling leaves your eyes");
525 }
526 light(&hero);
527 mvwaddch(cw, hero.y, hero.x, PLAYER);
528 when R_WARMTH: if (!ISWEARING(R_WARMTH) && !find_slot(nocold))
529 turn_off(player, NOCOLD);
530 when R_FIRE: if (!ISWEARING(R_FIRE) &&
531 !cur_relic[SURTUR_RING] &&
532 !find_slot(nofire))
533 turn_off(player, NOFIRE);
534 when R_LIGHT: {
535 if(roomin(&hero) != NULL) {
536 light(&hero);
537 mvwaddch(cw, hero.y, hero.x, PLAYER);
538 }
539 }
540 when R_SEARCH: kill_daemon(ring_search);
541 when R_TELEPORT: kill_daemon(ring_teleport);
542 }
543 }
544 else if (op->o_type == MM) {
545 switch (op->o_which) {
546 case MM_ADAPTION:
547 turn_off(player, NOGAS);
548
549 when MM_STRANGLE:
550 msg("You can breathe again.....whew!");
551 kill_daemon(strangle);
552
553 when MM_DANCE:
554 turn_off(player, ISDANCE);
555 msg ("Your feet take a break.....whew!");
556
557 when MM_FUMBLE:
558 kill_daemon(fumble);
559 }
560 }
561 return TRUE;
562 }
563
564 /*
565 * return a new thing
566 */
567 struct linked_list *
568 new_thing(thing_type, allow_curse)
569 int thing_type;
570 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(type, which, hit, damage)
782 int type, which, hit, damage;
783 {
784 register struct linked_list *item;
785 register struct object *obj;
786
787 item = new_item(sizeof *obj);
788 obj = OBJPTR(item);
789 obj->o_count = 1;
790 obj->o_group = 0;
791 obj->contents = NULL;
792 obj->o_type = type;
793 obj->o_which = which;
794 strncpy(obj->o_damage, "0d0", sizeof(obj->o_damage));
795 strncpy(obj->o_hurldmg, "0d0", sizeof(obj->o_hurldmg));
796 obj->o_hplus = 0;
797 obj->o_dplus = 0;
798 obj->o_flags = 0;
799 obj->o_mark[0] = '\0';
800 obj->o_text = NULL;
801 obj->o_launch = 0;
802 obj->o_weight = 0;
803
804 /* Handle special characteristics */
805 switch (type) {
806 case WEAPON:
807 init_weapon(obj, which);
808 obj->o_hplus = hit;
809 obj->o_dplus = damage;
810 obj->o_ac = 10;
811
812 if (hit > 0 || damage > 0) obj->o_flags |= ISBLESSED;
813 else if (hit < 0 || damage < 0) obj->o_flags |= ISCURSED;
814
815 when ARMOR:
816 obj->o_ac = armors[which].a_class - hit;
817 if (hit > 0) obj->o_flags |= ISBLESSED;
818 else if (hit < 0) obj->o_flags |= ISCURSED;
819
820 when RING:
821 obj->o_ac = hit;
822 switch (obj->o_which) {
823 case R_ADDSTR:
824 case R_ADDWISDOM:
825 case R_ADDINTEL:
826 case R_PROTECT:
827 case R_ADDHIT:
828 case R_ADDDAM:
829 case R_DIGEST:
830 if (hit > 1) obj->o_flags |= ISBLESSED;
831 else if (hit < 0) obj->o_flags |= ISCURSED;
832 }
833
834 when STICK:
835 fix_stick(obj);
836 obj->o_charges = hit;
837
838 when GOLD:
839 obj->o_type = GOLD;
840 obj->o_count = GOLDCALC;
841 obj->o_ac = 11;
842
843 when MM:
844 obj->o_type = MM;
845 obj->o_ac = hit;
846
847 when RELIC:
848 /* Handle weight here since these are all created uniquely */
849 obj->o_weight = things[TYP_RELIC].mi_wght;
850 if (obj->o_which == EMORI_CLOAK)
851 obj->o_charges = 1;
852
853 }
854 return(item);
855 }
856
857 /*
858 * pick an item out of a list of nitems possible magic items
859 */
860 pick_one(magic, nitems)
861 register struct magic_item *magic;
862 int nitems;
863 {
864 register struct magic_item *end;
865 register int i;
866 register struct magic_item *start;
867
868 start = magic;
869 for (end = &magic[nitems], i = rnd(1000); magic < end; magic++)
870 if (i < magic->mi_prob)
871 break;
872 if (magic == end)
873 {
874 if (wizard)
875 {
876 msg("bad pick_one: %d from %d items", i, nitems);
877 for (magic = start; magic < end; magic++)
878 msg("%s: %d%%", magic->mi_name, magic->mi_prob);
879 }
880 magic = start;
881 }
882 return (int) (magic - start);
883 }
884
885
886 /* blesscurse returns whether, according to the flag, the object is
887 * blessed, cursed, or neither
888 */
889
890 char *
891 blesscurse(flags)
892 int flags;
893 {
894 if (flags & ISKNOW) {
895 if (flags & ISCURSED) return("cursed ");
896 if (flags & ISBLESSED) return("blessed ");
897 return("normal ");
898 }
899 return("");
900 }
901
902 /*
903 * p_kind returns the type of potion for some types of identified potions;
904 * otherwise, it returns the color.
905 */
906
907 char *
908 p_kind(obj)
909 struct object *obj; /* We assume that obj points to a potion */
910 {
911 if (obj->o_which == P_ABIL) return(abilities[obj->o_kind]);
912 else return(p_colors[obj->o_which]);
913 }
914
915 /*
916 * extras:
917 * Return the number of extra items to be created
918 */
919 extras()
920 {
921 reg int i;
922
923 i = rnd(100);
924 if (i < 4) /* 4% for 2 more */
925 return (2);
926 else if (i < 11) /* 7% for 1 more */
927 return (1);
928 else /* otherwise no more */
929 return (0);
930 }